diff --git a/example/client/api/api.go b/example/client/api/api.go index 4fe09ed..2220554 100644 --- a/example/client/api/api.go +++ b/example/client/api/api.go @@ -34,14 +34,14 @@ func main() { router := mux.NewRouter() - //public url accessible without any authorization - //will print `OK` and current timestamp + // public url accessible without any authorization + // will print `OK` and current timestamp router.HandleFunc(publicURL, func(w http.ResponseWriter, r *http.Request) { w.Write([]byte("OK " + time.Now().String())) }) - //protected url which needs an active token - //will print the result of the introspection endpoint on success + // protected url which needs an active token + // will print the result of the introspection endpoint on success router.HandleFunc(protectedURL, func(w http.ResponseWriter, r *http.Request) { ok, token := checkToken(w, r) if !ok { @@ -60,9 +60,9 @@ func main() { w.Write(data) }) - //protected url which needs an active token and checks if the response of the introspect endpoint - //contains a requested claim with the required (string) value - //e.g. /protected/username/livio@caos.ch + // protected url which needs an active token and checks if the response of the introspect endpoint + // contains a requested claim with the required (string) value + // e.g. /protected/username/livio@caos.ch router.HandleFunc(protectedClaimURL, func(w http.ResponseWriter, r *http.Request) { ok, token := checkToken(w, r) if !ok { diff --git a/example/client/app/app.go b/example/client/app/app.go index 10453b1..c2c8c3f 100644 --- a/example/client/app/app.go +++ b/example/client/app/app.go @@ -48,18 +48,18 @@ func main() { logrus.Fatalf("error creating provider %s", err.Error()) } - //generate some state (representing the state of the user in your application, - //e.g. the page where he was before sending him to login + // generate some state (representing the state of the user in your application, + // e.g. the page where he was before sending him to login state := func() string { return uuid.New().String() } - //register the AuthURLHandler at your preferred path - //the AuthURLHandler creates the auth request and redirects the user to the auth server - //including state handling with secure cookie and the possibility to use PKCE + // register the AuthURLHandler at your preferred path + // the AuthURLHandler creates the auth request and redirects the user to the auth server + // including state handling with secure cookie and the possibility to use PKCE http.Handle("/login", rp.AuthURLHandler(state, provider)) - //for demonstration purposes the returned userinfo response is written as JSON object onto response + // for demonstration purposes the returned userinfo response is written as JSON object onto response marshalUserinfo := func(w http.ResponseWriter, r *http.Request, tokens *oidc.Tokens, state string, rp rp.RelyingParty, info oidc.UserInfo) { data, err := json.Marshal(info) if err != nil { @@ -69,9 +69,9 @@ func main() { w.Write(data) } - //you could also just take the access_token and id_token without calling the userinfo endpoint: + // you could also just take the access_token and id_token without calling the userinfo endpoint: // - //marshalToken := func(w http.ResponseWriter, r *http.Request, tokens *oidc.Tokens, state string, rp rp.RelyingParty) { + // marshalToken := func(w http.ResponseWriter, r *http.Request, tokens *oidc.Tokens, state string, rp rp.RelyingParty) { // data, err := json.Marshal(tokens) // if err != nil { // http.Error(w, err.Error(), http.StatusInternalServerError) @@ -80,16 +80,16 @@ func main() { // w.Write(data) //} - //register the CodeExchangeHandler at the callbackPath - //the CodeExchangeHandler handles the auth response, creates the token request and calls the callback function - //with the returned tokens from the token endpoint - //in this example the callback function itself is wrapped by the UserinfoCallback which - //will call the Userinfo endpoint, check the sub and pass the info into the callback function + // register the CodeExchangeHandler at the callbackPath + // the CodeExchangeHandler handles the auth response, creates the token request and calls the callback function + // with the returned tokens from the token endpoint + // in this example the callback function itself is wrapped by the UserinfoCallback which + // will call the Userinfo endpoint, check the sub and pass the info into the callback function http.Handle(callbackPath, rp.CodeExchangeHandler(rp.UserinfoCallback(marshalUserinfo), provider)) - //if you would use the callback without calling the userinfo endpoint, simply switch the callback handler for: + // if you would use the callback without calling the userinfo endpoint, simply switch the callback handler for: // - //http.Handle(callbackPath, rp.CodeExchangeHandler(marshalToken, provider)) + // http.Handle(callbackPath, rp.CodeExchangeHandler(marshalToken, provider)) lis := fmt.Sprintf("127.0.0.1:%s", port) logrus.Infof("listening on http://%s/", lis) diff --git a/example/client/service/service.go b/example/client/service/service.go index f406c6d..980abcd 100644 --- a/example/client/service/service.go +++ b/example/client/service/service.go @@ -16,9 +16,7 @@ import ( "github.com/zitadel/oidc/pkg/client/profile" ) -var ( - client = http.DefaultClient -) +var client = http.DefaultClient func main() { keyPath := os.Getenv("KEY_PATH") @@ -145,7 +143,6 @@ func main() { if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) } - }) lis := fmt.Sprintf("127.0.0.1:%s", port) logrus.Infof("listening on http://%s/", lis) diff --git a/pkg/client/client.go b/pkg/client/client.go index ccc3cc0..d6d27f7 100644 --- a/pkg/client/client.go +++ b/pkg/client/client.go @@ -15,20 +15,17 @@ import ( "github.com/zitadel/oidc/pkg/oidc" ) -var ( - Encoder = func() httphelper.Encoder { - e := schema.NewEncoder() - e.RegisterEncoder(oidc.SpaceDelimitedArray{}, func(value reflect.Value) string { - return value.Interface().(oidc.SpaceDelimitedArray).Encode() - }) - return e - }() -) +var Encoder = func() httphelper.Encoder { + e := schema.NewEncoder() + e.RegisterEncoder(oidc.SpaceDelimitedArray{}, func(value reflect.Value) string { + return value.Interface().(oidc.SpaceDelimitedArray).Encode() + }) + return e +}() -//Discover calls the discovery endpoint of the provided issuer and returns its configuration -//It accepts an optional argument "wellknownUrl" which can be used to overide the dicovery endpoint url +// Discover calls the discovery endpoint of the provided issuer and returns its configuration +// It accepts an optional argument "wellknownUrl" which can be used to overide the dicovery endpoint url func Discover(issuer string, httpClient *http.Client, wellKnownUrl ...string) (*oidc.DiscoveryConfiguration, error) { - wellKnown := strings.TrimSuffix(issuer, "/") + oidc.DiscoveryEndpoint if len(wellKnownUrl) == 1 && wellKnownUrl[0] != "" { wellKnown = wellKnownUrl[0] diff --git a/pkg/client/key.go b/pkg/client/key.go index f89a2b4..740c6d3 100644 --- a/pkg/client/key.go +++ b/pkg/client/key.go @@ -14,12 +14,12 @@ type keyFile struct { Type string `json:"type"` // serviceaccount or application KeyID string `json:"keyId"` Key string `json:"key"` - Issuer string `json:"issuer"` //not yet in file + Issuer string `json:"issuer"` // not yet in file - //serviceaccount + // serviceaccount UserID string `json:"userId"` - //application + // application ClientID string `json:"clientId"` } diff --git a/pkg/client/profile/jwt_profile.go b/pkg/client/profile/jwt_profile.go index 03fa52a..b29fcaa 100644 --- a/pkg/client/profile/jwt_profile.go +++ b/pkg/client/profile/jwt_profile.go @@ -11,9 +11,9 @@ import ( "github.com/zitadel/oidc/pkg/oidc" ) -//jwtProfileTokenSource implement the oauth2.TokenSource -//it will request a token using the OAuth2 JWT Profile Grant -//therefore sending an `assertion` by singing a JWT with the provided private key +// jwtProfileTokenSource implement the oauth2.TokenSource +// it will request a token using the OAuth2 JWT Profile Grant +// therefore sending an `assertion` by singing a JWT with the provided private key type jwtProfileTokenSource struct { clientID string audience []string diff --git a/pkg/client/rp/delegation.go b/pkg/client/rp/delegation.go index 463a5c4..a2b1f00 100644 --- a/pkg/client/rp/delegation.go +++ b/pkg/client/rp/delegation.go @@ -4,8 +4,8 @@ import ( "github.com/zitadel/oidc/pkg/oidc/grants/tokenexchange" ) -//DelegationTokenRequest is an implementation of TokenExchangeRequest -//it exchanges an "urn:ietf:params:oauth:token-type:access_token" with an optional +// DelegationTokenRequest is an implementation of TokenExchangeRequest +// it exchanges an "urn:ietf:params:oauth:token-type:access_token" with an optional //"urn:ietf:params:oauth:token-type:access_token" actor token for an //"urn:ietf:params:oauth:token-type:access_token" delegation token func DelegationTokenRequest(subjectToken string, opts ...tokenexchange.TokenExchangeOption) *tokenexchange.TokenExchangeRequest { diff --git a/pkg/client/rp/jwks.go b/pkg/client/rp/jwks.go index 0624d6b..cc49eb7 100644 --- a/pkg/client/rp/jwks.go +++ b/pkg/client/rp/jwks.go @@ -21,12 +21,12 @@ func NewRemoteKeySet(client *http.Client, jwksURL string, opts ...func(*remoteKe return keyset } -//SkipRemoteCheck will suppress checking for new remote keys if signature validation fails with cached keys -//and no kid header is set in the JWT +// SkipRemoteCheck will suppress checking for new remote keys if signature validation fails with cached keys +// and no kid header is set in the JWT // -//this might be handy to save some unnecessary round trips in cases where the JWT does not contain a kid header and -//there is only a single remote key -//please notice that remote keys will then only be fetched if cached keys are empty +// this might be handy to save some unnecessary round trips in cases where the JWT does not contain a kid header and +// there is only a single remote key +// please notice that remote keys will then only be fetched if cached keys are empty func SkipRemoteCheck() func(set *remoteKeySet) { return func(set *remoteKeySet) { set.skipRemoteCheck = true @@ -97,15 +97,15 @@ func (r *remoteKeySet) VerifySignature(ctx context.Context, jws *jose.JSONWebSig return r.verifySignatureRemote(ctx, jws, keyID, alg) } -//verifySignatureCached checks for a matching key in the cached key list +// verifySignatureCached checks for a matching key in the cached key list // -//if there is only one possible, it tries to verify the signature and will return the payload if successful +// if there is only one possible, it tries to verify the signature and will return the payload if successful // -//it only returns an error if signature validation fails and keys exactMatch which is if either: +// it only returns an error if signature validation fails and keys exactMatch which is if either: // - both kid are empty and skipRemoteCheck is set to true // - or both (JWT and JWK) kid are equal // -//otherwise it will return no error (so remote keys will be loaded) +// otherwise it will return no error (so remote keys will be loaded) func (r *remoteKeySet) verifySignatureCached(jws *jose.JSONWebSignature, keyID, alg string) ([]byte, error) { keys := r.keysFromCache() if len(keys) == 0 { @@ -113,7 +113,7 @@ func (r *remoteKeySet) verifySignatureCached(jws *jose.JSONWebSignature, keyID, } key, err := oidc.FindMatchingKey(keyID, oidc.KeyUseSignature, alg, keys...) if err != nil { - //no key / multiple found, try with remote keys + // no key / multiple found, try with remote keys return nil, nil //nolint:nilerr } payload, err := jws.Verify(&key) @@ -121,7 +121,7 @@ func (r *remoteKeySet) verifySignatureCached(jws *jose.JSONWebSignature, keyID, return payload, nil } if !r.exactMatch(key.KeyID, keyID) { - //no exact key match, try getting better match with remote keys + // no exact key match, try getting better match with remote keys return nil, nil } return nil, fmt.Errorf("signature verification failed: %w", err) @@ -213,11 +213,11 @@ func (r *remoteKeySet) fetchRemoteKeys(ctx context.Context) ([]jose.JSONWebKey, return keySet.Keys, nil } -//jsonWebKeySet is an alias for jose.JSONWebKeySet which ignores unknown key types (kty) +// jsonWebKeySet is an alias for jose.JSONWebKeySet which ignores unknown key types (kty) type jsonWebKeySet jose.JSONWebKeySet -//UnmarshalJSON overrides the default jose.JSONWebKeySet method to ignore any error -//which might occur because of unknown key types (kty) +// UnmarshalJSON overrides the default jose.JSONWebKeySet method to ignore any error +// which might occur because of unknown key types (kty) func (k *jsonWebKeySet) UnmarshalJSON(data []byte) (err error) { var raw rawJSONWebKeySet err = json.Unmarshal(data, &raw) diff --git a/pkg/client/rp/relying_party.go b/pkg/client/rp/relying_party.go index bf0619a..cb271e7 100644 --- a/pkg/client/rp/relying_party.go +++ b/pkg/client/rp/relying_party.go @@ -23,53 +23,49 @@ const ( pkceCode = "pkce" ) -var ( - ErrUserInfoSubNotMatching = errors.New("sub from userinfo does not match the sub from the id_token") -) +var ErrUserInfoSubNotMatching = errors.New("sub from userinfo does not match the sub from the id_token") -//RelyingParty declares the minimal interface for oidc clients +// RelyingParty declares the minimal interface for oidc clients type RelyingParty interface { - //OAuthConfig returns the oauth2 Config + // OAuthConfig returns the oauth2 Config OAuthConfig() *oauth2.Config - //Issuer returns the issuer of the oidc config + // Issuer returns the issuer of the oidc config Issuer() string - //IsPKCE returns if authorization is done using `Authorization Code Flow with Proof Key for Code Exchange (PKCE)` + // IsPKCE returns if authorization is done using `Authorization Code Flow with Proof Key for Code Exchange (PKCE)` IsPKCE() bool - //CookieHandler returns a http cookie handler used for various state transfer cookies + // CookieHandler returns a http cookie handler used for various state transfer cookies CookieHandler() *httphelper.CookieHandler - //HttpClient returns a http client used for calls to the openid provider, e.g. calling token endpoint + // HttpClient returns a http client used for calls to the openid provider, e.g. calling token endpoint HttpClient() *http.Client - //IsOAuth2Only specifies whether relaying party handles only oauth2 or oidc calls + // IsOAuth2Only specifies whether relaying party handles only oauth2 or oidc calls IsOAuth2Only() bool - //Signer is used if the relaying party uses the JWT Profile + // Signer is used if the relaying party uses the JWT Profile Signer() jose.Signer - //GetEndSessionEndpoint returns the endpoint to sign out on a IDP + // GetEndSessionEndpoint returns the endpoint to sign out on a IDP GetEndSessionEndpoint() string - //UserinfoEndpoint returns the userinfo + // UserinfoEndpoint returns the userinfo UserinfoEndpoint() string - //IDTokenVerifier returns the verifier interface used for oidc id_token verification + // IDTokenVerifier returns the verifier interface used for oidc id_token verification IDTokenVerifier() IDTokenVerifier - //ErrorHandler returns the handler used for callback errors + // ErrorHandler returns the handler used for callback errors ErrorHandler() func(http.ResponseWriter, *http.Request, string, string, string) } type ErrorHandler func(w http.ResponseWriter, r *http.Request, errorType string, errorDesc string, state string) -var ( - DefaultErrorHandler ErrorHandler = func(w http.ResponseWriter, r *http.Request, errorType string, errorDesc string, state string) { - http.Error(w, errorType+": "+errorDesc, http.StatusInternalServerError) - } -) +var DefaultErrorHandler ErrorHandler = func(w http.ResponseWriter, r *http.Request, errorType string, errorDesc string, state string) { + http.Error(w, errorType+": "+errorDesc, http.StatusInternalServerError) +} type relyingParty struct { issuer string @@ -138,9 +134,9 @@ func (rp *relyingParty) ErrorHandler() func(http.ResponseWriter, *http.Request, return rp.errorHandler } -//NewRelyingPartyOAuth creates an (OAuth2) RelyingParty with the given -//OAuth2 Config and possible configOptions -//it will use the AuthURL and TokenURL set in config +// NewRelyingPartyOAuth creates an (OAuth2) RelyingParty with the given +// OAuth2 Config and possible configOptions +// it will use the AuthURL and TokenURL set in config func NewRelyingPartyOAuth(config *oauth2.Config, options ...Option) (RelyingParty, error) { rp := &relyingParty{ oauthConfig: config, @@ -161,9 +157,9 @@ func NewRelyingPartyOAuth(config *oauth2.Config, options ...Option) (RelyingPart return rp, nil } -//NewRelyingPartyOIDC creates an (OIDC) RelyingParty with the given -//issuer, clientID, clientSecret, redirectURI, scopes and possible configOptions -//it will run discovery on the provided issuer and use the found endpoints +// NewRelyingPartyOIDC creates an (OIDC) RelyingParty with the given +// issuer, clientID, clientSecret, redirectURI, scopes and possible configOptions +// it will run discovery on the provided issuer and use the found endpoints func NewRelyingPartyOIDC(issuer, clientID, clientSecret, redirectURI string, scopes []string, options ...Option) (RelyingParty, error) { rp := &relyingParty{ issuer: issuer, @@ -197,7 +193,7 @@ func NewRelyingPartyOIDC(issuer, clientID, clientSecret, redirectURI string, sco return rp, nil } -//Option is the type for providing dynamic options to the relyingParty +// Option is the type for providing dynamic options to the relyingParty type Option func(*relyingParty) error func WithCustomDiscoveryUrl(url string) Option { @@ -207,7 +203,7 @@ func WithCustomDiscoveryUrl(url string) Option { } } -//WithCookieHandler set a `CookieHandler` for securing the various redirects +// WithCookieHandler set a `CookieHandler` for securing the various redirects func WithCookieHandler(cookieHandler *httphelper.CookieHandler) Option { return func(rp *relyingParty) error { rp.cookieHandler = cookieHandler @@ -215,9 +211,9 @@ func WithCookieHandler(cookieHandler *httphelper.CookieHandler) Option { } } -//WithPKCE sets the RP to use PKCE (oauth2 code challenge) -//it also sets a `CookieHandler` for securing the various redirects -//and exchanging the code challenge +// WithPKCE sets the RP to use PKCE (oauth2 code challenge) +// it also sets a `CookieHandler` for securing the various redirects +// and exchanging the code challenge func WithPKCE(cookieHandler *httphelper.CookieHandler) Option { return func(rp *relyingParty) error { rp.pkce = true @@ -226,7 +222,7 @@ func WithPKCE(cookieHandler *httphelper.CookieHandler) Option { } } -//WithHTTPClient provides the ability to set an http client to be used for the relaying party and verifier +// WithHTTPClient provides the ability to set an http client to be used for the relaying party and verifier func WithHTTPClient(client *http.Client) Option { return func(rp *relyingParty) error { rp.httpClient = client @@ -297,7 +293,7 @@ func SignerFromKeyAndKeyID(key []byte, keyID string) SignerFromKey { } } -//Discover calls the discovery endpoint of the provided issuer and returns the found endpoints +// Discover calls the discovery endpoint of the provided issuer and returns the found endpoints // //deprecated: use client.Discover func Discover(issuer string, httpClient *http.Client) (Endpoints, error) { @@ -317,7 +313,7 @@ func Discover(issuer string, httpClient *http.Client) (Endpoints, error) { return GetEndpoints(discoveryConfig), nil } -//AuthURL returns the auth request url +// AuthURL returns the auth request url //(wrapping the oauth2 `AuthCodeURL`) func AuthURL(state string, rp RelyingParty, opts ...AuthURLOpt) string { authOpts := make([]oauth2.AuthCodeOption, 0) @@ -327,8 +323,8 @@ func AuthURL(state string, rp RelyingParty, opts ...AuthURLOpt) string { return rp.OAuthConfig().AuthCodeURL(state, authOpts...) } -//AuthURLHandler extends the `AuthURL` method with a http redirect handler -//including handling setting cookie for secure `state` transfer +// AuthURLHandler extends the `AuthURL` method with a http redirect handler +// including handling setting cookie for secure `state` transfer func AuthURLHandler(stateFn func() string, rp RelyingParty) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { opts := make([]AuthURLOpt, 0) @@ -349,7 +345,7 @@ func AuthURLHandler(stateFn func() string, rp RelyingParty) http.HandlerFunc { } } -//GenerateAndStoreCodeChallenge generates a PKCE code challenge and stores its verifier into a secure cookie +// GenerateAndStoreCodeChallenge generates a PKCE code challenge and stores its verifier into a secure cookie func GenerateAndStoreCodeChallenge(w http.ResponseWriter, rp RelyingParty) (string, error) { codeVerifier := base64.RawURLEncoding.EncodeToString([]byte(uuid.New().String())) if err := rp.CookieHandler().SetCookie(w, pkceCode, codeVerifier); err != nil { @@ -358,8 +354,8 @@ func GenerateAndStoreCodeChallenge(w http.ResponseWriter, rp RelyingParty) (stri return oidc.NewSHACodeChallenge(codeVerifier), nil } -//CodeExchange handles the oauth2 code exchange, extracting and validating the id_token -//returning it parsed together with the oauth2 tokens (access, refresh) +// CodeExchange handles the oauth2 code exchange, extracting and validating the id_token +// returning it parsed together with the oauth2 tokens (access, refresh) func CodeExchange(ctx context.Context, code string, rp RelyingParty, opts ...CodeExchangeOpt) (tokens *oidc.Tokens, err error) { ctx = context.WithValue(ctx, oauth2.HTTPClient, rp.HttpClient()) codeOpts := make([]oauth2.AuthCodeOption, 0) @@ -391,9 +387,9 @@ func CodeExchange(ctx context.Context, code string, rp RelyingParty, opts ...Cod type CodeExchangeCallback func(w http.ResponseWriter, r *http.Request, tokens *oidc.Tokens, state string, rp RelyingParty) -//CodeExchangeHandler extends the `CodeExchange` method with a http handler -//including cookie handling for secure `state` transfer -//and optional PKCE code verifier checking +// CodeExchangeHandler extends the `CodeExchange` method with a http handler +// including cookie handling for secure `state` transfer +// and optional PKCE code verifier checking func CodeExchangeHandler(callback CodeExchangeCallback, rp RelyingParty) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { state, err := tryReadStateCookie(w, r, rp) @@ -434,9 +430,9 @@ func CodeExchangeHandler(callback CodeExchangeCallback, rp RelyingParty) http.Ha type CodeExchangeUserinfoCallback func(w http.ResponseWriter, r *http.Request, tokens *oidc.Tokens, state string, provider RelyingParty, info oidc.UserInfo) -//UserinfoCallback wraps the callback function of the CodeExchangeHandler -//and calls the userinfo endpoint with the access token -//on success it will pass the userinfo into its callback function as well +// UserinfoCallback wraps the callback function of the CodeExchangeHandler +// and calls the userinfo endpoint with the access token +// on success it will pass the userinfo into its callback function as well func UserinfoCallback(f CodeExchangeUserinfoCallback) CodeExchangeCallback { return func(w http.ResponseWriter, r *http.Request, tokens *oidc.Tokens, state string, rp RelyingParty) { info, err := Userinfo(tokens.AccessToken, tokens.TokenType, tokens.IDTokenClaims.GetSubject(), rp) @@ -448,7 +444,7 @@ func UserinfoCallback(f CodeExchangeUserinfoCallback) CodeExchangeCallback { } } -//Userinfo will call the OIDC Userinfo Endpoint with the provided token +// Userinfo will call the OIDC Userinfo Endpoint with the provided token func Userinfo(token, tokenType, subject string, rp RelyingParty) (oidc.UserInfo, error) { req, err := http.NewRequest("GET", rp.UserinfoEndpoint(), nil) if err != nil { @@ -512,7 +508,7 @@ func GetEndpoints(discoveryConfig *oidc.DiscoveryConfiguration) Endpoints { type AuthURLOpt func() []oauth2.AuthCodeOption -//WithCodeChallenge sets the `code_challenge` params in the auth request +// WithCodeChallenge sets the `code_challenge` params in the auth request func WithCodeChallenge(codeChallenge string) AuthURLOpt { return func() []oauth2.AuthCodeOption { return []oauth2.AuthCodeOption{ @@ -522,7 +518,7 @@ func WithCodeChallenge(codeChallenge string) AuthURLOpt { } } -//WithPrompt sets the `prompt` params in the auth request +// WithPrompt sets the `prompt` params in the auth request func WithPrompt(prompt ...string) AuthURLOpt { return func() []oauth2.AuthCodeOption { return []oauth2.AuthCodeOption{ @@ -533,14 +529,14 @@ func WithPrompt(prompt ...string) AuthURLOpt { type CodeExchangeOpt func() []oauth2.AuthCodeOption -//WithCodeVerifier sets the `code_verifier` param in the token request +// WithCodeVerifier sets the `code_verifier` param in the token request func WithCodeVerifier(codeVerifier string) CodeExchangeOpt { return func() []oauth2.AuthCodeOption { return []oauth2.AuthCodeOption{oauth2.SetAuthURLParam("code_verifier", codeVerifier)} } } -//WithClientAssertionJWT sets the `client_assertion` param in the token request +// WithClientAssertionJWT sets the `client_assertion` param in the token request func WithClientAssertionJWT(clientAssertion string) CodeExchangeOpt { return func() []oauth2.AuthCodeOption { return client.ClientAssertionCodeOptions(clientAssertion) diff --git a/pkg/client/rp/tockenexchange.go b/pkg/client/rp/tockenexchange.go index a1cb3be..3950fe1 100644 --- a/pkg/client/rp/tockenexchange.go +++ b/pkg/client/rp/tockenexchange.go @@ -8,20 +8,20 @@ import ( "github.com/zitadel/oidc/pkg/oidc/grants/tokenexchange" ) -//TokenExchangeRP extends the `RelyingParty` interface for the *draft* oauth2 `Token Exchange` +// TokenExchangeRP extends the `RelyingParty` interface for the *draft* oauth2 `Token Exchange` type TokenExchangeRP interface { RelyingParty - //TokenExchange implement the `Token Exchange Grant` exchanging some token for an other + // TokenExchange implement the `Token Exchange Grant` exchanging some token for an other TokenExchange(context.Context, *tokenexchange.TokenExchangeRequest) (*oauth2.Token, error) } -//DelegationTokenExchangeRP extends the `TokenExchangeRP` interface -//for the specific `delegation token` request +// DelegationTokenExchangeRP extends the `TokenExchangeRP` interface +// for the specific `delegation token` request type DelegationTokenExchangeRP interface { TokenExchangeRP - //DelegationTokenExchange implement the `Token Exchange Grant` - //providing an access token in request for a `delegation` token for a given resource / audience + // DelegationTokenExchange implement the `Token Exchange Grant` + // providing an access token in request for a `delegation` token for a given resource / audience DelegationTokenExchange(context.Context, string, ...tokenexchange.TokenExchangeOption) (*oauth2.Token, error) } diff --git a/pkg/client/rp/verifier.go b/pkg/client/rp/verifier.go index 6cf5614..6b3b3fd 100644 --- a/pkg/client/rp/verifier.go +++ b/pkg/client/rp/verifier.go @@ -19,7 +19,7 @@ type IDTokenVerifier interface { MaxAge() time.Duration } -//VerifyTokens implement the Token Response Validation as defined in OIDC specification +// VerifyTokens implement the Token Response Validation as defined in OIDC specification //https://openid.net/specs/openid-connect-core-1_0.html#TokenResponseValidation func VerifyTokens(ctx context.Context, accessToken, idTokenString string, v IDTokenVerifier) (oidc.IDTokenClaims, error) { idToken, err := VerifyIDToken(ctx, idTokenString, v) @@ -32,7 +32,7 @@ func VerifyTokens(ctx context.Context, accessToken, idTokenString string, v IDTo return idToken, nil } -//VerifyIDToken validates the id token according to +// VerifyIDToken validates the id token according to //https://openid.net/specs/openid-connect-core-1_0.html#IDTokenValidation func VerifyIDToken(ctx context.Context, token string, v IDTokenVerifier) (oidc.IDTokenClaims, error) { claims := oidc.EmptyIDTokenClaims() @@ -88,7 +88,7 @@ func VerifyIDToken(ctx context.Context, token string, v IDTokenVerifier) (oidc.I return claims, nil } -//VerifyAccessToken validates the access token according to +// VerifyAccessToken validates the access token according to //https://openid.net/specs/openid-connect-core-1_0.html#CodeFlowTokenValidation func VerifyAccessToken(accessToken, atHash string, sigAlgorithm jose.SignatureAlgorithm) error { if atHash == "" { @@ -105,8 +105,8 @@ func VerifyAccessToken(accessToken, atHash string, sigAlgorithm jose.SignatureAl return nil } -//NewIDTokenVerifier returns an implementation of `IDTokenVerifier` -//for `VerifyTokens` and `VerifyIDToken` +// NewIDTokenVerifier returns an implementation of `IDTokenVerifier` +// for `VerifyTokens` and `VerifyIDToken` func NewIDTokenVerifier(issuer, clientID string, keySet oidc.KeySet, options ...VerifierOption) IDTokenVerifier { v := &idTokenVerifier{ issuer: issuer, @@ -125,46 +125,46 @@ func NewIDTokenVerifier(issuer, clientID string, keySet oidc.KeySet, options ... return v } -//VerifierOption is the type for providing dynamic options to the IDTokenVerifier +// VerifierOption is the type for providing dynamic options to the IDTokenVerifier type VerifierOption func(*idTokenVerifier) -//WithIssuedAtOffset mitigates the risk of iat to be in the future -//because of clock skews with the ability to add an offset to the current time +// WithIssuedAtOffset mitigates the risk of iat to be in the future +// because of clock skews with the ability to add an offset to the current time func WithIssuedAtOffset(offset time.Duration) func(*idTokenVerifier) { return func(v *idTokenVerifier) { v.offset = offset } } -//WithIssuedAtMaxAge provides the ability to define the maximum duration between iat and now +// WithIssuedAtMaxAge provides the ability to define the maximum duration between iat and now func WithIssuedAtMaxAge(maxAge time.Duration) func(*idTokenVerifier) { return func(v *idTokenVerifier) { v.maxAge = maxAge } } -//WithNonce sets the function to check the nonce +// WithNonce sets the function to check the nonce func WithNonce(nonce func(context.Context) string) VerifierOption { return func(v *idTokenVerifier) { v.nonce = nonce } } -//WithACRVerifier sets the verifier for the acr claim +// WithACRVerifier sets the verifier for the acr claim func WithACRVerifier(verifier oidc.ACRVerifier) VerifierOption { return func(v *idTokenVerifier) { v.acr = verifier } } -//WithAuthTimeMaxAge provides the ability to define the maximum duration between auth_time and now +// WithAuthTimeMaxAge provides the ability to define the maximum duration between auth_time and now func WithAuthTimeMaxAge(maxAge time.Duration) VerifierOption { return func(v *idTokenVerifier) { v.maxAge = maxAge } } -//WithSupportedSigningAlgorithms overwrites the default RS256 signing algorithm +// WithSupportedSigningAlgorithms overwrites the default RS256 signing algorithm func WithSupportedSigningAlgorithms(algs ...string) VerifierOption { return func(v *idTokenVerifier) { v.supportedSignAlgs = algs diff --git a/pkg/client/rs/resource_server.go b/pkg/client/rs/resource_server.go index 63b29d4..b1bc47e 100644 --- a/pkg/client/rs/resource_server.go +++ b/pkg/client/rs/resource_server.go @@ -43,6 +43,7 @@ func NewResourceServerClientCredentials(issuer, clientID, clientSecret string, o } return newResourceServer(issuer, authorizer, option...) } + func NewResourceServerJWTProfile(issuer, clientID, keyID string, key []byte, options ...Option) (ResourceServer, error) { signer, err := client.NewSignerFromPrivateKeyByte(key, keyID) if err != nil { @@ -91,14 +92,14 @@ func NewResourceServerFromKeyFile(issuer, path string, options ...Option) (Resou type Option func(*resourceServer) -//WithClient provides the ability to set an http client to be used for the resource server +// WithClient provides the ability to set an http client to be used for the resource server func WithClient(client *http.Client) Option { return func(server *resourceServer) { server.httpClient = client } } -//WithStaticEndpoints provides the ability to set static token and introspect URL +// WithStaticEndpoints provides the ability to set static token and introspect URL func WithStaticEndpoints(tokenURL, introspectURL string) Option { return func(server *resourceServer) { server.tokenURL = tokenURL diff --git a/pkg/crypto/crypto.go b/pkg/crypto/crypto.go index 488d8a4..109fa0b 100644 --- a/pkg/crypto/crypto.go +++ b/pkg/crypto/crypto.go @@ -9,9 +9,7 @@ import ( "io" ) -var ( - ErrCipherTextBlockSize = errors.New("ciphertext block size is too short") -) +var ErrCipherTextBlockSize = errors.New("ciphertext block size is too short") func EncryptAES(data string, key string) (string, error) { encrypted, err := EncryptBytesAES([]byte(data), key) diff --git a/pkg/crypto/hash.go b/pkg/crypto/hash.go index 6529249..6fcc71f 100644 --- a/pkg/crypto/hash.go +++ b/pkg/crypto/hash.go @@ -11,9 +11,7 @@ import ( "gopkg.in/square/go-jose.v2" ) -var ( - ErrUnsupportedAlgorithm = errors.New("unsupported signing algorithm") -) +var ErrUnsupportedAlgorithm = errors.New("unsupported signing algorithm") func GetHashAlgorithm(sigAlgorithm jose.SignatureAlgorithm) (hash.Hash, error) { switch sigAlgorithm { diff --git a/pkg/http/http.go b/pkg/http/http.go index b0d1ef7..0e97b6f 100644 --- a/pkg/http/http.go +++ b/pkg/http/http.go @@ -12,15 +12,14 @@ import ( "time" ) -var ( - DefaultHTTPClient = &http.Client{ - Timeout: 30 * time.Second, - } -) +var DefaultHTTPClient = &http.Client{ + Timeout: 30 * time.Second, +} type Decoder interface { Decode(dst interface{}, src map[string][]string) error } + type Encoder interface { Encode(src interface{}, dst map[string][]string) error } diff --git a/pkg/oidc/authorization.go b/pkg/oidc/authorization.go index e6cfe58..f620ecb 100644 --- a/pkg/oidc/authorization.go +++ b/pkg/oidc/authorization.go @@ -1,40 +1,40 @@ package oidc const ( - //ScopeOpenID defines the scope `openid` - //OpenID Connect requests MUST contain the `openid` scope value + // ScopeOpenID defines the scope `openid` + // OpenID Connect requests MUST contain the `openid` scope value ScopeOpenID = "openid" - //ScopeProfile defines the scope `profile` - //This (optional) scope value requests access to the End-User's default profile Claims, - //which are: name, family_name, given_name, middle_name, nickname, preferred_username, - //profile, picture, website, gender, birthdate, zoneinfo, locale, and updated_at. + // ScopeProfile defines the scope `profile` + // This (optional) scope value requests access to the End-User's default profile Claims, + // which are: name, family_name, given_name, middle_name, nickname, preferred_username, + // profile, picture, website, gender, birthdate, zoneinfo, locale, and updated_at. ScopeProfile = "profile" - //ScopeEmail defines the scope `email` - //This (optional) scope value requests access to the email and email_verified Claims. + // ScopeEmail defines the scope `email` + // This (optional) scope value requests access to the email and email_verified Claims. ScopeEmail = "email" - //ScopeAddress defines the scope `address` - //This (optional) scope value requests access to the address Claim. + // ScopeAddress defines the scope `address` + // This (optional) scope value requests access to the address Claim. ScopeAddress = "address" - //ScopePhone defines the scope `phone` - //This (optional) scope value requests access to the phone_number and phone_number_verified Claims. + // ScopePhone defines the scope `phone` + // This (optional) scope value requests access to the phone_number and phone_number_verified Claims. ScopePhone = "phone" - //ScopeOfflineAccess defines the scope `offline_access` - //This (optional) scope value requests that an OAuth 2.0 Refresh Token be issued that can be used to obtain an Access Token - //that grants access to the End-User's UserInfo Endpoint even when the End-User is not present (not logged in). + // ScopeOfflineAccess defines the scope `offline_access` + // This (optional) scope value requests that an OAuth 2.0 Refresh Token be issued that can be used to obtain an Access Token + // that grants access to the End-User's UserInfo Endpoint even when the End-User is not present (not logged in). ScopeOfflineAccess = "offline_access" - //ResponseTypeCode for the Authorization Code Flow returning a code from the Authorization Server + // ResponseTypeCode for the Authorization Code Flow returning a code from the Authorization Server ResponseTypeCode ResponseType = "code" - //ResponseTypeIDToken for the Implicit Flow returning id and access tokens directly from the Authorization Server + // ResponseTypeIDToken for the Implicit Flow returning id and access tokens directly from the Authorization Server ResponseTypeIDToken ResponseType = "id_token token" - //ResponseTypeIDTokenOnly for the Implicit Flow returning only id token directly from the Authorization Server + // ResponseTypeIDTokenOnly for the Implicit Flow returning only id token directly from the Authorization Server ResponseTypeIDTokenOnly ResponseType = "id_token" DisplayPage Display = "page" @@ -45,21 +45,21 @@ const ( ResponseModeQuery ResponseMode = "query" ResponseModeFragment ResponseMode = "fragment" - //PromptNone (`none`) disallows the Authorization Server to display any authentication or consent user interface pages. - //An error (login_required, interaction_required, ...) will be returned if the user is not already authenticated or consent is needed + // PromptNone (`none`) disallows the Authorization Server to display any authentication or consent user interface pages. + // An error (login_required, interaction_required, ...) will be returned if the user is not already authenticated or consent is needed PromptNone = "none" - //PromptLogin (`login`) directs the Authorization Server to prompt the End-User for reauthentication. + // PromptLogin (`login`) directs the Authorization Server to prompt the End-User for reauthentication. PromptLogin = "login" - //PromptConsent (`consent`) directs the Authorization Server to prompt the End-User for consent (of sharing information). + // PromptConsent (`consent`) directs the Authorization Server to prompt the End-User for consent (of sharing information). PromptConsent = "consent" - //PromptSelectAccount (`select_account `) directs the Authorization Server to prompt the End-User to select a user account (to enable multi user / session switching) + // PromptSelectAccount (`select_account `) directs the Authorization Server to prompt the End-User to select a user account (to enable multi user / session switching) PromptSelectAccount = "select_account" ) -//AuthRequest according to: +// AuthRequest according to: //https://openid.net/specs/openid-connect-core-1_0.html#AuthRequest type AuthRequest struct { Scopes SpaceDelimitedArray `json:"scope" schema:"scope"` @@ -82,21 +82,21 @@ type AuthRequest struct { CodeChallenge string `json:"code_challenge" schema:"code_challenge"` CodeChallengeMethod CodeChallengeMethod `json:"code_challenge_method" schema:"code_challenge_method"` - //RequestParam enables OIDC requests to be passed in a single, self-contained parameter (as JWT, called Request Object) + // RequestParam enables OIDC requests to be passed in a single, self-contained parameter (as JWT, called Request Object) RequestParam string `schema:"request"` } -//GetRedirectURI returns the redirect_uri value for the ErrAuthRequest interface +// GetRedirectURI returns the redirect_uri value for the ErrAuthRequest interface func (a *AuthRequest) GetRedirectURI() string { return a.RedirectURI } -//GetResponseType returns the response_type value for the ErrAuthRequest interface +// GetResponseType returns the response_type value for the ErrAuthRequest interface func (a *AuthRequest) GetResponseType() ResponseType { return a.ResponseType } -//GetState returns the optional state value for the ErrAuthRequest interface +// GetState returns the optional state value for the ErrAuthRequest interface func (a *AuthRequest) GetState() string { return a.State } diff --git a/pkg/oidc/discovery.go b/pkg/oidc/discovery.go index 673d628..4a817e8 100644 --- a/pkg/oidc/discovery.go +++ b/pkg/oidc/discovery.go @@ -9,143 +9,143 @@ const ( ) type DiscoveryConfiguration struct { - //Issuer is the identifier of the OP and is used in the tokens as `iss` claim. + // Issuer is the identifier of the OP and is used in the tokens as `iss` claim. Issuer string `json:"issuer,omitempty"` - //AuthorizationEndpoint is the URL of the OAuth 2.0 Authorization Endpoint where all user interactive login start + // AuthorizationEndpoint is the URL of the OAuth 2.0 Authorization Endpoint where all user interactive login start AuthorizationEndpoint string `json:"authorization_endpoint,omitempty"` - //TokenEndpoint is the URL of the OAuth 2.0 Token Endpoint where all tokens are issued, except when using Implicit Flow + // TokenEndpoint is the URL of the OAuth 2.0 Token Endpoint where all tokens are issued, except when using Implicit Flow TokenEndpoint string `json:"token_endpoint,omitempty"` - //IntrospectionEndpoint is the URL of the OAuth 2.0 Introspection Endpoint. + // IntrospectionEndpoint is the URL of the OAuth 2.0 Introspection Endpoint. IntrospectionEndpoint string `json:"introspection_endpoint,omitempty"` - //UserinfoEndpoint is the URL where an access_token can be used to retrieve the Userinfo. + // UserinfoEndpoint is the URL where an access_token can be used to retrieve the Userinfo. UserinfoEndpoint string `json:"userinfo_endpoint,omitempty"` - //RevocationEndpoint is the URL of the OAuth 2.0 Revocation Endpoint. + // RevocationEndpoint is the URL of the OAuth 2.0 Revocation Endpoint. RevocationEndpoint string `json:"revocation_endpoint,omitempty"` - //EndSessionEndpoint is a URL where the RP can perform a redirect to request that the End-User be logged out at the OP. + // EndSessionEndpoint is a URL where the RP can perform a redirect to request that the End-User be logged out at the OP. EndSessionEndpoint string `json:"end_session_endpoint,omitempty"` - //CheckSessionIframe is a URL where the OP provides an iframe that support cross-origin communications for session state information with the RP Client. + // CheckSessionIframe is a URL where the OP provides an iframe that support cross-origin communications for session state information with the RP Client. CheckSessionIframe string `json:"check_session_iframe,omitempty"` - //JwksURI is the URL of the JSON Web Key Set. This site contains the signing keys that RPs can use to validate the signature. - //It may also contain the OP's encryption keys that RPs can use to encrypt request to the OP. + // JwksURI is the URL of the JSON Web Key Set. This site contains the signing keys that RPs can use to validate the signature. + // It may also contain the OP's encryption keys that RPs can use to encrypt request to the OP. JwksURI string `json:"jwks_uri,omitempty"` - //RegistrationEndpoint is the URL for the Dynamic Client Registration. + // RegistrationEndpoint is the URL for the Dynamic Client Registration. RegistrationEndpoint string `json:"registration_endpoint,omitempty"` - //ScopesSupported lists an array of supported scopes. This list must not include every supported scope by the OP. + // ScopesSupported lists an array of supported scopes. This list must not include every supported scope by the OP. ScopesSupported []string `json:"scopes_supported,omitempty"` - //ResponseTypesSupported contains a list of the OAuth 2.0 response_type values that the OP supports (code, id_token, token id_token, ...). + // ResponseTypesSupported contains a list of the OAuth 2.0 response_type values that the OP supports (code, id_token, token id_token, ...). ResponseTypesSupported []string `json:"response_types_supported,omitempty"` - //ResponseModesSupported contains a list of the OAuth 2.0 response_mode values that the OP supports. If omitted, the default value is ["query", "fragment"]. + // ResponseModesSupported contains a list of the OAuth 2.0 response_mode values that the OP supports. If omitted, the default value is ["query", "fragment"]. ResponseModesSupported []string `json:"response_modes_supported,omitempty"` - //GrantTypesSupported contains a list of the OAuth 2.0 grant_type values that the OP supports. If omitted, the default value is ["authorization_code", "implicit"]. + // GrantTypesSupported contains a list of the OAuth 2.0 grant_type values that the OP supports. If omitted, the default value is ["authorization_code", "implicit"]. GrantTypesSupported []GrantType `json:"grant_types_supported,omitempty"` - //ACRValuesSupported contains a list of Authentication Context Class References that the OP supports. + // ACRValuesSupported contains a list of Authentication Context Class References that the OP supports. ACRValuesSupported []string `json:"acr_values_supported,omitempty"` - //SubjectTypesSupported contains a list of Subject Identifier types that the OP supports (pairwise, public). + // SubjectTypesSupported contains a list of Subject Identifier types that the OP supports (pairwise, public). SubjectTypesSupported []string `json:"subject_types_supported,omitempty"` - //IDTokenSigningAlgValuesSupported contains a list of JWS signing algorithms (alg values) supported by the OP for the ID Token. + // IDTokenSigningAlgValuesSupported contains a list of JWS signing algorithms (alg values) supported by the OP for the ID Token. IDTokenSigningAlgValuesSupported []string `json:"id_token_signing_alg_values_supported,omitempty"` - //IDTokenEncryptionAlgValuesSupported contains a list of JWE encryption algorithms (alg values) supported by the OP for the ID Token. + // IDTokenEncryptionAlgValuesSupported contains a list of JWE encryption algorithms (alg values) supported by the OP for the ID Token. IDTokenEncryptionAlgValuesSupported []string `json:"id_token_encryption_alg_values_supported,omitempty"` - //IDTokenEncryptionEncValuesSupported contains a list of JWE encryption algorithms (enc values) supported by the OP for the ID Token. + // IDTokenEncryptionEncValuesSupported contains a list of JWE encryption algorithms (enc values) supported by the OP for the ID Token. IDTokenEncryptionEncValuesSupported []string `json:"id_token_encryption_enc_values_supported,omitempty"` - //UserinfoSigningAlgValuesSupported contains a list of JWS signing algorithms (alg values) supported by the OP for UserInfo Endpoint. + // UserinfoSigningAlgValuesSupported contains a list of JWS signing algorithms (alg values) supported by the OP for UserInfo Endpoint. UserinfoSigningAlgValuesSupported []string `json:"userinfo_signing_alg_values_supported,omitempty"` - //UserinfoEncryptionAlgValuesSupported contains a list of JWE encryption algorithms (alg values) supported by the OP for the UserInfo Endpoint. + // UserinfoEncryptionAlgValuesSupported contains a list of JWE encryption algorithms (alg values) supported by the OP for the UserInfo Endpoint. UserinfoEncryptionAlgValuesSupported []string `json:"userinfo_encryption_alg_values_supported,omitempty"` - //UserinfoEncryptionEncValuesSupported contains a list of JWE encryption algorithms (enc values) supported by the OP for the UserInfo Endpoint. + // UserinfoEncryptionEncValuesSupported contains a list of JWE encryption algorithms (enc values) supported by the OP for the UserInfo Endpoint. UserinfoEncryptionEncValuesSupported []string `json:"userinfo_encryption_enc_values_supported,omitempty"` - //RequestObjectSigningAlgValuesSupported contains a list of JWS signing algorithms (alg values) supported by the OP for Request Objects. - //These algorithms are used both then the Request Object is passed by value (using the request parameter) and when it is passed by reference (using the request_uri parameter). + // RequestObjectSigningAlgValuesSupported contains a list of JWS signing algorithms (alg values) supported by the OP for Request Objects. + // These algorithms are used both then the Request Object is passed by value (using the request parameter) and when it is passed by reference (using the request_uri parameter). RequestObjectSigningAlgValuesSupported []string `json:"request_object_signing_alg_values_supported,omitempty"` - //RequestObjectEncryptionAlgValuesSupported contains a list of JWE encryption algorithms (alg values) supported by the OP for Request Objects. - //These algorithms are used both when the Request Object is passed by value and by reference. + // RequestObjectEncryptionAlgValuesSupported contains a list of JWE encryption algorithms (alg values) supported by the OP for Request Objects. + // These algorithms are used both when the Request Object is passed by value and by reference. RequestObjectEncryptionAlgValuesSupported []string `json:"request_object_encryption_alg_values_supported,omitempty"` - //RequestObjectEncryptionEncValuesSupported contains a list of JWE encryption algorithms (enc values) supported by the OP for Request Objects. - //These algorithms are used both when the Request Object is passed by value and by reference. + // RequestObjectEncryptionEncValuesSupported contains a list of JWE encryption algorithms (enc values) supported by the OP for Request Objects. + // These algorithms are used both when the Request Object is passed by value and by reference. RequestObjectEncryptionEncValuesSupported []string `json:"request_object_encryption_enc_values_supported,omitempty"` - //TokenEndpointAuthMethodsSupported contains a list of Client Authentication methods supported by the Token Endpoint. If omitted, the default is client_secret_basic. + // TokenEndpointAuthMethodsSupported contains a list of Client Authentication methods supported by the Token Endpoint. If omitted, the default is client_secret_basic. TokenEndpointAuthMethodsSupported []AuthMethod `json:"token_endpoint_auth_methods_supported,omitempty"` - //TokenEndpointAuthSigningAlgValuesSupported contains a list of JWS signing algorithms (alg values) supported by the Token Endpoint - //for the signature of the JWT used to authenticate the Client by private_key_jwt and client_secret_jwt. + // TokenEndpointAuthSigningAlgValuesSupported contains a list of JWS signing algorithms (alg values) supported by the Token Endpoint + // for the signature of the JWT used to authenticate the Client by private_key_jwt and client_secret_jwt. TokenEndpointAuthSigningAlgValuesSupported []string `json:"token_endpoint_auth_signing_alg_values_supported,omitempty"` - //RevocationEndpointAuthMethodsSupported contains a list of Client Authentication methods supported by the Revocation Endpoint. If omitted, the default is client_secret_basic. + // RevocationEndpointAuthMethodsSupported contains a list of Client Authentication methods supported by the Revocation Endpoint. If omitted, the default is client_secret_basic. RevocationEndpointAuthMethodsSupported []AuthMethod `json:"revocation_endpoint_auth_methods_supported,omitempty"` - //RevocationEndpointAuthSigningAlgValuesSupported contains a list of JWS signing algorithms (alg values) supported by the Revocation Endpoint - //for the signature of the JWT used to authenticate the Client by private_key_jwt and client_secret_jwt. + // RevocationEndpointAuthSigningAlgValuesSupported contains a list of JWS signing algorithms (alg values) supported by the Revocation Endpoint + // for the signature of the JWT used to authenticate the Client by private_key_jwt and client_secret_jwt. RevocationEndpointAuthSigningAlgValuesSupported []string `json:"revocation_endpoint_auth_signing_alg_values_supported,omitempty"` - //IntrospectionEndpointAuthMethodsSupported contains a list of Client Authentication methods supported by the Introspection Endpoint. + // IntrospectionEndpointAuthMethodsSupported contains a list of Client Authentication methods supported by the Introspection Endpoint. IntrospectionEndpointAuthMethodsSupported []AuthMethod `json:"introspection_endpoint_auth_methods_supported,omitempty"` - //IntrospectionEndpointAuthSigningAlgValuesSupported contains a list of JWS signing algorithms (alg values) supported by the Revocation Endpoint - //for the signature of the JWT used to authenticate the Client by private_key_jwt and client_secret_jwt. + // IntrospectionEndpointAuthSigningAlgValuesSupported contains a list of JWS signing algorithms (alg values) supported by the Revocation Endpoint + // for the signature of the JWT used to authenticate the Client by private_key_jwt and client_secret_jwt. IntrospectionEndpointAuthSigningAlgValuesSupported []string `json:"introspection_endpoint_auth_signing_alg_values_supported,omitempty"` - //DisplayValuesSupported contains a list of display parameter values that the OP supports (page, popup, touch, wap). + // DisplayValuesSupported contains a list of display parameter values that the OP supports (page, popup, touch, wap). DisplayValuesSupported []Display `json:"display_values_supported,omitempty"` - //ClaimTypesSupported contains a list of Claim Types that the OP supports (normal, aggregated, distributed). If omitted, the default is normal Claims. + // ClaimTypesSupported contains a list of Claim Types that the OP supports (normal, aggregated, distributed). If omitted, the default is normal Claims. ClaimTypesSupported []string `json:"claim_types_supported,omitempty"` - //ClaimsSupported contains a list of Claim Names the OP may be able to supply values for. This list might not be exhaustive. + // ClaimsSupported contains a list of Claim Names the OP may be able to supply values for. This list might not be exhaustive. ClaimsSupported []string `json:"claims_supported,omitempty"` - //ClaimsParameterSupported specifies whether the OP supports use of the `claims` parameter. If omitted, the default is false. + // ClaimsParameterSupported specifies whether the OP supports use of the `claims` parameter. If omitted, the default is false. ClaimsParameterSupported bool `json:"claims_parameter_supported,omitempty"` - //CodeChallengeMethodsSupported contains a list of Proof Key for Code Exchange (PKCE) code challenge methods supported by the OP. + // CodeChallengeMethodsSupported contains a list of Proof Key for Code Exchange (PKCE) code challenge methods supported by the OP. CodeChallengeMethodsSupported []CodeChallengeMethod `json:"code_challenge_methods_supported,omitempty"` - //ServiceDocumentation is a URL where developers can get information about the OP and its usage. + // ServiceDocumentation is a URL where developers can get information about the OP and its usage. ServiceDocumentation string `json:"service_documentation,omitempty"` - //ClaimsLocalesSupported contains a list of BCP47 language tag values that the OP supports for values of Claims returned. + // ClaimsLocalesSupported contains a list of BCP47 language tag values that the OP supports for values of Claims returned. ClaimsLocalesSupported []language.Tag `json:"claims_locales_supported,omitempty"` - //UILocalesSupported contains a list of BCP47 language tag values that the OP supports for the user interface. + // UILocalesSupported contains a list of BCP47 language tag values that the OP supports for the user interface. UILocalesSupported []language.Tag `json:"ui_locales_supported,omitempty"` - //RequestParameterSupported specifies whether the OP supports use of the `request` parameter. If omitted, the default value is false. + // RequestParameterSupported specifies whether the OP supports use of the `request` parameter. If omitted, the default value is false. RequestParameterSupported bool `json:"request_parameter_supported,omitempty"` - //RequestURIParameterSupported specifies whether the OP supports use of the `request_uri` parameter. If omitted, the default value is true. (therefore no omitempty) + // RequestURIParameterSupported specifies whether the OP supports use of the `request_uri` parameter. If omitted, the default value is true. (therefore no omitempty) RequestURIParameterSupported bool `json:"request_uri_parameter_supported"` - //RequireRequestURIRegistration specifies whether the OP requires any `request_uri` to be pre-registered using the request_uris registration parameter. If omitted, the default value is false. + // RequireRequestURIRegistration specifies whether the OP requires any `request_uri` to be pre-registered using the request_uris registration parameter. If omitted, the default value is false. RequireRequestURIRegistration bool `json:"require_request_uri_registration,omitempty"` - //OPPolicyURI is a URL the OP provides to the person registering the Client to read about the OP's requirements on how the RP can use the data provided by the OP. + // OPPolicyURI is a URL the OP provides to the person registering the Client to read about the OP's requirements on how the RP can use the data provided by the OP. OPPolicyURI string `json:"op_policy_uri,omitempty"` - //OPTermsOfServiceURI is a URL the OpenID Provider provides to the person registering the Client to read about OpenID Provider's terms of service. + // OPTermsOfServiceURI is a URL the OpenID Provider provides to the person registering the Client to read about OpenID Provider's terms of service. OPTermsOfServiceURI string `json:"op_tos_uri,omitempty"` } diff --git a/pkg/oidc/grants/client_credentials.go b/pkg/oidc/grants/client_credentials.go index e9f467e..8cb8425 100644 --- a/pkg/oidc/grants/client_credentials.go +++ b/pkg/oidc/grants/client_credentials.go @@ -13,8 +13,8 @@ type clientCredentialsGrant struct { clientSecret string `schema:"client_secret"` } -//ClientCredentialsGrantBasic creates an oauth2 `Client Credentials` Grant -//sending client_id and client_secret as basic auth header +// ClientCredentialsGrantBasic creates an oauth2 `Client Credentials` Grant +// sending client_id and client_secret as basic auth header func ClientCredentialsGrantBasic(scopes ...string) *clientCredentialsGrantBasic { return &clientCredentialsGrantBasic{ grantType: "client_credentials", @@ -22,8 +22,8 @@ func ClientCredentialsGrantBasic(scopes ...string) *clientCredentialsGrantBasic } } -//ClientCredentialsGrantValues creates an oauth2 `Client Credentials` Grant -//sending client_id and client_secret as form values +// ClientCredentialsGrantValues creates an oauth2 `Client Credentials` Grant +// sending client_id and client_secret as form values func ClientCredentialsGrantValues(clientID, clientSecret string, scopes ...string) *clientCredentialsGrant { return &clientCredentialsGrant{ clientCredentialsGrantBasic: ClientCredentialsGrantBasic(scopes...), diff --git a/pkg/oidc/jwt_profile.go b/pkg/oidc/jwt_profile.go index 25b7caa..66fa3aa 100644 --- a/pkg/oidc/jwt_profile.go +++ b/pkg/oidc/jwt_profile.go @@ -6,9 +6,9 @@ type JWTProfileGrantRequest struct { GrantType GrantType `schema:"grant_type"` } -//NewJWTProfileGrantRequest creates an oauth2 `JSON Web Token (JWT) Profile` Grant +// NewJWTProfileGrantRequest creates an oauth2 `JSON Web Token (JWT) Profile` Grant //`urn:ietf:params:oauth:grant-type:jwt-bearer` -//sending a self-signed jwt as assertion +// sending a self-signed jwt as assertion func NewJWTProfileGrantRequest(assertion string, scopes ...string) *JWTProfileGrantRequest { return &JWTProfileGrantRequest{ GrantType: GrantTypeBearer, diff --git a/pkg/oidc/keyset.go b/pkg/oidc/keyset.go index 57fe526..c6e865b 100644 --- a/pkg/oidc/keyset.go +++ b/pkg/oidc/keyset.go @@ -19,16 +19,16 @@ var ( ErrKeyNone = errors.New("no possible keys matches") ) -//KeySet represents a set of JSON Web Keys +// KeySet represents a set of JSON Web Keys // - remotely fetch via discovery and jwks_uri -> `remoteKeySet` // - held by the OP itself in storage -> `openIDKeySet` // - dynamically aggregated by request for OAuth JWT Profile Assertion -> `jwtProfileKeySet` type KeySet interface { - //VerifySignature verifies the signature with the given keyset and returns the raw payload + // VerifySignature verifies the signature with the given keyset and returns the raw payload VerifySignature(ctx context.Context, jws *jose.JSONWebSignature) (payload []byte, err error) } -//GetKeyIDAndAlg returns the `kid` and `alg` claim from the JWS header +// GetKeyIDAndAlg returns the `kid` and `alg` claim from the JWS header func GetKeyIDAndAlg(jws *jose.JSONWebSignature) (string, string) { keyID := "" alg := "" @@ -40,11 +40,11 @@ func GetKeyIDAndAlg(jws *jose.JSONWebSignature) (string, string) { return keyID, alg } -//FindKey searches the given JSON Web Keys for the requested key ID, usage and key type +// FindKey searches the given JSON Web Keys for the requested key ID, usage and key type // -//will return the key immediately if matches exact (id, usage, type) +// will return the key immediately if matches exact (id, usage, type) // -//will return false none or multiple match +// will return false none or multiple match // //deprecated: use FindMatchingKey which will return an error (more specific) instead of just a bool //moved implementation already to FindMatchingKey @@ -53,35 +53,35 @@ func FindKey(keyID, use, expectedAlg string, keys ...jose.JSONWebKey) (jose.JSON return key, err == nil } -//FindMatchingKey searches the given JSON Web Keys for the requested key ID, usage and alg type +// FindMatchingKey searches the given JSON Web Keys for the requested key ID, usage and alg type // -//will return the key immediately if matches exact (id, usage, type) +// will return the key immediately if matches exact (id, usage, type) // -//will return a specific error if none (ErrKeyNone) or multiple (ErrKeyMultiple) match +// will return a specific error if none (ErrKeyNone) or multiple (ErrKeyMultiple) match func FindMatchingKey(keyID, use, expectedAlg string, keys ...jose.JSONWebKey) (key jose.JSONWebKey, err error) { var validKeys []jose.JSONWebKey for _, k := range keys { - //ignore all keys with wrong use (let empty use of published key pass) + // ignore all keys with wrong use (let empty use of published key pass) if k.Use != use && k.Use != "" { continue } - //ignore all keys with wrong algorithm type + // ignore all keys with wrong algorithm type if !algToKeyType(k.Key, expectedAlg) { continue } - //if we get here, use and alg match, so an equal (not empty) keyID is an exact match + // if we get here, use and alg match, so an equal (not empty) keyID is an exact match if k.KeyID == keyID && keyID != "" { return k, nil } - //keyIDs did not match or at least one was empty (if later, then it could be a match) + // keyIDs did not match or at least one was empty (if later, then it could be a match) if k.KeyID == "" || keyID == "" { validKeys = append(validKeys, k) } } - //if we get here, no match was possible at all (use / alg) or no exact match due to - //the signed JWT and / or the published keys didn't have a kid - //if later applies and only one key could be found, we'll return it - //otherwise a corresponding error will be thrown + // if we get here, no match was possible at all (use / alg) or no exact match due to + // the signed JWT and / or the published keys didn't have a kid + // if later applies and only one key could be found, we'll return it + // otherwise a corresponding error will be thrown if len(validKeys) == 1 { return validKeys[0], nil } diff --git a/pkg/oidc/session.go b/pkg/oidc/session.go index 9aa70c1..b470d1e 100644 --- a/pkg/oidc/session.go +++ b/pkg/oidc/session.go @@ -1,6 +1,6 @@ package oidc -//EndSessionRequest for the RP-Initiated Logout according to: +// EndSessionRequest for the RP-Initiated Logout according to: //https://openid.net/specs/openid-connect-rpinitiated-1_0.html#RPLogout type EndSessionRequest struct { IdTokenHint string `schema:"id_token_hint"` diff --git a/pkg/oidc/token.go b/pkg/oidc/token.go index 9c8c48b..784684d 100644 --- a/pkg/oidc/token.go +++ b/pkg/oidc/token.go @@ -14,7 +14,7 @@ import ( ) const ( - //BearerToken defines the token_type `Bearer`, which is returned in a successful token response + // BearerToken defines the token_type `Bearer`, which is returned in a successful token response BearerToken = "Bearer" PrefixBearer = BearerToken + " " @@ -91,62 +91,62 @@ type accessTokenClaims struct { signatureAlg jose.SignatureAlgorithm `json:"-"` } -//GetIssuer implements the Claims interface +// GetIssuer implements the Claims interface func (a *accessTokenClaims) GetIssuer() string { return a.Issuer } -//GetAudience implements the Claims interface +// GetAudience implements the Claims interface func (a *accessTokenClaims) GetAudience() []string { return a.Audience } -//GetExpiration implements the Claims interface +// GetExpiration implements the Claims interface func (a *accessTokenClaims) GetExpiration() time.Time { return time.Time(a.Expiration) } -//GetIssuedAt implements the Claims interface +// GetIssuedAt implements the Claims interface func (a *accessTokenClaims) GetIssuedAt() time.Time { return time.Time(a.IssuedAt) } -//GetNonce implements the Claims interface +// GetNonce implements the Claims interface func (a *accessTokenClaims) GetNonce() string { return a.Nonce } -//GetAuthenticationContextClassReference implements the Claims interface +// GetAuthenticationContextClassReference implements the Claims interface func (a *accessTokenClaims) GetAuthenticationContextClassReference() string { return a.AuthenticationContextClassReference } -//GetAuthTime implements the Claims interface +// GetAuthTime implements the Claims interface func (a *accessTokenClaims) GetAuthTime() time.Time { return time.Time(a.AuthTime) } -//GetAuthorizedParty implements the Claims interface +// GetAuthorizedParty implements the Claims interface func (a *accessTokenClaims) GetAuthorizedParty() string { return a.AuthorizedParty } -//SetSignatureAlgorithm implements the Claims interface +// SetSignatureAlgorithm implements the Claims interface func (a *accessTokenClaims) SetSignatureAlgorithm(algorithm jose.SignatureAlgorithm) { a.signatureAlg = algorithm } -//GetSubject implements the AccessTokenClaims interface +// GetSubject implements the AccessTokenClaims interface func (a *accessTokenClaims) GetSubject() string { return a.Subject } -//GetTokenID implements the AccessTokenClaims interface +// GetTokenID implements the AccessTokenClaims interface func (a *accessTokenClaims) GetTokenID() string { return a.JWTID } -//SetPrivateClaims implements the AccessTokenClaims interface +// SetPrivateClaims implements the AccessTokenClaims interface func (a *accessTokenClaims) SetPrivateClaims(claims map[string]interface{}) { a.claims = claims } @@ -243,97 +243,97 @@ type idTokenClaims struct { signatureAlg jose.SignatureAlgorithm } -//GetIssuer implements the Claims interface +// GetIssuer implements the Claims interface func (t *idTokenClaims) GetIssuer() string { return t.Issuer } -//GetAudience implements the Claims interface +// GetAudience implements the Claims interface func (t *idTokenClaims) GetAudience() []string { return t.Audience } -//GetExpiration implements the Claims interface +// GetExpiration implements the Claims interface func (t *idTokenClaims) GetExpiration() time.Time { return time.Time(t.Expiration) } -//GetIssuedAt implements the Claims interface +// GetIssuedAt implements the Claims interface func (t *idTokenClaims) GetIssuedAt() time.Time { return time.Time(t.IssuedAt) } -//GetNonce implements the Claims interface +// GetNonce implements the Claims interface func (t *idTokenClaims) GetNonce() string { return t.Nonce } -//GetAuthenticationContextClassReference implements the Claims interface +// GetAuthenticationContextClassReference implements the Claims interface func (t *idTokenClaims) GetAuthenticationContextClassReference() string { return t.AuthenticationContextClassReference } -//GetAuthTime implements the Claims interface +// GetAuthTime implements the Claims interface func (t *idTokenClaims) GetAuthTime() time.Time { return time.Time(t.AuthTime) } -//GetAuthorizedParty implements the Claims interface +// GetAuthorizedParty implements the Claims interface func (t *idTokenClaims) GetAuthorizedParty() string { return t.AuthorizedParty } -//SetSignatureAlgorithm implements the Claims interface +// SetSignatureAlgorithm implements the Claims interface func (t *idTokenClaims) SetSignatureAlgorithm(alg jose.SignatureAlgorithm) { t.signatureAlg = alg } -//GetNotBefore implements the IDTokenClaims interface +// GetNotBefore implements the IDTokenClaims interface func (t *idTokenClaims) GetNotBefore() time.Time { return time.Time(t.NotBefore) } -//GetJWTID implements the IDTokenClaims interface +// GetJWTID implements the IDTokenClaims interface func (t *idTokenClaims) GetJWTID() string { return t.JWTID } -//GetAccessTokenHash implements the IDTokenClaims interface +// GetAccessTokenHash implements the IDTokenClaims interface func (t *idTokenClaims) GetAccessTokenHash() string { return t.AccessTokenHash } -//GetCodeHash implements the IDTokenClaims interface +// GetCodeHash implements the IDTokenClaims interface func (t *idTokenClaims) GetCodeHash() string { return t.CodeHash } -//GetAuthenticationMethodsReferences implements the IDTokenClaims interface +// GetAuthenticationMethodsReferences implements the IDTokenClaims interface func (t *idTokenClaims) GetAuthenticationMethodsReferences() []string { return t.AuthenticationMethodsReferences } -//GetClientID implements the IDTokenClaims interface +// GetClientID implements the IDTokenClaims interface func (t *idTokenClaims) GetClientID() string { return t.ClientID } -//GetSignatureAlgorithm implements the IDTokenClaims interface +// GetSignatureAlgorithm implements the IDTokenClaims interface func (t *idTokenClaims) GetSignatureAlgorithm() jose.SignatureAlgorithm { return t.signatureAlg } -//SetAccessTokenHash implements the IDTokenClaims interface +// SetAccessTokenHash implements the IDTokenClaims interface func (t *idTokenClaims) SetAccessTokenHash(hash string) { t.AccessTokenHash = hash } -//SetUserinfo implements the IDTokenClaims interface +// SetUserinfo implements the IDTokenClaims interface func (t *idTokenClaims) SetUserinfo(info UserInfo) { t.UserInfo = info } -//SetCodeHash implements the IDTokenClaims interface +// SetCodeHash implements the IDTokenClaims interface func (t *idTokenClaims) SetCodeHash(hash string) { t.CodeHash = hash } diff --git a/pkg/oidc/token_request.go b/pkg/oidc/token_request.go index a25da9c..ec11057 100644 --- a/pkg/oidc/token_request.go +++ b/pkg/oidc/token_request.go @@ -9,33 +9,34 @@ import ( ) const ( - //GrantTypeCode defines the grant_type `authorization_code` used for the Token Request in the Authorization Code Flow + // GrantTypeCode defines the grant_type `authorization_code` used for the Token Request in the Authorization Code Flow GrantTypeCode GrantType = "authorization_code" - //GrantTypeRefreshToken defines the grant_type `refresh_token` used for the Token Request in the Refresh Token Flow + // GrantTypeRefreshToken defines the grant_type `refresh_token` used for the Token Request in the Refresh Token Flow GrantTypeRefreshToken GrantType = "refresh_token" - //GrantTypeClientCredentials defines the grant_type `client_credentials` used for the Token Request in the Client Credentials Token Flow + // GrantTypeClientCredentials defines the grant_type `client_credentials` used for the Token Request in the Client Credentials Token Flow GrantTypeClientCredentials GrantType = "client_credentials" - //GrantTypeBearer defines the grant_type `urn:ietf:params:oauth:grant-type:jwt-bearer` used for the JWT Authorization Grant + // GrantTypeBearer defines the grant_type `urn:ietf:params:oauth:grant-type:jwt-bearer` used for the JWT Authorization Grant GrantTypeBearer GrantType = "urn:ietf:params:oauth:grant-type:jwt-bearer" - //GrantTypeTokenExchange defines the grant_type `urn:ietf:params:oauth:grant-type:token-exchange` used for the OAuth Token Exchange Grant + // GrantTypeTokenExchange defines the grant_type `urn:ietf:params:oauth:grant-type:token-exchange` used for the OAuth Token Exchange Grant GrantTypeTokenExchange GrantType = "urn:ietf:params:oauth:grant-type:token-exchange" - //GrantTypeImplicit defines the grant type `implicit` used for implicit flows that skip the generation and exchange of an Authorization Code + // GrantTypeImplicit defines the grant type `implicit` used for implicit flows that skip the generation and exchange of an Authorization Code GrantTypeImplicit GrantType = "implicit" - //ClientAssertionTypeJWTAssertion defines the client_assertion_type `urn:ietf:params:oauth:client-assertion-type:jwt-bearer` - //used for the OAuth JWT Profile Client Authentication + // ClientAssertionTypeJWTAssertion defines the client_assertion_type `urn:ietf:params:oauth:client-assertion-type:jwt-bearer` + // used for the OAuth JWT Profile Client Authentication ClientAssertionTypeJWTAssertion = "urn:ietf:params:oauth:client-assertion-type:jwt-bearer" ) var AllGrantTypes = []GrantType{ GrantTypeCode, GrantTypeRefreshToken, GrantTypeClientCredentials, GrantTypeBearer, GrantTypeTokenExchange, GrantTypeImplicit, - ClientAssertionTypeJWTAssertion} + ClientAssertionTypeJWTAssertion, +} type GrantType string @@ -60,12 +61,12 @@ func (a *AccessTokenRequest) GrantType() GrantType { return GrantTypeCode } -//SetClientID implements op.AuthenticatedTokenRequest +// SetClientID implements op.AuthenticatedTokenRequest func (a *AccessTokenRequest) SetClientID(clientID string) { a.ClientID = clientID } -//SetClientSecret implements op.AuthenticatedTokenRequest +// SetClientSecret implements op.AuthenticatedTokenRequest func (a *AccessTokenRequest) SetClientSecret(clientSecret string) { a.ClientSecret = clientSecret } @@ -85,12 +86,12 @@ func (a *RefreshTokenRequest) GrantType() GrantType { return GrantTypeRefreshToken } -//SetClientID implements op.AuthenticatedTokenRequest +// SetClientID implements op.AuthenticatedTokenRequest func (a *RefreshTokenRequest) SetClientID(clientID string) { a.ClientID = clientID } -//SetClientSecret implements op.AuthenticatedTokenRequest +// SetClientSecret implements op.AuthenticatedTokenRequest func (a *RefreshTokenRequest) SetClientSecret(clientSecret string) { a.ClientSecret = clientSecret } @@ -148,55 +149,55 @@ func (j *JWTTokenRequest) GetCustomClaim(key string) interface{} { return j.private[key] } -//GetIssuer implements the Claims interface +// GetIssuer implements the Claims interface func (j *JWTTokenRequest) GetIssuer() string { return j.Issuer } -//GetAudience implements the Claims and TokenRequest interfaces +// GetAudience implements the Claims and TokenRequest interfaces func (j *JWTTokenRequest) GetAudience() []string { return j.Audience } -//GetExpiration implements the Claims interface +// GetExpiration implements the Claims interface func (j *JWTTokenRequest) GetExpiration() time.Time { return time.Time(j.ExpiresAt) } -//GetIssuedAt implements the Claims interface +// GetIssuedAt implements the Claims interface func (j *JWTTokenRequest) GetIssuedAt() time.Time { return time.Time(j.IssuedAt) } -//GetNonce implements the Claims interface +// GetNonce implements the Claims interface func (j *JWTTokenRequest) GetNonce() string { return "" } -//GetAuthenticationContextClassReference implements the Claims interface +// GetAuthenticationContextClassReference implements the Claims interface func (j *JWTTokenRequest) GetAuthenticationContextClassReference() string { return "" } -//GetAuthTime implements the Claims interface +// GetAuthTime implements the Claims interface func (j *JWTTokenRequest) GetAuthTime() time.Time { return time.Time{} } -//GetAuthorizedParty implements the Claims interface +// GetAuthorizedParty implements the Claims interface func (j *JWTTokenRequest) GetAuthorizedParty() string { return "" } -//SetSignatureAlgorithm implements the Claims interface +// SetSignatureAlgorithm implements the Claims interface func (j *JWTTokenRequest) SetSignatureAlgorithm(_ jose.SignatureAlgorithm) {} -//GetSubject implements the TokenRequest interface +// GetSubject implements the TokenRequest interface func (j *JWTTokenRequest) GetSubject() string { return j.Subject } -//GetScopes implements the TokenRequest interface +// GetScopes implements the TokenRequest interface func (j *JWTTokenRequest) GetScopes() []string { return j.Scopes } diff --git a/pkg/oidc/verifier.go b/pkg/oidc/verifier.go index 474e52e..cc18c80 100644 --- a/pkg/oidc/verifier.go +++ b/pkg/oidc/verifier.go @@ -61,11 +61,11 @@ type Verifier interface { Offset() time.Duration } -//ACRVerifier specifies the function to be used by the `DefaultVerifier` for validating the acr claim +// ACRVerifier specifies the function to be used by the `DefaultVerifier` for validating the acr claim type ACRVerifier func(string) error -//DefaultACRVerifier implements `ACRVerifier` returning an error -//if none of the provided values matches the acr claim +// DefaultACRVerifier implements `ACRVerifier` returning an error +// if none of the provided values matches the acr claim func DefaultACRVerifier(possibleValues []string) ACRVerifier { return func(acr string) error { if !str.Contains(possibleValues, acr) { @@ -76,7 +76,7 @@ func DefaultACRVerifier(possibleValues []string) ACRVerifier { } func DecryptToken(tokenString string) (string, error) { - return tokenString, nil //TODO: impl + return tokenString, nil // TODO: impl } func ParseToken(tokenString string, claims interface{}) ([]byte, error) { @@ -111,7 +111,7 @@ func CheckAudience(claims Claims, clientID string) error { return fmt.Errorf("%w: Audience must contain client_id %q", ErrAudience, clientID) } - //TODO: check aud trusted + // TODO: check aud trusted return nil } @@ -202,6 +202,7 @@ func CheckAuthorizationContextClassReference(claims Claims, acr ACRVerifier) err } return nil } + func CheckAuthTime(claims Claims, maxAge time.Duration) error { if maxAge == 0 { return nil diff --git a/pkg/op/auth_request.go b/pkg/op/auth_request.go index 979fe62..9dc07d2 100644 --- a/pkg/op/auth_request.go +++ b/pkg/op/auth_request.go @@ -45,8 +45,8 @@ type Authorizer interface { RequestObjectSupported() bool } -//AuthorizeValidator is an extension of Authorizer interface -//implementing its own validation mechanism for the auth request +// AuthorizeValidator is an extension of Authorizer interface +// implementing its own validation mechanism for the auth request type AuthorizeValidator interface { Authorizer ValidateAuthRequest(context.Context, *oidc.AuthRequest, Storage, IDTokenHintVerifier) (string, error) @@ -64,8 +64,8 @@ func authorizeCallbackHandler(authorizer Authorizer) func(http.ResponseWriter, * } } -//Authorize handles the authorization request, including -//parsing, validating, storing and finally redirecting to the login handler +// Authorize handles the authorization request, including +// parsing, validating, storing and finally redirecting to the login handler func Authorize(w http.ResponseWriter, r *http.Request, authorizer Authorizer) { authReq, err := ParseAuthorizeRequest(r, authorizer.Decoder()) if err != nil { @@ -113,7 +113,7 @@ func Authorize(w http.ResponseWriter, r *http.Request, authorizer Authorizer) { RedirectToLogin(req.GetID(), client, w, r) } -//ParseAuthorizeRequest parsed the http request into an oidc.AuthRequest +// ParseAuthorizeRequest parsed the http request into an oidc.AuthRequest func ParseAuthorizeRequest(r *http.Request, decoder httphelper.Decoder) (*oidc.AuthRequest, error) { err := r.ParseForm() if err != nil { @@ -127,8 +127,8 @@ func ParseAuthorizeRequest(r *http.Request, decoder httphelper.Decoder) (*oidc.A return authReq, nil } -//ParseRequestObject parse the `request` parameter, validates the token including the signature -//and copies the token claims into the auth request +// ParseRequestObject parse the `request` parameter, validates the token including the signature +// and copies the token claims into the auth request func ParseRequestObject(ctx context.Context, authReq *oidc.AuthRequest, storage Storage, issuer string) (*oidc.AuthRequest, error) { requestObject := new(oidc.RequestObject) payload, err := oidc.ParseToken(authReq.RequestParam, requestObject) @@ -156,8 +156,8 @@ func ParseRequestObject(ctx context.Context, authReq *oidc.AuthRequest, storage return authReq, nil } -//CopyRequestObjectToAuthRequest overwrites present values from the Request Object into the auth request -//and clears the `RequestParam` of the auth request +// CopyRequestObjectToAuthRequest overwrites present values from the Request Object into the auth request +// and clears the `RequestParam` of the auth request func CopyRequestObjectToAuthRequest(authReq *oidc.AuthRequest, requestObject *oidc.RequestObject) { if str.Contains(authReq.Scopes, oidc.ScopeOpenID) && len(requestObject.Scopes) > 0 { authReq.Scopes = requestObject.Scopes @@ -204,7 +204,7 @@ func CopyRequestObjectToAuthRequest(authReq *oidc.AuthRequest, requestObject *oi authReq.RequestParam = "" } -//ValidateAuthRequest validates the authorize parameters and returns the userID of the id_token_hint if passed +// ValidateAuthRequest validates the authorize parameters and returns the userID of the id_token_hint if passed func ValidateAuthRequest(ctx context.Context, authReq *oidc.AuthRequest, storage Storage, verifier IDTokenHintVerifier) (sub string, err error) { authReq.MaxAge, err = ValidateAuthReqPrompt(authReq.Prompt, authReq.MaxAge) if err != nil { @@ -227,7 +227,7 @@ func ValidateAuthRequest(ctx context.Context, authReq *oidc.AuthRequest, storage return ValidateAuthReqIDTokenHint(ctx, authReq.IDTokenHint, verifier) } -//ValidateAuthReqPrompt validates the passed prompt values and sets max_age to 0 if prompt login is present +// ValidateAuthReqPrompt validates the passed prompt values and sets max_age to 0 if prompt login is present func ValidateAuthReqPrompt(prompts []string, maxAge *uint) (_ *uint, err error) { for _, prompt := range prompts { if prompt == oidc.PromptNone && len(prompts) > 1 { @@ -240,7 +240,7 @@ func ValidateAuthReqPrompt(prompts []string, maxAge *uint) (_ *uint, err error) return maxAge, nil } -//ValidateAuthReqScopes validates the passed scopes +// ValidateAuthReqScopes validates the passed scopes func ValidateAuthReqScopes(client Client, scopes []string) ([]string, error) { if len(scopes) == 0 { return nil, oidc.ErrInvalidRequest(). @@ -274,7 +274,7 @@ func ValidateAuthReqScopes(client Client, scopes []string) ([]string, error) { return scopes, nil } -//ValidateAuthReqRedirectURI validates the passed redirect_uri and response_type to the registered uris and client type +// ValidateAuthReqRedirectURI validates the passed redirect_uri and response_type to the registered uris and client type func ValidateAuthReqRedirectURI(client Client, uri string, responseType oidc.ResponseType) error { if uri == "" { return oidc.ErrInvalidRequestRedirectURI().WithDescription("The redirect_uri is missing in the request. " + @@ -309,7 +309,7 @@ func ValidateAuthReqRedirectURI(client Client, uri string, responseType oidc.Res "If you have any questions, you may contact the administrator of the application.") } -//ValidateAuthReqRedirectURINative validates the passed redirect_uri and response_type to the registered uris and client type +// ValidateAuthReqRedirectURINative validates the passed redirect_uri and response_type to the registered uris and client type func validateAuthReqRedirectURINative(client Client, uri string, responseType oidc.ResponseType) error { parsedURL, isLoopback := HTTPLoopbackOrLocalhost(uri) isCustomSchema := !strings.HasPrefix(uri, "http://") @@ -350,7 +350,7 @@ func HTTPLoopbackOrLocalhost(rawurl string) (*url.URL, bool) { return parsedURL, hostName == "localhost" || net.ParseIP(hostName).IsLoopback() } -//ValidateAuthReqResponseType validates the passed response_type to the registered response types +// ValidateAuthReqResponseType validates the passed response_type to the registered response types func ValidateAuthReqResponseType(client Client, responseType oidc.ResponseType) error { if responseType == "" { return oidc.ErrInvalidRequest().WithDescription("The response type is missing in your request. " + @@ -363,8 +363,8 @@ func ValidateAuthReqResponseType(client Client, responseType oidc.ResponseType) return nil } -//ValidateAuthReqIDTokenHint validates the id_token_hint (if passed as parameter in the request) -//and returns the `sub` claim +// ValidateAuthReqIDTokenHint validates the id_token_hint (if passed as parameter in the request) +// and returns the `sub` claim func ValidateAuthReqIDTokenHint(ctx context.Context, idTokenHint string, verifier IDTokenHintVerifier) (string, error) { if idTokenHint == "" { return "", nil @@ -377,13 +377,13 @@ func ValidateAuthReqIDTokenHint(ctx context.Context, idTokenHint string, verifie return claims.GetSubject(), nil } -//RedirectToLogin redirects the end user to the Login UI for authentication +// RedirectToLogin redirects the end user to the Login UI for authentication func RedirectToLogin(authReqID string, client Client, w http.ResponseWriter, r *http.Request) { login := client.LoginURL(authReqID) http.Redirect(w, r, login, http.StatusFound) } -//AuthorizeCallback handles the callback after authentication in the Login UI +// AuthorizeCallback handles the callback after authentication in the Login UI func AuthorizeCallback(w http.ResponseWriter, r *http.Request, authorizer Authorizer) { params := mux.Vars(r) id := params["id"] @@ -406,7 +406,7 @@ func AuthorizeCallback(w http.ResponseWriter, r *http.Request, authorizer Author AuthResponse(authReq, authorizer, w, r) } -//AuthResponse creates the successful authentication response (either code or tokens) +// AuthResponse creates the successful authentication response (either code or tokens) func AuthResponse(authReq AuthRequest, authorizer Authorizer, w http.ResponseWriter, r *http.Request) { client, err := authorizer.Storage().GetClientByClientID(r.Context(), authReq.GetClientID()) if err != nil { @@ -420,7 +420,7 @@ func AuthResponse(authReq AuthRequest, authorizer Authorizer, w http.ResponseWri AuthResponseToken(w, r, authReq, authorizer, client) } -//AuthResponseCode creates the successful code authentication response +// AuthResponseCode creates the successful code authentication response func AuthResponseCode(w http.ResponseWriter, r *http.Request, authReq AuthRequest, authorizer Authorizer) { code, err := CreateAuthRequestCode(r.Context(), authReq, authorizer.Storage(), authorizer.Crypto()) if err != nil { @@ -442,7 +442,7 @@ func AuthResponseCode(w http.ResponseWriter, r *http.Request, authReq AuthReques http.Redirect(w, r, callback, http.StatusFound) } -//AuthResponseToken creates the successful token(s) authentication response +// AuthResponseToken creates the successful token(s) authentication response func AuthResponseToken(w http.ResponseWriter, r *http.Request, authReq AuthRequest, authorizer Authorizer, client Client) { createAccessToken := authReq.GetResponseType() != oidc.ResponseTypeIDTokenOnly resp, err := CreateTokenResponse(r.Context(), authReq, client, authorizer, createAccessToken, "", "") @@ -458,7 +458,7 @@ func AuthResponseToken(w http.ResponseWriter, r *http.Request, authReq AuthReque http.Redirect(w, r, callback, http.StatusFound) } -//CreateAuthRequestCode creates and stores a code for the auth code response +// CreateAuthRequestCode creates and stores a code for the auth code response func CreateAuthRequestCode(ctx context.Context, authReq AuthRequest, storage Storage, crypto Crypto) (string, error) { code, err := BuildAuthRequestCode(authReq, crypto) if err != nil { @@ -470,13 +470,13 @@ func CreateAuthRequestCode(ctx context.Context, authReq AuthRequest, storage Sto return code, nil } -//BuildAuthRequestCode builds the string representation of the auth code +// BuildAuthRequestCode builds the string representation of the auth code func BuildAuthRequestCode(authReq AuthRequest, crypto Crypto) (string, error) { return crypto.Encrypt(authReq.GetID()) } -//AuthResponseURL encodes the authorization response (successful and error) and sets it as query or fragment values -//depending on the response_mode and response_type +// AuthResponseURL encodes the authorization response (successful and error) and sets it as query or fragment values +// depending on the response_mode and response_type func AuthResponseURL(redirectURI string, responseType oidc.ResponseType, responseMode oidc.ResponseMode, response interface{}, encoder httphelper.Encoder) (string, error) { uri, err := url.Parse(redirectURI) if err != nil { @@ -486,18 +486,18 @@ func AuthResponseURL(redirectURI string, responseType oidc.ResponseType, respons if err != nil { return "", oidc.ErrServerError().WithParent(err) } - //return explicitly requested mode + // return explicitly requested mode if responseMode == oidc.ResponseModeQuery { return mergeQueryParams(uri, params), nil } if responseMode == oidc.ResponseModeFragment { return setFragment(uri, params), nil } - //implicit must use fragment mode is not specified by client + // implicit must use fragment mode is not specified by client if responseType == oidc.ResponseTypeIDToken || responseType == oidc.ResponseTypeIDTokenOnly { return setFragment(uri, params), nil } - //if we get here it's code flow: defaults to query + // if we get here it's code flow: defaults to query return mergeQueryParams(uri, params), nil } diff --git a/pkg/op/auth_request_test.go b/pkg/op/auth_request_test.go index 9023011..dc6f655 100644 --- a/pkg/op/auth_request_test.go +++ b/pkg/op/auth_request_test.go @@ -20,8 +20,8 @@ import ( ) // -//TOOD: tests will be implemented in branch for service accounts -//func TestAuthorize(t *testing.T) { +// TOOD: tests will be implemented in branch for service accounts +// func TestAuthorize(t *testing.T) { // // testCallback := func(t *testing.T, clienID string) callbackHandler { // // return func(authReq *oidc.AuthRequest, client oidc.Client, w http.ResponseWriter, r *http.Request) { // // // require.Equal(t, clientID, client.) @@ -364,191 +364,245 @@ func TestValidateAuthReqRedirectURI(t *testing.T) { }{ { "empty fails", - args{"", + args{ + "", mock.NewClientWithConfig(t, []string{"https://registered.com/callback"}, op.ApplicationTypeWeb, nil, false), - oidc.ResponseTypeCode}, + oidc.ResponseTypeCode, + }, true, }, { "unregistered https fails", - args{"https://unregistered.com/callback", + args{ + "https://unregistered.com/callback", mock.NewClientWithConfig(t, []string{"https://registered.com/callback"}, op.ApplicationTypeWeb, nil, false), - oidc.ResponseTypeCode}, + oidc.ResponseTypeCode, + }, true, }, { "unregistered http fails", - args{"http://unregistered.com/callback", + args{ + "http://unregistered.com/callback", mock.NewClientWithConfig(t, []string{"http://registered.com/callback"}, op.ApplicationTypeWeb, nil, false), - oidc.ResponseTypeCode}, + oidc.ResponseTypeCode, + }, true, }, { "code flow registered https web ok", - args{"https://registered.com/callback", + args{ + "https://registered.com/callback", mock.NewClientWithConfig(t, []string{"https://registered.com/callback"}, op.ApplicationTypeWeb, nil, false), - oidc.ResponseTypeCode}, + oidc.ResponseTypeCode, + }, false, }, { "code flow registered https native ok", - args{"https://registered.com/callback", + args{ + "https://registered.com/callback", mock.NewClientWithConfig(t, []string{"https://registered.com/callback"}, op.ApplicationTypeNative, nil, false), - oidc.ResponseTypeCode}, + oidc.ResponseTypeCode, + }, false, }, { "code flow registered https user agent ok", - args{"https://registered.com/callback", + args{ + "https://registered.com/callback", mock.NewClientWithConfig(t, []string{"https://registered.com/callback"}, op.ApplicationTypeUserAgent, nil, false), - oidc.ResponseTypeCode}, + oidc.ResponseTypeCode, + }, false, }, { "code flow registered http confidential (web) ok", - args{"http://registered.com/callback", + args{ + "http://registered.com/callback", mock.NewClientWithConfig(t, []string{"http://registered.com/callback"}, op.ApplicationTypeWeb, nil, false), - oidc.ResponseTypeCode}, + oidc.ResponseTypeCode, + }, false, }, { "code flow registered http not confidential (native) fails", - args{"http://registered.com/callback", + args{ + "http://registered.com/callback", mock.NewClientWithConfig(t, []string{"http://registered.com/callback"}, op.ApplicationTypeNative, nil, false), - oidc.ResponseTypeCode}, + oidc.ResponseTypeCode, + }, true, }, { "code flow registered http not confidential (user agent) fails", - args{"http://registered.com/callback", + args{ + "http://registered.com/callback", mock.NewClientWithConfig(t, []string{"http://registered.com/callback"}, op.ApplicationTypeUserAgent, nil, false), - oidc.ResponseTypeCode}, + oidc.ResponseTypeCode, + }, true, }, { "code flow registered http localhost native ok", - args{"http://localhost:4200/callback", + args{ + "http://localhost:4200/callback", mock.NewClientWithConfig(t, []string{"http://localhost/callback"}, op.ApplicationTypeNative, nil, false), - oidc.ResponseTypeCode}, + oidc.ResponseTypeCode, + }, false, }, { "code flow registered http loopback v4 native ok", - args{"http://127.0.0.1:4200/callback", + args{ + "http://127.0.0.1:4200/callback", mock.NewClientWithConfig(t, []string{"http://127.0.0.1/callback"}, op.ApplicationTypeNative, nil, false), - oidc.ResponseTypeCode}, + oidc.ResponseTypeCode, + }, false, }, { "code flow registered http loopback v6 native ok", - args{"http://[::1]:4200/callback", + args{ + "http://[::1]:4200/callback", mock.NewClientWithConfig(t, []string{"http://[::1]/callback"}, op.ApplicationTypeNative, nil, false), - oidc.ResponseTypeCode}, + oidc.ResponseTypeCode, + }, false, }, { "code flow unregistered http native fails", - args{"http://unregistered.com/callback", + args{ + "http://unregistered.com/callback", mock.NewClientWithConfig(t, []string{"http://locahost/callback"}, op.ApplicationTypeNative, nil, false), - oidc.ResponseTypeCode}, + oidc.ResponseTypeCode, + }, true, }, { "code flow unregistered custom native fails", - args{"unregistered://callback", + args{ + "unregistered://callback", mock.NewClientWithConfig(t, []string{"registered://callback"}, op.ApplicationTypeNative, nil, false), - oidc.ResponseTypeCode}, + oidc.ResponseTypeCode, + }, true, }, { "code flow unregistered loopback native fails", - args{"http://[::1]:4200/unregistered", + args{ + "http://[::1]:4200/unregistered", mock.NewClientWithConfig(t, []string{"http://[::1]:4200/callback"}, op.ApplicationTypeNative, nil, false), - oidc.ResponseTypeCode}, + oidc.ResponseTypeCode, + }, true, }, { "code flow registered custom not native (web) fails", - args{"custom://callback", + args{ + "custom://callback", mock.NewClientWithConfig(t, []string{"custom://callback"}, op.ApplicationTypeWeb, nil, false), - oidc.ResponseTypeCode}, + oidc.ResponseTypeCode, + }, true, }, { "code flow registered custom not native (user agent) fails", - args{"custom://callback", + args{ + "custom://callback", mock.NewClientWithConfig(t, []string{"custom://callback"}, op.ApplicationTypeUserAgent, nil, false), - oidc.ResponseTypeCode}, + oidc.ResponseTypeCode, + }, true, }, { "code flow registered custom native ok", - args{"custom://callback", + args{ + "custom://callback", mock.NewClientWithConfig(t, []string{"custom://callback"}, op.ApplicationTypeNative, nil, false), - oidc.ResponseTypeCode}, + oidc.ResponseTypeCode, + }, false, }, { "code flow dev mode http ok", - args{"http://registered.com/callback", + args{ + "http://registered.com/callback", mock.NewClientWithConfig(t, []string{"http://registered.com/callback"}, op.ApplicationTypeUserAgent, nil, true), - oidc.ResponseTypeCode}, + oidc.ResponseTypeCode, + }, false, }, { "implicit flow registered ok", - args{"https://registered.com/callback", + args{ + "https://registered.com/callback", mock.NewClientWithConfig(t, []string{"https://registered.com/callback"}, op.ApplicationTypeUserAgent, nil, false), - oidc.ResponseTypeIDToken}, + oidc.ResponseTypeIDToken, + }, false, }, { "implicit flow unregistered fails", - args{"https://unregistered.com/callback", + args{ + "https://unregistered.com/callback", mock.NewClientWithConfig(t, []string{"https://registered.com/callback"}, op.ApplicationTypeUserAgent, nil, false), - oidc.ResponseTypeIDToken}, + oidc.ResponseTypeIDToken, + }, true, }, { "implicit flow registered http localhost native ok", - args{"http://localhost:9999/callback", + args{ + "http://localhost:9999/callback", mock.NewClientWithConfig(t, []string{"http://localhost:9999/callback"}, op.ApplicationTypeNative, nil, false), - oidc.ResponseTypeIDToken}, + oidc.ResponseTypeIDToken, + }, false, }, { "implicit flow registered http localhost web fails", - args{"http://localhost:9999/callback", + args{ + "http://localhost:9999/callback", mock.NewClientWithConfig(t, []string{"http://localhost:9999/callback"}, op.ApplicationTypeWeb, nil, false), - oidc.ResponseTypeIDToken}, + oidc.ResponseTypeIDToken, + }, true, }, { "implicit flow registered http localhost user agent fails", - args{"http://localhost:9999/callback", + args{ + "http://localhost:9999/callback", mock.NewClientWithConfig(t, []string{"http://localhost:9999/callback"}, op.ApplicationTypeUserAgent, nil, false), - oidc.ResponseTypeIDToken}, + oidc.ResponseTypeIDToken, + }, true, }, { "implicit flow http non localhost fails", - args{"http://registered.com/callback", + args{ + "http://registered.com/callback", mock.NewClientWithConfig(t, []string{"http://registered.com/callback"}, op.ApplicationTypeNative, nil, false), - oidc.ResponseTypeIDToken}, + oidc.ResponseTypeIDToken, + }, true, }, { "implicit flow custom fails", - args{"custom://callback", + args{ + "custom://callback", mock.NewClientWithConfig(t, []string{"custom://callback"}, op.ApplicationTypeNative, nil, false), - oidc.ResponseTypeIDToken}, + oidc.ResponseTypeIDToken, + }, false, }, { "implicit flow dev mode http ok", - args{"http://registered.com/callback", + args{ + "http://registered.com/callback", mock.NewClientWithConfig(t, []string{"http://registered.com/callback"}, op.ApplicationTypeUserAgent, nil, true), - oidc.ResponseTypeIDToken}, + oidc.ResponseTypeIDToken, + }, false, }, } @@ -647,20 +701,26 @@ func TestValidateAuthReqResponseType(t *testing.T) { }{ { "empty response type", - args{"", - mock.NewClientWithConfig(t, nil, op.ApplicationTypeNative, []oidc.ResponseType{oidc.ResponseTypeCode}, true)}, + args{ + "", + mock.NewClientWithConfig(t, nil, op.ApplicationTypeNative, []oidc.ResponseType{oidc.ResponseTypeCode}, true), + }, true, }, { "response type missing in client config", - args{oidc.ResponseTypeIDToken, - mock.NewClientWithConfig(t, nil, op.ApplicationTypeNative, []oidc.ResponseType{oidc.ResponseTypeCode}, true)}, + args{ + oidc.ResponseTypeIDToken, + mock.NewClientWithConfig(t, nil, op.ApplicationTypeNative, []oidc.ResponseType{oidc.ResponseTypeCode}, true), + }, true, }, { "valid response type", - args{oidc.ResponseTypeCode, - mock.NewClientWithConfig(t, nil, op.ApplicationTypeNative, []oidc.ResponseType{oidc.ResponseTypeCode}, true)}, + args{ + oidc.ResponseTypeCode, + mock.NewClientWithConfig(t, nil, op.ApplicationTypeNative, []oidc.ResponseType{oidc.ResponseTypeCode}, true), + }, false, }, } diff --git a/pkg/op/config_test.go b/pkg/op/config_test.go index 5029df8..9ff75f1 100644 --- a/pkg/op/config_test.go +++ b/pkg/op/config_test.go @@ -60,7 +60,7 @@ func TestValidateIssuer(t *testing.T) { true, }, } - //ensure env is not set + // ensure env is not set //nolint:errcheck os.Unsetenv(OidcDevMode) for _, tt := range tests { diff --git a/pkg/op/discovery.go b/pkg/op/discovery.go index c06f9a2..100bfc8 100644 --- a/pkg/op/discovery.go +++ b/pkg/op/discovery.go @@ -56,7 +56,7 @@ var DefaultSupportedScopes = []string{ } func Scopes(c Configuration) []string { - return DefaultSupportedScopes //TODO: config + return DefaultSupportedScopes // TODO: config } func ResponseTypes(c Configuration) []string { @@ -64,7 +64,7 @@ func ResponseTypes(c Configuration) []string { string(oidc.ResponseTypeCode), string(oidc.ResponseTypeIDTokenOnly), string(oidc.ResponseTypeIDToken), - } //TODO: ok for now, check later if dynamic needed + } // TODO: ok for now, check later if dynamic needed } func GrantTypes(c Configuration) []oidc.GrantType { @@ -88,7 +88,7 @@ func GrantTypes(c Configuration) []oidc.GrantType { } func SupportedClaims(c Configuration) []string { - return []string{ //TODO: config + return []string{ // TODO: config "sub", "aud", "exp", @@ -121,7 +121,7 @@ func SigAlgorithms(s Signer) []string { } func SubjectTypes(c Configuration) []string { - return []string{"public"} //TODO: config + return []string{"public"} // TODO: config } func AuthMethodsTokenEndpoint(c Configuration) []oidc.AuthMethod { diff --git a/pkg/op/endpoint.go b/pkg/op/endpoint.go index 21907f4..b1e1507 100644 --- a/pkg/op/endpoint.go +++ b/pkg/op/endpoint.go @@ -27,7 +27,7 @@ func (e Endpoint) Absolute(host string) string { } func (e Endpoint) Validate() error { - return nil //TODO: + return nil // TODO: } func absoluteEndpoint(host, endpoint string) string { diff --git a/pkg/op/endpoint_test.go b/pkg/op/endpoint_test.go index 96472b2..7c8d1ce 100644 --- a/pkg/op/endpoint_test.go +++ b/pkg/op/endpoint_test.go @@ -87,7 +87,7 @@ func TestEndpoint_Absolute(t *testing.T) { } } -//TODO: impl test +// TODO: impl test func TestEndpoint_Validate(t *testing.T) { tests := []struct { name string diff --git a/pkg/op/mock/authorizer.mock.impl.go b/pkg/op/mock/authorizer.mock.impl.go index 6df6115..d4f29d5 100644 --- a/pkg/op/mock/authorizer.mock.impl.go +++ b/pkg/op/mock/authorizer.mock.impl.go @@ -68,6 +68,7 @@ type Verifier struct{} func (v *Verifier) Verify(ctx context.Context, accessToken, idToken string) (*oidc.IDTokenClaims, error) { return nil, nil } + func (v *Verifier) VerifyIDToken(ctx context.Context, idToken string) (*oidc.IDTokenClaims, error) { return nil, nil } diff --git a/pkg/op/mock/client.go b/pkg/op/mock/client.go index 7d559ae..3b16e5e 100644 --- a/pkg/op/mock/client.go +++ b/pkg/op/mock/client.go @@ -20,7 +20,8 @@ func NewClientExpectAny(t *testing.T, appType op.ApplicationType) op.Client { "https://registered.com/callback", "http://registered.com/callback", "http://localhost:9999/callback", - "custom://callback"}) + "custom://callback", + }) m.EXPECT().ApplicationType().AnyTimes().Return(appType) m.EXPECT().LoginURL(gomock.Any()).AnyTimes().DoAndReturn( func(id string) string { diff --git a/pkg/op/mock/storage.mock.impl.go b/pkg/op/mock/storage.mock.impl.go index 5b74a50..946cee0 100644 --- a/pkg/op/mock/storage.mock.impl.go +++ b/pkg/op/mock/storage.mock.impl.go @@ -44,6 +44,7 @@ func NewMockStorageSigningKeyInvalid(t *testing.T) op.Storage { ExpectSigningKeyInvalid(m) return m } + func NewMockStorageSigningKey(t *testing.T) op.Storage { m := NewStorage(t) ExpectSigningKey(m) @@ -120,6 +121,7 @@ func (c *ConfClient) RedirectURIs() []string { "custom://callback", } } + func (c *ConfClient) PostLogoutRedirectURIs() []string { return []string{} } @@ -143,34 +145,43 @@ func (c *ConfClient) GetID() string { func (c *ConfClient) AccessTokenLifetime() time.Duration { return 5 * time.Minute } + func (c *ConfClient) IDTokenLifetime() time.Duration { return 5 * time.Minute } + func (c *ConfClient) AccessTokenType() op.AccessTokenType { return c.accessTokenType } + func (c *ConfClient) ResponseTypes() []oidc.ResponseType { return c.responseTypes } + func (c *ConfClient) GrantTypes() []oidc.GrantType { return c.grantTypes } + func (c *ConfClient) DevMode() bool { return c.devMode } + func (c *ConfClient) AllowedScopes() []string { return nil } + func (c *ConfClient) RestrictAdditionalIdTokenScopes() func(scopes []string) []string { return func(scopes []string) []string { return scopes } } + func (c *ConfClient) RestrictAdditionalAccessTokenScopes() func(scopes []string) []string { return func(scopes []string) []string { return scopes } } + func (c *ConfClient) IsScopeAllowed(scope string) bool { return false } diff --git a/pkg/op/op.go b/pkg/op/op.go index 659464f..db35a87 100644 --- a/pkg/op/op.go +++ b/pkg/op/op.go @@ -29,17 +29,15 @@ const ( defaultKeysEndpoint = "keys" ) -var ( - DefaultEndpoints = &endpoints{ - Authorization: NewEndpoint(defaultAuthorizationEndpoint), - Token: NewEndpoint(defaultTokenEndpoint), - Introspection: NewEndpoint(defaultIntrospectEndpoint), - Userinfo: NewEndpoint(defaultUserinfoEndpoint), - Revocation: NewEndpoint(defaultRevocationEndpoint), - EndSession: NewEndpoint(defaultEndSessionEndpoint), - JwksURI: NewEndpoint(defaultKeysEndpoint), - } -) +var DefaultEndpoints = &endpoints{ + Authorization: NewEndpoint(defaultAuthorizationEndpoint), + Token: NewEndpoint(defaultTokenEndpoint), + Introspection: NewEndpoint(defaultIntrospectEndpoint), + Userinfo: NewEndpoint(defaultUserinfoEndpoint), + Revocation: NewEndpoint(defaultRevocationEndpoint), + EndSession: NewEndpoint(defaultEndSessionEndpoint), + JwksURI: NewEndpoint(defaultKeysEndpoint), +} type OpenIDProvider interface { Configuration @@ -83,7 +81,7 @@ func CreateRouter(o OpenIDProvider, interceptors ...HttpInterceptor) *mux.Router return router } -//AuthCallbackURL builds the url for the redirect (with the requestID) after a successful login +// AuthCallbackURL builds the url for the redirect (with the requestID) after a successful login func AuthCallbackURL(o OpenIDProvider) func(string) string { return func(requestID string) string { return o.AuthorizationEndpoint().Absolute(o.Issuer()) + authCallbackPathSuffix + "?id=" + requestID @@ -117,8 +115,8 @@ type endpoints struct { JwksURI Endpoint } -//NewOpenIDProvider creates a provider. The provider provides (with HttpHandler()) -//a http.Router that handles a suite of endpoints (some paths can be overridden): +// NewOpenIDProvider creates a provider. The provider provides (with HttpHandler()) +// a http.Router that handles a suite of endpoints (some paths can be overridden): // /healthz // /ready // /.well-known/openid-configuration @@ -130,10 +128,10 @@ type endpoints struct { // /revoke // /end_session // /keys -//This does not include login. Login is handled with a redirect that includes the -//request ID. The redirect for logins is specified per-client by Client.LoginURL(). -//Successful logins should mark the request as authorized and redirect back to to -//op.AuthCallbackURL(provider) which is probably /callback. On the redirect back +// This does not include login. Login is handled with a redirect that includes the +// request ID. The redirect for logins is specified per-client by Client.LoginURL(). +// Successful logins should mark the request as authorized and redirect back to to +// op.AuthCallbackURL(provider) which is probably /callback. On the redirect back // to the AuthCallbackURL, the request id should be passed as the "id" parameter. func NewOpenIDProvider(ctx context.Context, config *Config, storage Storage, opOpts ...Option) (OpenIDProvider, error) { err := ValidateIssuer(config.Issuer) @@ -354,8 +352,8 @@ type openIDKeySet struct { Storage } -//VerifySignature implements the oidc.KeySet interface -//providing an implementation for the keys stored in the OP Storage interface +// VerifySignature implements the oidc.KeySet interface +// providing an implementation for the keys stored in the OP Storage interface func (o *openIDKeySet) VerifySignature(ctx context.Context, jws *jose.JSONWebSignature) ([]byte, error) { keySet, err := o.Storage.GetKeySet(ctx) if err != nil { diff --git a/pkg/op/probes.go b/pkg/op/probes.go index f328951..7b80fb4 100644 --- a/pkg/op/probes.go +++ b/pkg/op/probes.go @@ -39,6 +39,7 @@ func ReadySigner(s Signer) ProbesFn { return s.Health(ctx) } } + func ReadyStorage(s Storage) ProbesFn { return func(ctx context.Context) error { if s == nil { diff --git a/pkg/op/token_client_credentials.go b/pkg/op/token_client_credentials.go index 2248654..3787667 100644 --- a/pkg/op/token_client_credentials.go +++ b/pkg/op/token_client_credentials.go @@ -9,8 +9,8 @@ import ( "github.com/zitadel/oidc/pkg/oidc" ) -//ClientCredentialsExchange handles the OAuth 2.0 client_credentials grant, including -//parsing, validating, authorizing the client and finally returning a token +// ClientCredentialsExchange handles the OAuth 2.0 client_credentials grant, including +// parsing, validating, authorizing the client and finally returning a token func ClientCredentialsExchange(w http.ResponseWriter, r *http.Request, exchanger Exchanger) { request, err := ParseClientCredentialsRequest(r, exchanger.Decoder()) if err != nil { @@ -32,7 +32,7 @@ func ClientCredentialsExchange(w http.ResponseWriter, r *http.Request, exchanger httphelper.MarshalJSON(w, resp) } -//ParseClientCredentialsRequest parsed the http request into a oidc.ClientCredentialsRequest +// ParseClientCredentialsRequest parsed the http request into a oidc.ClientCredentialsRequest func ParseClientCredentialsRequest(r *http.Request, decoder httphelper.Decoder) (*oidc.ClientCredentialsRequest, error) { err := r.ParseForm() if err != nil { @@ -63,8 +63,8 @@ func ParseClientCredentialsRequest(r *http.Request, decoder httphelper.Decoder) return request, nil } -//ValidateClientCredentialsRequest validates the refresh_token request parameters including authorization check of the client -//and returns the data representing the original auth request corresponding to the refresh_token +// ValidateClientCredentialsRequest validates the refresh_token request parameters including authorization check of the client +// and returns the data representing the original auth request corresponding to the refresh_token func ValidateClientCredentialsRequest(ctx context.Context, request *oidc.ClientCredentialsRequest, exchanger Exchanger) (TokenRequest, Client, error) { storage, ok := exchanger.Storage().(ClientCredentialsStorage) if !ok { diff --git a/pkg/op/token_code.go b/pkg/op/token_code.go index 185fad8..ec48233 100644 --- a/pkg/op/token_code.go +++ b/pkg/op/token_code.go @@ -8,8 +8,8 @@ import ( "github.com/zitadel/oidc/pkg/oidc" ) -//CodeExchange handles the OAuth 2.0 authorization_code grant, including -//parsing, validating, authorizing the client and finally exchanging the code for tokens +// CodeExchange handles the OAuth 2.0 authorization_code grant, including +// parsing, validating, authorizing the client and finally exchanging the code for tokens func CodeExchange(w http.ResponseWriter, r *http.Request, exchanger Exchanger) { tokenReq, err := ParseAccessTokenRequest(r, exchanger.Decoder()) if err != nil { @@ -32,7 +32,7 @@ func CodeExchange(w http.ResponseWriter, r *http.Request, exchanger Exchanger) { httphelper.MarshalJSON(w, resp) } -//ParseAccessTokenRequest parsed the http request into a oidc.AccessTokenRequest +// ParseAccessTokenRequest parsed the http request into a oidc.AccessTokenRequest func ParseAccessTokenRequest(r *http.Request, decoder httphelper.Decoder) (*oidc.AccessTokenRequest, error) { request := new(oidc.AccessTokenRequest) err := ParseAuthenticatedTokenRequest(r, decoder, request) @@ -42,8 +42,8 @@ func ParseAccessTokenRequest(r *http.Request, decoder httphelper.Decoder) (*oidc return request, nil } -//ValidateAccessTokenRequest validates the token request parameters including authorization check of the client -//and returns the previous created auth request corresponding to the auth code +// ValidateAccessTokenRequest validates the token request parameters including authorization check of the client +// and returns the previous created auth request corresponding to the auth code func ValidateAccessTokenRequest(ctx context.Context, tokenReq *oidc.AccessTokenRequest, exchanger Exchanger) (AuthRequest, Client, error) { authReq, client, err := AuthorizeCodeClient(ctx, tokenReq, exchanger) if err != nil { @@ -61,8 +61,8 @@ func ValidateAccessTokenRequest(ctx context.Context, tokenReq *oidc.AccessTokenR return authReq, client, nil } -//AuthorizeCodeClient checks the authorization of the client and that the used method was the one previously registered. -//It than returns the auth request corresponding to the auth code +// AuthorizeCodeClient checks the authorization of the client and that the used method was the one previously registered. +// It than returns the auth request corresponding to the auth code func AuthorizeCodeClient(ctx context.Context, tokenReq *oidc.AccessTokenRequest, exchanger Exchanger) (request AuthRequest, client Client, err error) { if tokenReq.ClientAssertionType == oidc.ClientAssertionTypeJWTAssertion { jwtExchanger, ok := exchanger.(JWTAuthorizationGrantExchanger) @@ -102,7 +102,7 @@ func AuthorizeCodeClient(ctx context.Context, tokenReq *oidc.AccessTokenRequest, return request, client, err } -//AuthRequestByCode returns the AuthRequest previously created from Storage corresponding to the auth code or an error +// AuthRequestByCode returns the AuthRequest previously created from Storage corresponding to the auth code or an error func AuthRequestByCode(ctx context.Context, storage Storage, code string) (AuthRequest, error) { authReq, err := storage.AuthRequestByCode(ctx, code) if err != nil { diff --git a/pkg/op/token_exchange.go b/pkg/op/token_exchange.go index 501f6e5..7bb6e42 100644 --- a/pkg/op/token_exchange.go +++ b/pkg/op/token_exchange.go @@ -5,7 +5,7 @@ import ( "net/http" ) -//TokenExchange will handle the OAuth 2.0 token exchange grant ("urn:ietf:params:oauth:grant-type:token-exchange") +// TokenExchange will handle the OAuth 2.0 token exchange grant ("urn:ietf:params:oauth:grant-type:token-exchange") func TokenExchange(w http.ResponseWriter, r *http.Request, exchanger Exchanger) { RequestError(w, r, errors.New("unimplemented")) } diff --git a/pkg/op/token_jwt_profile.go b/pkg/op/token_jwt_profile.go index 0fccfe7..eb21517 100644 --- a/pkg/op/token_jwt_profile.go +++ b/pkg/op/token_jwt_profile.go @@ -14,7 +14,7 @@ type JWTAuthorizationGrantExchanger interface { JWTProfileVerifier() JWTProfileVerifier } -//JWTProfile handles the OAuth 2.0 JWT Profile Authorization Grant https://tools.ietf.org/html/rfc7523#section-2.1 +// JWTProfile handles the OAuth 2.0 JWT Profile Authorization Grant https://tools.ietf.org/html/rfc7523#section-2.1 func JWTProfile(w http.ResponseWriter, r *http.Request, exchanger JWTAuthorizationGrantExchanger) { profileRequest, err := ParseJWTProfileGrantRequest(r, exchanger.Decoder()) if err != nil { @@ -53,7 +53,7 @@ func ParseJWTProfileGrantRequest(r *http.Request, decoder httphelper.Decoder) (* return tokenReq, nil } -//CreateJWTTokenResponse creates +// CreateJWTTokenResponse creates func CreateJWTTokenResponse(ctx context.Context, tokenRequest TokenRequest, creator TokenCreator) (*oidc.AccessTokenResponse, error) { id, exp, err := creator.Storage().CreateAccessToken(ctx, tokenRequest) if err != nil { @@ -71,7 +71,7 @@ func CreateJWTTokenResponse(ctx context.Context, tokenRequest TokenRequest, crea }, nil } -//ParseJWTProfileRequest has been renamed to ParseJWTProfileGrantRequest +// ParseJWTProfileRequest has been renamed to ParseJWTProfileGrantRequest // //deprecated: use ParseJWTProfileGrantRequest func ParseJWTProfileRequest(r *http.Request, decoder httphelper.Decoder) (*oidc.JWTProfileGrantRequest, error) { diff --git a/pkg/op/token_refresh.go b/pkg/op/token_refresh.go index 5558a1d..7251eeb 100644 --- a/pkg/op/token_refresh.go +++ b/pkg/op/token_refresh.go @@ -21,8 +21,8 @@ type RefreshTokenRequest interface { SetCurrentScopes(scopes []string) } -//RefreshTokenExchange handles the OAuth 2.0 refresh_token grant, including -//parsing, validating, authorizing the client and finally exchanging the refresh_token for new tokens +// RefreshTokenExchange handles the OAuth 2.0 refresh_token grant, including +// parsing, validating, authorizing the client and finally exchanging the refresh_token for new tokens func RefreshTokenExchange(w http.ResponseWriter, r *http.Request, exchanger Exchanger) { tokenReq, err := ParseRefreshTokenRequest(r, exchanger.Decoder()) if err != nil { @@ -41,7 +41,7 @@ func RefreshTokenExchange(w http.ResponseWriter, r *http.Request, exchanger Exch httphelper.MarshalJSON(w, resp) } -//ParseRefreshTokenRequest parsed the http request into a oidc.RefreshTokenRequest +// ParseRefreshTokenRequest parsed the http request into a oidc.RefreshTokenRequest func ParseRefreshTokenRequest(r *http.Request, decoder httphelper.Decoder) (*oidc.RefreshTokenRequest, error) { request := new(oidc.RefreshTokenRequest) err := ParseAuthenticatedTokenRequest(r, decoder, request) @@ -51,8 +51,8 @@ func ParseRefreshTokenRequest(r *http.Request, decoder httphelper.Decoder) (*oid return request, nil } -//ValidateRefreshTokenRequest validates the refresh_token request parameters including authorization check of the client -//and returns the data representing the original auth request corresponding to the refresh_token +// ValidateRefreshTokenRequest validates the refresh_token request parameters including authorization check of the client +// and returns the data representing the original auth request corresponding to the refresh_token func ValidateRefreshTokenRequest(ctx context.Context, tokenReq *oidc.RefreshTokenRequest, exchanger Exchanger) (RefreshTokenRequest, Client, error) { if tokenReq.RefreshToken == "" { return nil, nil, oidc.ErrInvalidRequest().WithDescription("refresh_token missing") @@ -70,9 +70,9 @@ func ValidateRefreshTokenRequest(ctx context.Context, tokenReq *oidc.RefreshToke return request, client, nil } -//ValidateRefreshTokenScopes validates that the requested scope is a subset of the original auth request scope -//it will set the requested scopes as current scopes onto RefreshTokenRequest -//if empty the original scopes will be used +// ValidateRefreshTokenScopes validates that the requested scope is a subset of the original auth request scope +// it will set the requested scopes as current scopes onto RefreshTokenRequest +// if empty the original scopes will be used func ValidateRefreshTokenScopes(requestedScopes []string, authRequest RefreshTokenRequest) error { if len(requestedScopes) == 0 { return nil @@ -86,8 +86,8 @@ func ValidateRefreshTokenScopes(requestedScopes []string, authRequest RefreshTok return nil } -//AuthorizeRefreshClient checks the authorization of the client and that the used method was the one previously registered. -//It than returns the data representing the original auth request corresponding to the refresh_token +// AuthorizeRefreshClient checks the authorization of the client and that the used method was the one previously registered. +// It than returns the data representing the original auth request corresponding to the refresh_token func AuthorizeRefreshClient(ctx context.Context, tokenReq *oidc.RefreshTokenRequest, exchanger Exchanger) (request RefreshTokenRequest, client Client, err error) { if tokenReq.ClientAssertionType == oidc.ClientAssertionTypeJWTAssertion { jwtExchanger, ok := exchanger.(JWTAuthorizationGrantExchanger) @@ -128,8 +128,8 @@ func AuthorizeRefreshClient(ctx context.Context, tokenReq *oidc.RefreshTokenRequ return request, client, err } -//RefreshTokenRequestByRefreshToken returns the RefreshTokenRequest (data representing the original auth request) -//corresponding to the refresh_token from Storage or an error +// RefreshTokenRequestByRefreshToken returns the RefreshTokenRequest (data representing the original auth request) +// corresponding to the refresh_token from Storage or an error func RefreshTokenRequestByRefreshToken(ctx context.Context, storage Storage, refreshToken string) (RefreshTokenRequest, error) { request, err := storage.TokenRequestByRefreshToken(ctx, refreshToken) if err != nil { diff --git a/pkg/op/token_request.go b/pkg/op/token_request.go index dc8d118..6ccd489 100644 --- a/pkg/op/token_request.go +++ b/pkg/op/token_request.go @@ -29,7 +29,7 @@ func tokenHandler(exchanger Exchanger) func(w http.ResponseWriter, r *http.Reque } } -//Exchange performs a token exchange appropriate for the grant type +// Exchange performs a token exchange appropriate for the grant type func Exchange(w http.ResponseWriter, r *http.Request, exchanger Exchanger) { grantType := r.FormValue("grant_type") switch grantType { @@ -63,15 +63,15 @@ func Exchange(w http.ResponseWriter, r *http.Request, exchanger Exchanger) { RequestError(w, r, oidc.ErrUnsupportedGrantType().WithDescription("%s not supported", grantType)) } -//AuthenticatedTokenRequest is a helper interface for ParseAuthenticatedTokenRequest -//it is implemented by oidc.AuthRequest and oidc.RefreshTokenRequest +// AuthenticatedTokenRequest is a helper interface for ParseAuthenticatedTokenRequest +// it is implemented by oidc.AuthRequest and oidc.RefreshTokenRequest type AuthenticatedTokenRequest interface { SetClientID(string) SetClientSecret(string) } -//ParseAuthenticatedTokenRequest parses the client_id and client_secret from the HTTP request from either -//HTTP Basic Auth header or form body and sets them into the provided authenticatedTokenRequest interface +// ParseAuthenticatedTokenRequest parses the client_id and client_secret from the HTTP request from either +// HTTP Basic Auth header or form body and sets them into the provided authenticatedTokenRequest interface func ParseAuthenticatedTokenRequest(r *http.Request, decoder httphelper.Decoder, request AuthenticatedTokenRequest) error { err := r.ParseForm() if err != nil { @@ -98,7 +98,7 @@ func ParseAuthenticatedTokenRequest(r *http.Request, decoder httphelper.Decoder, return nil } -//AuthorizeClientIDSecret authorizes a client by validating the client_id and client_secret (Basic Auth and POST) +// AuthorizeClientIDSecret authorizes a client by validating the client_id and client_secret (Basic Auth and POST) func AuthorizeClientIDSecret(ctx context.Context, clientID, clientSecret string, storage Storage) error { err := storage.AuthorizeClientIDSecret(ctx, clientID, clientSecret) if err != nil { @@ -107,8 +107,8 @@ func AuthorizeClientIDSecret(ctx context.Context, clientID, clientSecret string, return nil } -//AuthorizeCodeChallenge authorizes a client by validating the code_verifier against the previously sent -//code_challenge of the auth request (PKCE) +// AuthorizeCodeChallenge authorizes a client by validating the code_verifier against the previously sent +// code_challenge of the auth request (PKCE) func AuthorizeCodeChallenge(tokenReq *oidc.AccessTokenRequest, challenge *oidc.CodeChallenge) error { if tokenReq.CodeVerifier == "" { return oidc.ErrInvalidRequest().WithDescription("code_challenge required") @@ -119,8 +119,8 @@ func AuthorizeCodeChallenge(tokenReq *oidc.AccessTokenRequest, challenge *oidc.C return nil } -//AuthorizePrivateJWTKey authorizes a client by validating the client_assertion's signature with a previously -//registered public key (JWT Profile) +// AuthorizePrivateJWTKey authorizes a client by validating the client_assertion's signature with a previously +// registered public key (JWT Profile) func AuthorizePrivateJWTKey(ctx context.Context, clientAssertion string, exchanger JWTAuthorizationGrantExchanger) (Client, error) { jwtReq, err := VerifyJWTAssertion(ctx, clientAssertion, exchanger.JWTProfileVerifier()) if err != nil { @@ -136,7 +136,7 @@ func AuthorizePrivateJWTKey(ctx context.Context, clientAssertion string, exchang return client, nil } -//ValidateGrantType ensures that the requested grant_type is allowed by the Client +// ValidateGrantType ensures that the requested grant_type is allowed by the Client func ValidateGrantType(client Client, grantType oidc.GrantType) bool { if client == nil { return false diff --git a/pkg/op/token_revocation.go b/pkg/op/token_revocation.go index b4ae266..375f7fc 100644 --- a/pkg/op/token_revocation.go +++ b/pkg/op/token_revocation.go @@ -54,9 +54,9 @@ func ParseTokenRevocationRequest(r *http.Request, revoker Revoker) (token, token } req := new(struct { oidc.RevocationRequest - oidc.ClientAssertionParams //for auth_method private_key_jwt - ClientID string `schema:"client_id"` //for auth_method none and post - ClientSecret string `schema:"client_secret"` //for auth_method post + oidc.ClientAssertionParams // for auth_method private_key_jwt + ClientID string `schema:"client_id"` // for auth_method none and post + ClientSecret string `schema:"client_secret"` // for auth_method post }) err = revoker.Decoder().Decode(req, r.Form) if err != nil { diff --git a/pkg/op/verifier_access_token.go b/pkg/op/verifier_access_token.go index d2c0c80..1729c23 100644 --- a/pkg/op/verifier_access_token.go +++ b/pkg/op/verifier_access_token.go @@ -23,27 +23,27 @@ type accessTokenVerifier struct { keySet oidc.KeySet } -//Issuer implements oidc.Verifier interface +// Issuer implements oidc.Verifier interface func (i *accessTokenVerifier) Issuer() string { return i.issuer } -//MaxAgeIAT implements oidc.Verifier interface +// MaxAgeIAT implements oidc.Verifier interface func (i *accessTokenVerifier) MaxAgeIAT() time.Duration { return i.maxAgeIAT } -//Offset implements oidc.Verifier interface +// Offset implements oidc.Verifier interface func (i *accessTokenVerifier) Offset() time.Duration { return i.offset } -//SupportedSignAlgs implements AccessTokenVerifier interface +// SupportedSignAlgs implements AccessTokenVerifier interface func (i *accessTokenVerifier) SupportedSignAlgs() []string { return i.supportedSignAlgs } -//KeySet implements AccessTokenVerifier interface +// KeySet implements AccessTokenVerifier interface func (i *accessTokenVerifier) KeySet() oidc.KeySet { return i.keySet } @@ -67,7 +67,7 @@ func NewAccessTokenVerifier(issuer string, keySet oidc.KeySet, opts ...AccessTok return verifier } -//VerifyAccessToken validates the access token (issuer, signature and expiration) +// VerifyAccessToken validates the access token (issuer, signature and expiration) func VerifyAccessToken(ctx context.Context, token string, v AccessTokenVerifier) (oidc.AccessTokenClaims, error) { claims := oidc.EmptyAccessTokenClaims() diff --git a/pkg/op/verifier_id_token_hint.go b/pkg/op/verifier_id_token_hint.go index bd9ff8e..e0372ee 100644 --- a/pkg/op/verifier_id_token_hint.go +++ b/pkg/op/verifier_id_token_hint.go @@ -61,7 +61,7 @@ func NewIDTokenHintVerifier(issuer string, keySet oidc.KeySet) IDTokenHintVerifi return verifier } -//VerifyIDTokenHint validates the id token according to +// VerifyIDTokenHint validates the id token according to //https://openid.net/specs/openid-connect-core-1_0.html#IDTokenValidation func VerifyIDTokenHint(ctx context.Context, token string, v IDTokenHintVerifier) (oidc.IDTokenClaims, error) { claims := oidc.EmptyIDTokenClaims() diff --git a/pkg/op/verifier_jwt_profile.go b/pkg/op/verifier_jwt_profile.go index 90dfc11..0215e84 100644 --- a/pkg/op/verifier_jwt_profile.go +++ b/pkg/op/verifier_jwt_profile.go @@ -25,7 +25,7 @@ type jwtProfileVerifier struct { offset time.Duration } -//NewJWTProfileVerifier creates a oidc.Verifier for JWT Profile assertions (authorization grant and client authentication) +// NewJWTProfileVerifier creates a oidc.Verifier for JWT Profile assertions (authorization grant and client authentication) func NewJWTProfileVerifier(storage jwtProfileKeyStorage, issuer string, maxAgeIAT, offset time.Duration, opts ...JWTProfileVerifierOption) JWTProfileVerifier { j := &jwtProfileVerifier{ storage: storage, @@ -70,9 +70,9 @@ func (v *jwtProfileVerifier) CheckSubject(request *oidc.JWTTokenRequest) error { return v.subjectCheck(request) } -//VerifyJWTAssertion verifies the assertion string from JWT Profile (authorization grant and client authentication) +// VerifyJWTAssertion verifies the assertion string from JWT Profile (authorization grant and client authentication) // -//checks audience, exp, iat, signature and that issuer and sub are the same +// checks audience, exp, iat, signature and that issuer and sub are the same func VerifyJWTAssertion(ctx context.Context, assertion string, v JWTProfileVerifier) (*oidc.JWTTokenRequest, error) { request := new(oidc.JWTTokenRequest) payload, err := oidc.ParseToken(assertion, request) @@ -119,7 +119,7 @@ type jwtProfileKeySet struct { clientID string } -//VerifySignature implements oidc.KeySet by getting the public key from Storage implementation +// VerifySignature implements oidc.KeySet by getting the public key from Storage implementation func (k *jwtProfileKeySet) VerifySignature(ctx context.Context, jws *jose.JSONWebSignature) (payload []byte, err error) { keyID, _ := oidc.GetKeyIDAndAlg(jws) key, err := k.storage.GetKeyByIDAndUserID(ctx, keyID, k.clientID)