chore(linting): apply gofumpt & goimports to all .go files (#225)
This commit is contained in:
parent
c4b7ef9160
commit
b5da6ec29b
45 changed files with 539 additions and 479 deletions
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
@ -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,
|
||||
},
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
38
pkg/op/op.go
38
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 {
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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"))
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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()
|
||||
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue