diff --git a/vcr/api/oauth2/v0/api.go b/vcr/api/oauth2/v0/api.go index 8a1a607015..837f547908 100644 --- a/vcr/api/oauth2/v0/api.go +++ b/vcr/api/oauth2/v0/api.go @@ -130,7 +130,7 @@ func (r Wrapper) HandleAuthorizeRequest(ctx context.Context, request HandleAutho return nil, err } if result != nil { - return HandleAuthorizeRequest200TexthtmlResponse{Body: bytes.NewReader(result.HTML), ContentLength: int64(len(result.HTML))}, nil + return HandleAuthorizeRequest200TexthtmlResponse{Body: bytes.NewReader(result.html), ContentLength: int64(len(result.html))}, nil } } diff --git a/vcr/api/oauth2/v0/authorized_code.go b/vcr/api/oauth2/v0/authorized_code.go index 2d18909a33..4ca0b89900 100644 --- a/vcr/api/oauth2/v0/authorized_code.go +++ b/vcr/api/oauth2/v0/authorized_code.go @@ -52,7 +52,7 @@ func (a authorizedCodeFlow) handleAuthzRequest(params map[string]string, session return nil, fmt.Errorf("unable to render authorization page: %w", err) } return &authzResponse{ - HTML: buf.Bytes(), + html: buf.Bytes(), }, nil } diff --git a/vcr/api/oauth2/v0/interface.go b/vcr/api/oauth2/v0/interface.go index 54f038e82c..a168a8fa4b 100644 --- a/vcr/api/oauth2/v0/interface.go +++ b/vcr/api/oauth2/v0/interface.go @@ -1,64 +1,23 @@ package v0 import ( - "github.com/google/uuid" "github.com/nuts-foundation/nuts-node/core" - "net/url" - "sync" ) +// authzResponse is the response to an Authorization Code flow request. type authzResponse struct { - HTML []byte + // html is the HTML page to be rendered to the user. + html []byte } type protocol interface { core.Routable + // handleAuthzRequest handles an Authorization Code flow request and returns an authzResponse if the request is handled by this protocol. + // If the protocol can't handle the supplied parameters it returns nil. handleAuthzRequest(map[string]string, *Session) (*authzResponse, error) grantHandlers() map[string]grantHandler } -// authzHandler defines a function for checking authorization requests given the input parameters, used to initiate the authorization code flow. -type authzHandler func(map[string]string, *Session) (bool, error) - // grantHandler defines a function for checking a grant given the input parameters, used to validate token requests. // It returns the requested scopes if the validation succeeds. type grantHandler func(map[string]string) (string, error) - -type SessionManager struct { - sessions *sync.Map -} - -func (s *SessionManager) Create(session Session) string { - // TODO: Session expiration - // TODO: Session storage - // TODO: Session pinning and other safety measures (see OAuth2 Threat Model) - id := uuid.NewString() - s.sessions.Store(id, session) - return id -} - -func (s *SessionManager) Get(id string) *Session { - session, ok := s.sessions.Load(id) - if !ok { - return nil - } - result := session.(Session) - return &result -} - -type Session struct { - ClientID string - Scope string - ClientState string - RedirectURI string -} - -func (s Session) CreateRedirectURI(params map[string]string) string { - redirectURI, _ := url.Parse(s.RedirectURI) - query := redirectURI.Query() - for key, value := range params { - query.Add(key, value) - } - redirectURI.RawQuery = query.Encode() - return redirectURI.String() -} diff --git a/vcr/api/oauth2/v0/openid4vp.go b/vcr/api/oauth2/v0/openid4vp.go index 52c67cccc3..79ea1c7873 100644 --- a/vcr/api/oauth2/v0/openid4vp.go +++ b/vcr/api/oauth2/v0/openid4vp.go @@ -64,7 +64,7 @@ func (a openID4VP) handleAuthzRequest(params map[string]string, session *Session return nil, fmt.Errorf("unable to render authorization page: %w", err) } return &authzResponse{ - HTML: buf.Bytes(), + html: buf.Bytes(), }, nil } diff --git a/vcr/api/oauth2/v0/session.go b/vcr/api/oauth2/v0/session.go new file mode 100644 index 0000000000..5b1f392871 --- /dev/null +++ b/vcr/api/oauth2/v0/session.go @@ -0,0 +1,46 @@ +package v0 + +import ( + "github.com/google/uuid" + "net/url" + "sync" +) + +type SessionManager struct { + sessions *sync.Map +} + +func (s *SessionManager) Create(session Session) string { + // TODO: Session expiration + // TODO: Session storage + // TODO: Session pinning and other safety measures (see OAuth2 Threat Model) + id := uuid.NewString() + s.sessions.Store(id, session) + return id +} + +func (s *SessionManager) Get(id string) *Session { + session, ok := s.sessions.Load(id) + if !ok { + return nil + } + result := session.(Session) + return &result +} + +type Session struct { + ClientID string + Scope string + ClientState string + RedirectURI string +} + +func (s Session) CreateRedirectURI(params map[string]string) string { + redirectURI, _ := url.Parse(s.RedirectURI) + query := redirectURI.Query() + for key, value := range params { + query.Add(key, value) + } + redirectURI.RawQuery = query.Encode() + return redirectURI.String() +}