Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fixes ext jwt authentication for HA SDK #484

Merged
merged 2 commits into from
Feb 20, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
104 changes: 102 additions & 2 deletions edge-apis/authwrapper.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import (
manInfo "github.com/openziti/edge-api/rest_management_api_client/informational"
"github.com/openziti/edge-api/rest_model"
"github.com/openziti/edge-api/rest_util"
"github.com/openziti/foundation/v2/errorz"
"github.com/openziti/foundation/v2/stringz"
"github.com/pkg/errors"
"github.com/zitadel/oidc/v2/pkg/client/tokenexchange"
Expand Down Expand Up @@ -426,7 +427,16 @@ func oidcAuth(issuer string, credentials Credentials, configTypes []string, http

formData := payload.toMap()

resp, err = client.R().SetFormData(formData).Post(opLoginUri)
req := client.R()
clientRequest := asClientRequest(req, client)

err = credentials.AuthenticateRequest(clientRequest, strfmt.Default)

if err != nil {
return nil, err
}

resp, err = req.SetFormData(formData).Post(opLoginUri)

if err != nil {
return nil, err
Expand Down Expand Up @@ -456,7 +466,7 @@ func oidcAuth(issuer string, credentials Credentials, configTypes []string, http
return nil, fmt.Errorf("timedout waiting for totpT callback")
}

_, err = client.R().SetBody(&totpCodePayload{
resp, err = client.R().SetBody(&totpCodePayload{
MfaCode: rest_model.MfaCode{
Code: &totpCode,
},
Expand All @@ -466,11 +476,24 @@ func oidcAuth(issuer string, credentials Credentials, configTypes []string, http
if err != nil {
return nil, err
}

if resp.StatusCode() != http.StatusOK {
apiErr := &errorz.ApiError{}
err = json.Unmarshal(resp.Body(), apiErr)

if err != nil {
return nil, fmt.Errorf("could not verify TOTP MFA code recieved %d - could not parse body: %s", resp.StatusCode(), string(resp.Body()))
}

return nil, apiErr

}
}

var outTokens *oidc.Tokens[*oidc.IDTokenClaims]

tokens := <-rpServer.TokenChan

if tokens == nil {
return nil, errors.New("authentication did not complete, received nil tokens")
}
Expand All @@ -493,6 +516,83 @@ func oidcAuth(issuer string, credentials Credentials, configTypes []string, http
}, nil
}

// restyClientRequest is meant to mimic open api's client request which is a combination
// of resty's request and client.
type restyClientRequest struct {
restyRequest *resty.Request
restyClient *resty.Client
}

func (r *restyClientRequest) SetHeaderParam(s string, s2 ...string) error {
r.restyRequest.Header[s] = s2
return nil
}

func (r *restyClientRequest) GetHeaderParams() http.Header {
return r.restyRequest.Header
}

func (r *restyClientRequest) SetQueryParam(s string, s2 ...string) error {
r.restyRequest.QueryParam[s] = s2
return nil
}

func (r *restyClientRequest) SetFormParam(s string, s2 ...string) error {
r.restyRequest.FormData[s] = s2
return nil
}

func (r *restyClientRequest) SetPathParam(s string, s2 string) error {
r.restyRequest.PathParams[s] = s2
return nil
}

func (r *restyClientRequest) GetQueryParams() url.Values {
return r.restyRequest.QueryParam
}

func (r *restyClientRequest) SetFileParam(s string, closer ...runtime.NamedReadCloser) error {
for _, curCloser := range closer {
r.restyRequest.SetFileReader(s, curCloser.Name(), curCloser)
}

return nil
}

func (r *restyClientRequest) SetBodyParam(i interface{}) error {
r.restyRequest.SetBody(i)
return nil
}

func (r *restyClientRequest) SetTimeout(duration time.Duration) error {
r.restyClient.SetTimeout(duration)
return nil
}

func (r *restyClientRequest) GetMethod() string {
return r.restyRequest.Method
}

func (r *restyClientRequest) GetPath() string {
return r.restyRequest.URL
}

func (r *restyClientRequest) GetBody() []byte {
return r.restyRequest.Body.([]byte)
}

func (r *restyClientRequest) GetBodyParam() interface{} {
return r.restyRequest.Body
}

func (r *restyClientRequest) GetFileParam() map[string][]runtime.NamedReadCloser {
return nil
}

func asClientRequest(request *resty.Request, client *resty.Client) runtime.ClientRequest {
return &restyClientRequest{request, client}
}

func ToPtr[T any](s T) *T {
return &s
}
Loading