@ -35,13 +35,13 @@ func (s *Server) handlePublicKeys(w http.ResponseWriter, r *http.Request) {
// TODO(ericchiang): Cache this.
// TODO(ericchiang): Cache this.
keys , err := s . storage . GetKeys ( )
keys , err := s . storage . GetKeys ( )
if err != nil {
if err != nil {
s . logger . Errorf ( "failed to get keys: %v " , err )
s . logger . Error ( "failed to get keys" , "err " , err )
s . renderError ( r , w , http . StatusInternalServerError , "Internal server error." )
s . renderError ( r , w , http . StatusInternalServerError , "Internal server error." )
return
return
}
}
if keys . SigningKeyPub == nil {
if keys . SigningKeyPub == nil {
s . logger . Errorf ( "N o public keys found." )
s . logger . Error ( "n o public keys found." )
s . renderError ( r , w , http . StatusInternalServerError , "Internal server error." )
s . renderError ( r , w , http . StatusInternalServerError , "Internal server error." )
return
return
}
}
@ -56,7 +56,7 @@ func (s *Server) handlePublicKeys(w http.ResponseWriter, r *http.Request) {
data , err := json . MarshalIndent ( jwks , "" , " " )
data , err := json . MarshalIndent ( jwks , "" , " " )
if err != nil {
if err != nil {
s . logger . Errorf ( "failed to marshal discovery data: %v " , err )
s . logger . Error ( "failed to marshal discovery data" , "err " , err )
s . renderError ( r , w , http . StatusInternalServerError , "Internal server error." )
s . renderError ( r , w , http . StatusInternalServerError , "Internal server error." )
return
return
}
}
@ -132,7 +132,7 @@ func (s *Server) discoveryHandler() (http.HandlerFunc, error) {
func ( s * Server ) handleAuthorization ( w http . ResponseWriter , r * http . Request ) {
func ( s * Server ) handleAuthorization ( w http . ResponseWriter , r * http . Request ) {
// Extract the arguments
// Extract the arguments
if err := r . ParseForm ( ) ; err != nil {
if err := r . ParseForm ( ) ; err != nil {
s . logger . Errorf ( "Failed to parse arguments: %v " , err )
s . logger . Error ( "failed to parse arguments" , "err " , err )
s . renderError ( r , w , http . StatusBadRequest , err . Error ( ) )
s . renderError ( r , w , http . StatusBadRequest , err . Error ( ) )
return
return
@ -142,7 +142,7 @@ func (s *Server) handleAuthorization(w http.ResponseWriter, r *http.Request) {
connectors , err := s . storage . ListConnectors ( )
connectors , err := s . storage . ListConnectors ( )
if err != nil {
if err != nil {
s . logger . Errorf ( "Failed to get list of connectors: %v " , err )
s . logger . Error ( "failed to get list of connectors" , "err " , err )
s . renderError ( r , w , http . StatusInternalServerError , "Failed to retrieve connector list." )
s . renderError ( r , w , http . StatusInternalServerError , "Failed to retrieve connector list." )
return
return
}
}
@ -185,7 +185,7 @@ func (s *Server) handleAuthorization(w http.ResponseWriter, r *http.Request) {
}
}
if err := s . templates . login ( r , w , connectorInfos ) ; err != nil {
if err := s . templates . login ( r , w , connectorInfos ) ; err != nil {
s . logger . Errorf ( "Server template error: %v " , err )
s . logger . Error ( "server template error" , "err " , err )
}
}
}
}
@ -193,7 +193,7 @@ func (s *Server) handleConnectorLogin(w http.ResponseWriter, r *http.Request) {
ctx := r . Context ( )
ctx := r . Context ( )
authReq , err := s . parseAuthorizationRequest ( r )
authReq , err := s . parseAuthorizationRequest ( r )
if err != nil {
if err != nil {
s . logger . Errorf ( "Failed to parse authorization request: %v " , err )
s . logger . Error ( "failed to parse authorization request" , "err " , err )
switch authErr := err . ( type ) {
switch authErr := err . ( type ) {
case * redirectedAuthErr :
case * redirectedAuthErr :
@ -209,22 +209,22 @@ func (s *Server) handleConnectorLogin(w http.ResponseWriter, r *http.Request) {
connID , err := url . PathUnescape ( mux . Vars ( r ) [ "connector" ] )
connID , err := url . PathUnescape ( mux . Vars ( r ) [ "connector" ] )
if err != nil {
if err != nil {
s . logger . Errorf ( "Failed to parse connector: %v " , err )
s . logger . Error ( "failed to parse connector" , "err " , err )
s . renderError ( r , w , http . StatusBadRequest , "Requested resource does not exist" )
s . renderError ( r , w , http . StatusBadRequest , "Requested resource does not exist" )
return
return
}
}
conn , err := s . getConnector ( connID )
conn , err := s . getConnector ( connID )
if err != nil {
if err != nil {
s . logger . Errorf ( "Failed to get connector: %v " , err )
s . logger . Error ( "Failed to get connector" , "err " , err )
s . renderError ( r , w , http . StatusBadRequest , "Requested resource does not exist" )
s . renderError ( r , w , http . StatusBadRequest , "Requested resource does not exist" )
return
return
}
}
// Set the connector being used for the login.
// Set the connector being used for the login.
if authReq . ConnectorID != "" && authReq . ConnectorID != connID {
if authReq . ConnectorID != "" && authReq . ConnectorID != connID {
s . logger . Errorf ( "Mismatched connector ID in auth request: %s vs %s " ,
s . logger . Error ( "mismatched connector ID in auth request " ,
authReq . ConnectorID , connID )
"auth_request_connector_id" , authReq . ConnectorID , "connector_id" , connID )
s . renderError ( r , w , http . StatusBadRequest , "Bad connector ID" )
s . renderError ( r , w , http . StatusBadRequest , "Bad connector ID" )
return
return
}
}
@ -234,7 +234,7 @@ func (s *Server) handleConnectorLogin(w http.ResponseWriter, r *http.Request) {
// Actually create the auth request
// Actually create the auth request
authReq . Expiry = s . now ( ) . Add ( s . authRequestsValidFor )
authReq . Expiry = s . now ( ) . Add ( s . authRequestsValidFor )
if err := s . storage . CreateAuthRequest ( ctx , * authReq ) ; err != nil {
if err := s . storage . CreateAuthRequest ( ctx , * authReq ) ; err != nil {
s . logger . Errorf ( "Failed to create authorization request: %v " , err )
s . logger . Error ( "failed to create authorization request" , "err " , err )
s . renderError ( r , w , http . StatusInternalServerError , "Failed to connect to the database." )
s . renderError ( r , w , http . StatusInternalServerError , "Failed to connect to the database." )
return
return
}
}
@ -260,7 +260,7 @@ func (s *Server) handleConnectorLogin(w http.ResponseWriter, r *http.Request) {
// TODO(ericchiang): Is this appropriate or should we also be using a nonce?
// TODO(ericchiang): Is this appropriate or should we also be using a nonce?
callbackURL , err := conn . LoginURL ( scopes , s . absURL ( "/callback" ) , authReq . ID )
callbackURL , err := conn . LoginURL ( scopes , s . absURL ( "/callback" ) , authReq . ID )
if err != nil {
if err != nil {
s . logger . Errorf ( "Connector %q returned error when creating callback: %v " , connID , err )
s . logger . Error ( "connector returned error when creating callback" , "connector_id " , connID , "err" , err )
s . renderError ( r , w , http . StatusInternalServerError , "Login error." )
s . renderError ( r , w , http . StatusInternalServerError , "Login error." )
return
return
}
}
@ -278,7 +278,7 @@ func (s *Server) handleConnectorLogin(w http.ResponseWriter, r *http.Request) {
case connector . SAMLConnector :
case connector . SAMLConnector :
action , value , err := conn . POSTData ( scopes , authReq . ID )
action , value , err := conn . POSTData ( scopes , authReq . ID )
if err != nil {
if err != nil {
s . logger . Errorf ( "Creating SAML data: %v " , err )
s . logger . Error ( "creating SAML data" , "err " , err )
s . renderError ( r , w , http . StatusInternalServerError , "Connector Login Error" )
s . renderError ( r , w , http . StatusInternalServerError , "Connector Login Error" )
return
return
}
}
@ -321,36 +321,36 @@ func (s *Server) handlePasswordLogin(w http.ResponseWriter, r *http.Request) {
authReq , err := s . storage . GetAuthRequest ( authID )
authReq , err := s . storage . GetAuthRequest ( authID )
if err != nil {
if err != nil {
if err == storage . ErrNotFound {
if err == storage . ErrNotFound {
s . logger . Errorf ( "Invalid 'state' parameter provided: %v " , err )
s . logger . Error ( "invalid 'state' parameter provided" , "err " , err )
s . renderError ( r , w , http . StatusBadRequest , "Requested resource does not exist." )
s . renderError ( r , w , http . StatusBadRequest , "Requested resource does not exist." )
return
return
}
}
s . logger . Errorf ( "Failed to get auth request: %v " , err )
s . logger . Error ( "failed to get auth request" , "err " , err )
s . renderError ( r , w , http . StatusInternalServerError , "Database error." )
s . renderError ( r , w , http . StatusInternalServerError , "Database error." )
return
return
}
}
connID , err := url . PathUnescape ( mux . Vars ( r ) [ "connector" ] )
connID , err := url . PathUnescape ( mux . Vars ( r ) [ "connector" ] )
if err != nil {
if err != nil {
s . logger . Errorf ( "Failed to parse connector: %v " , err )
s . logger . Error ( "failed to parse connector" , "err " , err )
s . renderError ( r , w , http . StatusBadRequest , "Requested resource does not exist" )
s . renderError ( r , w , http . StatusBadRequest , "Requested resource does not exist" )
return
return
} else if connID != "" && connID != authReq . ConnectorID {
} else if connID != "" && connID != authReq . ConnectorID {
s . logger . Errorf ( "Connector mismatch: authentication started with id %q, but password login for id %q was triggere d" , authReq . ConnectorID , connID )
s . logger . Error ( "connector mismatch: password login triggered for different connector from authentication start" , "start_connector_i d" , authReq . ConnectorID , "password_connector_id" , connID )
s . renderError ( r , w , http . StatusInternalServerError , "Requested resource does not exist." )
s . renderError ( r , w , http . StatusInternalServerError , "Requested resource does not exist." )
return
return
}
}
conn , err := s . getConnector ( authReq . ConnectorID )
conn , err := s . getConnector ( authReq . ConnectorID )
if err != nil {
if err != nil {
s . logger . Errorf ( "Failed to get connector with id %q : %v " , authReq . ConnectorID , err )
s . logger . Error ( "failed to get connector" , "connector_id " , authReq . ConnectorID , "err" , err )
s . renderError ( r , w , http . StatusInternalServerError , "Requested resource does not exist." )
s . renderError ( r , w , http . StatusInternalServerError , "Requested resource does not exist." )
return
return
}
}
pwConn , ok := conn . Connector . ( connector . PasswordConnector )
pwConn , ok := conn . Connector . ( connector . PasswordConnector )
if ! ok {
if ! ok {
s . logger . Errorf ( "Expected password connector in handlePasswordLogin(), but got %v " , pwConn )
s . logger . Error ( "expected password connector in handlePasswordLogin()" , "password_connector " , pwConn )
s . renderError ( r , w , http . StatusInternalServerError , "Requested resource does not exist." )
s . renderError ( r , w , http . StatusInternalServerError , "Requested resource does not exist." )
return
return
}
}
@ -358,7 +358,7 @@ func (s *Server) handlePasswordLogin(w http.ResponseWriter, r *http.Request) {
switch r . Method {
switch r . Method {
case http . MethodGet :
case http . MethodGet :
if err := s . templates . password ( r , w , r . URL . String ( ) , "" , usernamePrompt ( pwConn ) , false , backLink ) ; err != nil {
if err := s . templates . password ( r , w , r . URL . String ( ) , "" , usernamePrompt ( pwConn ) , false , backLink ) ; err != nil {
s . logger . Errorf ( "Server template error: %v " , err )
s . logger . Error ( "server template error" , "err " , err )
}
}
case http . MethodPost :
case http . MethodPost :
username := r . FormValue ( "login" )
username := r . FormValue ( "login" )
@ -367,20 +367,20 @@ func (s *Server) handlePasswordLogin(w http.ResponseWriter, r *http.Request) {
identity , ok , err := pwConn . Login ( ctx , scopes , username , password )
identity , ok , err := pwConn . Login ( ctx , scopes , username , password )
if err != nil {
if err != nil {
s . logger . Errorf ( "Failed to login user: %v " , err )
s . logger . Error ( "failed to login user" , "err " , err )
s . renderError ( r , w , http . StatusInternalServerError , fmt . Sprintf ( "Login error: %v" , err ) )
s . renderError ( r , w , http . StatusInternalServerError , fmt . Sprintf ( "Login error: %v" , err ) )
return
return
}
}
if ! ok {
if ! ok {
if err := s . templates . password ( r , w , r . URL . String ( ) , username , usernamePrompt ( pwConn ) , true , backLink ) ; err != nil {
if err := s . templates . password ( r , w , r . URL . String ( ) , username , usernamePrompt ( pwConn ) , true , backLink ) ; err != nil {
s . logger . Errorf ( "Server template error: %v " , err )
s . logger . Error ( "server template error" , "err " , err )
}
}
s . logger . Errorf ( "Failed login attempt for user: %q. Invalid credentials. " , username )
s . logger . Error ( "failed login attempt: Invalid credentials." , "user " , username )
return
return
}
}
redirectURL , canSkipApproval , err := s . finalizeLogin ( ctx , identity , authReq , conn . Connector )
redirectURL , canSkipApproval , err := s . finalizeLogin ( ctx , identity , authReq , conn . Connector )
if err != nil {
if err != nil {
s . logger . Errorf ( "Failed to finalize login: %v " , err )
s . logger . Error ( "failed to finalize login" , "err " , err )
s . renderError ( r , w , http . StatusInternalServerError , "Login error." )
s . renderError ( r , w , http . StatusInternalServerError , "Login error." )
return
return
}
}
@ -388,7 +388,7 @@ func (s *Server) handlePasswordLogin(w http.ResponseWriter, r *http.Request) {
if canSkipApproval {
if canSkipApproval {
authReq , err = s . storage . GetAuthRequest ( authReq . ID )
authReq , err = s . storage . GetAuthRequest ( authReq . ID )
if err != nil {
if err != nil {
s . logger . Errorf ( "Failed to get finalized auth request: %v " , err )
s . logger . Error ( "failed to get finalized auth request" , "err " , err )
s . renderError ( r , w , http . StatusInternalServerError , "Login error." )
s . renderError ( r , w , http . StatusInternalServerError , "Login error." )
return
return
}
}
@ -424,29 +424,29 @@ func (s *Server) handleConnectorCallback(w http.ResponseWriter, r *http.Request)
authReq , err := s . storage . GetAuthRequest ( authID )
authReq , err := s . storage . GetAuthRequest ( authID )
if err != nil {
if err != nil {
if err == storage . ErrNotFound {
if err == storage . ErrNotFound {
s . logger . Errorf ( "Invalid 'state' parameter provided: %v " , err )
s . logger . Error ( "invalid 'state' parameter provided" , "err " , err )
s . renderError ( r , w , http . StatusBadRequest , "Requested resource does not exist." )
s . renderError ( r , w , http . StatusBadRequest , "Requested resource does not exist." )
return
return
}
}
s . logger . Errorf ( "Failed to get auth request: %v " , err )
s . logger . Error ( "failed to get auth request" , "err " , err )
s . renderError ( r , w , http . StatusInternalServerError , "Database error." )
s . renderError ( r , w , http . StatusInternalServerError , "Database error." )
return
return
}
}
connID , err := url . PathUnescape ( mux . Vars ( r ) [ "connector" ] )
connID , err := url . PathUnescape ( mux . Vars ( r ) [ "connector" ] )
if err != nil {
if err != nil {
s . logger . Errorf ( "Failed to get connector with id %q : %v " , authReq . ConnectorID , err )
s . logger . Error ( "failed to get connector" , "connector_id " , authReq . ConnectorID , "err" , err )
s . renderError ( r , w , http . StatusInternalServerError , "Requested resource does not exist." )
s . renderError ( r , w , http . StatusInternalServerError , "Requested resource does not exist." )
return
return
} else if connID != "" && connID != authReq . ConnectorID {
} else if connID != "" && connID != authReq . ConnectorID {
s . logger . Errorf ( "Connector mismatch: authentication started with id %q, but callback for id %q was triggere d" , authReq . ConnectorID , connID )
s . logger . Error ( "connector mismatch: callback triggered for different connector than authentication start" , "authentication_start_connector_i d" , authReq . ConnectorID , "connector_id" , connID )
s . renderError ( r , w , http . StatusInternalServerError , "Requested resource does not exist." )
s . renderError ( r , w , http . StatusInternalServerError , "Requested resource does not exist." )
return
return
}
}
conn , err := s . getConnector ( authReq . ConnectorID )
conn , err := s . getConnector ( authReq . ConnectorID )
if err != nil {
if err != nil {
s . logger . Errorf ( "Failed to get connector with id %q : %v " , authReq . ConnectorID , err )
s . logger . Error ( "failed to get connector" , "connector_id " , authReq . ConnectorID , "err" , err )
s . renderError ( r , w , http . StatusInternalServerError , "Requested resource does not exist." )
s . renderError ( r , w , http . StatusInternalServerError , "Requested resource does not exist." )
return
return
}
}
@ -455,14 +455,14 @@ func (s *Server) handleConnectorCallback(w http.ResponseWriter, r *http.Request)
switch conn := conn . Connector . ( type ) {
switch conn := conn . Connector . ( type ) {
case connector . CallbackConnector :
case connector . CallbackConnector :
if r . Method != http . MethodGet {
if r . Method != http . MethodGet {
s . logger . Errorf ( "SAML request mapped to OAuth2 connector" )
s . logger . Error ( "SAML request mapped to OAuth2 connector" )
s . renderError ( r , w , http . StatusBadRequest , "Invalid request" )
s . renderError ( r , w , http . StatusBadRequest , "Invalid request" )
return
return
}
}
identity , err = conn . HandleCallback ( parseScopes ( authReq . Scopes ) , r )
identity , err = conn . HandleCallback ( parseScopes ( authReq . Scopes ) , r )
case connector . SAMLConnector :
case connector . SAMLConnector :
if r . Method != http . MethodPost {
if r . Method != http . MethodPost {
s . logger . Errorf ( "OAuth2 request mapped to SAML connector" )
s . logger . Error ( "OAuth2 request mapped to SAML connector" )
s . renderError ( r , w , http . StatusBadRequest , "Invalid request" )
s . renderError ( r , w , http . StatusBadRequest , "Invalid request" )
return
return
}
}
@ -473,14 +473,14 @@ func (s *Server) handleConnectorCallback(w http.ResponseWriter, r *http.Request)
}
}
if err != nil {
if err != nil {
s . logger . Errorf ( "Failed to authenticate: %v " , err )
s . logger . Error ( "failed to authenticate" , "err " , err )
s . renderError ( r , w , http . StatusInternalServerError , fmt . Sprintf ( "Failed to authenticate: %v" , err ) )
s . renderError ( r , w , http . StatusInternalServerError , fmt . Sprintf ( "Failed to authenticate: %v" , err ) )
return
return
}
}
redirectURL , canSkipApproval , err := s . finalizeLogin ( ctx , identity , authReq , conn . Connector )
redirectURL , canSkipApproval , err := s . finalizeLogin ( ctx , identity , authReq , conn . Connector )
if err != nil {
if err != nil {
s . logger . Errorf ( "Failed to finalize login: %v " , err )
s . logger . Error ( "failed to finalize login" , "err " , err )
s . renderError ( r , w , http . StatusInternalServerError , "Login error." )
s . renderError ( r , w , http . StatusInternalServerError , "Login error." )
return
return
}
}
@ -488,7 +488,7 @@ func (s *Server) handleConnectorCallback(w http.ResponseWriter, r *http.Request)
if canSkipApproval {
if canSkipApproval {
authReq , err = s . storage . GetAuthRequest ( authReq . ID )
authReq , err = s . storage . GetAuthRequest ( authReq . ID )
if err != nil {
if err != nil {
s . logger . Errorf ( "Failed to get finalized auth request: %v " , err )
s . logger . Error ( "failed to get finalized auth request" , "err " , err )
s . renderError ( r , w , http . StatusInternalServerError , "Login error." )
s . renderError ( r , w , http . StatusInternalServerError , "Login error." )
return
return
}
}
@ -526,8 +526,9 @@ func (s *Server) finalizeLogin(ctx context.Context, identity connector.Identity,
email += " (unverified)"
email += " (unverified)"
}
}
s . logger . Infof ( "login successful: connector %q, username=%q, preferred_username=%q, email=%q, groups=%q" ,
s . logger . Info ( "login successful" ,
authReq . ConnectorID , claims . Username , claims . PreferredUsername , email , claims . Groups )
"connector_id" , authReq . ConnectorID , "username" , claims . Username ,
"preferred_username" , claims . PreferredUsername , "email" , email , "groups" , claims . Groups )
// we can skip the redirect to /approval and go ahead and send code if it's not required
// we can skip the redirect to /approval and go ahead and send code if it's not required
if s . skipApproval && ! authReq . ForceApprovalPrompt {
if s . skipApproval && ! authReq . ForceApprovalPrompt {
@ -561,7 +562,7 @@ func (s *Server) finalizeLogin(ctx context.Context, identity connector.Identity,
session , err := s . storage . GetOfflineSessions ( identity . UserID , authReq . ConnectorID )
session , err := s . storage . GetOfflineSessions ( identity . UserID , authReq . ConnectorID )
if err != nil {
if err != nil {
if err != storage . ErrNotFound {
if err != storage . ErrNotFound {
s . logger . Errorf ( "failed to get offline session: %v " , err )
s . logger . Error ( "failed to get offline session" , "err " , err )
return "" , false , err
return "" , false , err
}
}
offlineSessions := storage . OfflineSessions {
offlineSessions := storage . OfflineSessions {
@ -574,7 +575,7 @@ func (s *Server) finalizeLogin(ctx context.Context, identity connector.Identity,
// Create a new OfflineSession object for the user and add a reference object for
// Create a new OfflineSession object for the user and add a reference object for
// the newly received refreshtoken.
// the newly received refreshtoken.
if err := s . storage . CreateOfflineSessions ( ctx , offlineSessions ) ; err != nil {
if err := s . storage . CreateOfflineSessions ( ctx , offlineSessions ) ; err != nil {
s . logger . Errorf ( "failed to create offline session: %v " , err )
s . logger . Error ( "failed to create offline session" , "err " , err )
return "" , false , err
return "" , false , err
}
}
@ -588,7 +589,7 @@ func (s *Server) finalizeLogin(ctx context.Context, identity connector.Identity,
}
}
return old , nil
return old , nil
} ) ; err != nil {
} ) ; err != nil {
s . logger . Errorf ( "failed to update offline session: %v " , err )
s . logger . Error ( "failed to update offline session" , "err " , err )
return "" , false , err
return "" , false , err
}
}
@ -609,12 +610,12 @@ func (s *Server) handleApproval(w http.ResponseWriter, r *http.Request) {
authReq , err := s . storage . GetAuthRequest ( r . FormValue ( "req" ) )
authReq , err := s . storage . GetAuthRequest ( r . FormValue ( "req" ) )
if err != nil {
if err != nil {
s . logger . Errorf ( "Failed to get auth request: %v " , err )
s . logger . Error ( "failed to get auth request" , "err " , err )
s . renderError ( r , w , http . StatusInternalServerError , "Database error." )
s . renderError ( r , w , http . StatusInternalServerError , "Database error." )
return
return
}
}
if ! authReq . LoggedIn {
if ! authReq . LoggedIn {
s . logger . Errorf ( "A uth request does not have an identity for approval" )
s . logger . Error ( "a uth request does not have an identity for approval" )
s . renderError ( r , w , http . StatusInternalServerError , "Login process not yet finalized." )
s . renderError ( r , w , http . StatusInternalServerError , "Login process not yet finalized." )
return
return
}
}
@ -633,12 +634,12 @@ func (s *Server) handleApproval(w http.ResponseWriter, r *http.Request) {
case http . MethodGet :
case http . MethodGet :
client , err := s . storage . GetClient ( authReq . ClientID )
client , err := s . storage . GetClient ( authReq . ClientID )
if err != nil {
if err != nil {
s . logger . Errorf ( "Failed to get client %q: %v " , authReq . ClientID , err )
s . logger . Error ( "Failed to get client" , "client_id " , authReq . ClientID , "err" , err )
s . renderError ( r , w , http . StatusInternalServerError , "Failed to retrieve client." )
s . renderError ( r , w , http . StatusInternalServerError , "Failed to retrieve client." )
return
return
}
}
if err := s . templates . approval ( r , w , authReq . ID , authReq . Claims . Username , client . Name , authReq . Scopes ) ; err != nil {
if err := s . templates . approval ( r , w , authReq . ID , authReq . Claims . Username , client . Name , authReq . Scopes ) ; err != nil {
s . logger . Errorf ( "Server template error: %v " , err )
s . logger . Error ( "server template error" , "err " , err )
}
}
case http . MethodPost :
case http . MethodPost :
if r . FormValue ( "approval" ) != "approve" {
if r . FormValue ( "approval" ) != "approve" {
@ -658,7 +659,7 @@ func (s *Server) sendCodeResponse(w http.ResponseWriter, r *http.Request, authRe
if err := s . storage . DeleteAuthRequest ( authReq . ID ) ; err != nil {
if err := s . storage . DeleteAuthRequest ( authReq . ID ) ; err != nil {
if err != storage . ErrNotFound {
if err != storage . ErrNotFound {
s . logger . Errorf ( "Failed to delete authorization request: %v " , err )
s . logger . Error ( "Failed to delete authorization request" , "err " , err )
s . renderError ( r , w , http . StatusInternalServerError , "Internal server error." )
s . renderError ( r , w , http . StatusInternalServerError , "Internal server error." )
} else {
} else {
s . renderError ( r , w , http . StatusBadRequest , "User session error." )
s . renderError ( r , w , http . StatusBadRequest , "User session error." )
@ -704,7 +705,7 @@ func (s *Server) sendCodeResponse(w http.ResponseWriter, r *http.Request, authRe
PKCE : authReq . PKCE ,
PKCE : authReq . PKCE ,
}
}
if err := s . storage . CreateAuthCode ( ctx , code ) ; err != nil {
if err := s . storage . CreateAuthCode ( ctx , code ) ; err != nil {
s . logger . Errorf ( "Failed to create auth code: %v " , err )
s . logger . Error ( "Failed to create auth code" , "err " , err )
s . renderError ( r , w , http . StatusInternalServerError , "Internal server error." )
s . renderError ( r , w , http . StatusInternalServerError , "Internal server error." )
return
return
}
}
@ -713,7 +714,7 @@ func (s *Server) sendCodeResponse(w http.ResponseWriter, r *http.Request, authRe
// rejected earlier. If we got here we're using the code flow.
// rejected earlier. If we got here we're using the code flow.
if authReq . RedirectURI == redirectURIOOB {
if authReq . RedirectURI == redirectURIOOB {
if err := s . templates . oob ( r , w , code . ID ) ; err != nil {
if err := s . templates . oob ( r , w , code . ID ) ; err != nil {
s . logger . Errorf ( "Server template error: %v " , err )
s . logger . Error ( "server template error" , "err " , err )
}
}
return
return
}
}
@ -725,14 +726,14 @@ func (s *Server) sendCodeResponse(w http.ResponseWriter, r *http.Request, authRe
accessToken , _ , err = s . newAccessToken ( authReq . ClientID , authReq . Claims , authReq . Scopes , authReq . Nonce , authReq . ConnectorID )
accessToken , _ , err = s . newAccessToken ( authReq . ClientID , authReq . Claims , authReq . Scopes , authReq . Nonce , authReq . ConnectorID )
if err != nil {
if err != nil {
s . logger . Errorf ( "failed to create new access token: %v " , err )
s . logger . Error ( "failed to create new access token" , "err " , err )
s . tokenErrHelper ( w , errServerError , "" , http . StatusInternalServerError )
s . tokenErrHelper ( w , errServerError , "" , http . StatusInternalServerError )
return
return
}
}
idToken , idTokenExpiry , err = s . newIDToken ( authReq . ClientID , authReq . Claims , authReq . Scopes , authReq . Nonce , accessToken , code . ID , authReq . ConnectorID )
idToken , idTokenExpiry , err = s . newIDToken ( authReq . ClientID , authReq . Claims , authReq . Scopes , authReq . Nonce , accessToken , code . ID , authReq . ConnectorID )
if err != nil {
if err != nil {
s . logger . Errorf ( "failed to create ID token: %v " , err )
s . logger . Error ( "failed to create ID token" , "err " , err )
s . tokenErrHelper ( w , errServerError , "" , http . StatusInternalServerError )
s . tokenErrHelper ( w , errServerError , "" , http . StatusInternalServerError )
return
return
}
}
@ -807,7 +808,7 @@ func (s *Server) withClientFromStorage(w http.ResponseWriter, r *http.Request, h
client , err := s . storage . GetClient ( clientID )
client , err := s . storage . GetClient ( clientID )
if err != nil {
if err != nil {
if err != storage . ErrNotFound {
if err != storage . ErrNotFound {
s . logger . Errorf ( "failed to get client: %v " , err )
s . logger . Error ( "failed to get client" , "err " , err )
s . tokenErrHelper ( w , errServerError , "" , http . StatusInternalServerError )
s . tokenErrHelper ( w , errServerError , "" , http . StatusInternalServerError )
} else {
} else {
s . tokenErrHelper ( w , errInvalidClient , "Invalid client credentials." , http . StatusUnauthorized )
s . tokenErrHelper ( w , errInvalidClient , "Invalid client credentials." , http . StatusUnauthorized )
@ -817,9 +818,9 @@ func (s *Server) withClientFromStorage(w http.ResponseWriter, r *http.Request, h
if subtle . ConstantTimeCompare ( [ ] byte ( client . Secret ) , [ ] byte ( clientSecret ) ) != 1 {
if subtle . ConstantTimeCompare ( [ ] byte ( client . Secret ) , [ ] byte ( clientSecret ) ) != 1 {
if clientSecret == "" {
if clientSecret == "" {
s . logger . Infof ( "missing client_secret on token request for client: %s " , client . ID )
s . logger . Info ( "missing client_secret on token request" , "client_id " , client . ID )
} else {
} else {
s . logger . Infof ( "invalid client_secret on token request for client: %s " , client . ID )
s . logger . Info ( "invalid client_secret on token request" , "client_id " , client . ID )
}
}
s . tokenErrHelper ( w , errInvalidClient , "Invalid client credentials." , http . StatusUnauthorized )
s . tokenErrHelper ( w , errInvalidClient , "Invalid client credentials." , http . StatusUnauthorized )
return
return
@ -837,14 +838,14 @@ func (s *Server) handleToken(w http.ResponseWriter, r *http.Request) {
err := r . ParseForm ( )
err := r . ParseForm ( )
if err != nil {
if err != nil {
s . logger . Errorf ( "Could not parse request body: %v " , err )
s . logger . Error ( "could not parse request body" , "err " , err )
s . tokenErrHelper ( w , errInvalidRequest , "" , http . StatusBadRequest )
s . tokenErrHelper ( w , errInvalidRequest , "" , http . StatusBadRequest )
return
return
}
}
grantType := r . PostFormValue ( "grant_type" )
grantType := r . PostFormValue ( "grant_type" )
if ! contains ( s . supportedGrantTypes , grantType ) {
if ! contains ( s . supportedGrantTypes , grantType ) {
s . logger . Errorf ( "unsupported grant type: %v " , grantType )
s . logger . Error ( "unsupported grant type" , "grant_type " , grantType )
s . tokenErrHelper ( w , errUnsupportedGrantType , "" , http . StatusBadRequest )
s . tokenErrHelper ( w , errUnsupportedGrantType , "" , http . StatusBadRequest )
return
return
}
}
@ -890,7 +891,7 @@ func (s *Server) handleAuthCode(w http.ResponseWriter, r *http.Request, client s
authCode , err := s . storage . GetAuthCode ( code )
authCode , err := s . storage . GetAuthCode ( code )
if err != nil || s . now ( ) . After ( authCode . Expiry ) || authCode . ClientID != client . ID {
if err != nil || s . now ( ) . After ( authCode . Expiry ) || authCode . ClientID != client . ID {
if err != storage . ErrNotFound {
if err != storage . ErrNotFound {
s . logger . Errorf ( "failed to get auth code: %v " , err )
s . logger . Error ( "failed to get auth code" , "err " , err )
s . tokenErrHelper ( w , errServerError , "" , http . StatusInternalServerError )
s . tokenErrHelper ( w , errServerError , "" , http . StatusInternalServerError )
} else {
} else {
s . tokenErrHelper ( w , errInvalidGrant , "Invalid or expired code parameter." , http . StatusBadRequest )
s . tokenErrHelper ( w , errInvalidGrant , "Invalid or expired code parameter." , http . StatusBadRequest )
@ -906,7 +907,7 @@ func (s *Server) handleAuthCode(w http.ResponseWriter, r *http.Request, client s
case providedCodeVerifier != "" && codeChallengeFromStorage != "" :
case providedCodeVerifier != "" && codeChallengeFromStorage != "" :
calculatedCodeChallenge , err := s . calculateCodeChallenge ( providedCodeVerifier , authCode . PKCE . CodeChallengeMethod )
calculatedCodeChallenge , err := s . calculateCodeChallenge ( providedCodeVerifier , authCode . PKCE . CodeChallengeMethod )
if err != nil {
if err != nil {
s . logger . Error ( err )
s . logger . Error ( "failed to calculate code challenge" , "err" , err )
s . tokenErrHelper ( w , errServerError , "" , http . StatusInternalServerError )
s . tokenErrHelper ( w , errServerError , "" , http . StatusInternalServerError )
return
return
}
}
@ -940,20 +941,20 @@ func (s *Server) handleAuthCode(w http.ResponseWriter, r *http.Request, client s
func ( s * Server ) exchangeAuthCode ( ctx context . Context , w http . ResponseWriter , authCode storage . AuthCode , client storage . Client ) ( * accessTokenResponse , error ) {
func ( s * Server ) exchangeAuthCode ( ctx context . Context , w http . ResponseWriter , authCode storage . AuthCode , client storage . Client ) ( * accessTokenResponse , error ) {
accessToken , _ , err := s . newAccessToken ( client . ID , authCode . Claims , authCode . Scopes , authCode . Nonce , authCode . ConnectorID )
accessToken , _ , err := s . newAccessToken ( client . ID , authCode . Claims , authCode . Scopes , authCode . Nonce , authCode . ConnectorID )
if err != nil {
if err != nil {
s . logger . Errorf ( "failed to create new access token: %v " , err )
s . logger . Error ( "failed to create new access token" , "err " , err )
s . tokenErrHelper ( w , errServerError , "" , http . StatusInternalServerError )
s . tokenErrHelper ( w , errServerError , "" , http . StatusInternalServerError )
return nil , err
return nil , err
}
}
idToken , expiry , err := s . newIDToken ( client . ID , authCode . Claims , authCode . Scopes , authCode . Nonce , accessToken , authCode . ID , authCode . ConnectorID )
idToken , expiry , err := s . newIDToken ( client . ID , authCode . Claims , authCode . Scopes , authCode . Nonce , accessToken , authCode . ID , authCode . ConnectorID )
if err != nil {
if err != nil {
s . logger . Errorf ( "failed to create ID token: %v " , err )
s . logger . Error ( "failed to create ID token" , "err " , err )
s . tokenErrHelper ( w , errServerError , "" , http . StatusInternalServerError )
s . tokenErrHelper ( w , errServerError , "" , http . StatusInternalServerError )
return nil , err
return nil , err
}
}
if err := s . storage . DeleteAuthCode ( authCode . ID ) ; err != nil {
if err := s . storage . DeleteAuthCode ( authCode . ID ) ; err != nil {
s . logger . Errorf ( "failed to delete auth code: %v " , err )
s . logger . Error ( "failed to delete auth code" , "err " , err )
s . tokenErrHelper ( w , errServerError , "" , http . StatusInternalServerError )
s . tokenErrHelper ( w , errServerError , "" , http . StatusInternalServerError )
return nil , err
return nil , err
}
}
@ -964,7 +965,7 @@ func (s *Server) exchangeAuthCode(ctx context.Context, w http.ResponseWriter, au
// Connectors like `saml` do not implement RefreshConnector.
// Connectors like `saml` do not implement RefreshConnector.
conn , err := s . getConnector ( authCode . ConnectorID )
conn , err := s . getConnector ( authCode . ConnectorID )
if err != nil {
if err != nil {
s . logger . Errorf ( "connector with ID %q not found: %v " , authCode . ConnectorID , err )
s . logger . Error ( "connector not found" , "connector_id " , authCode . ConnectorID , "err" , err )
s . tokenErrHelper ( w , errServerError , "" , http . StatusInternalServerError )
s . tokenErrHelper ( w , errServerError , "" , http . StatusInternalServerError )
return false
return false
}
}
@ -1000,13 +1001,13 @@ func (s *Server) exchangeAuthCode(ctx context.Context, w http.ResponseWriter, au
Token : refresh . Token ,
Token : refresh . Token ,
}
}
if refreshToken , err = internal . Marshal ( token ) ; err != nil {
if refreshToken , err = internal . Marshal ( token ) ; err != nil {
s . logger . Errorf ( "failed to marshal refresh token: %v " , err )
s . logger . Error ( "failed to marshal refresh token" , "err " , err )
s . tokenErrHelper ( w , errServerError , "" , http . StatusInternalServerError )
s . tokenErrHelper ( w , errServerError , "" , http . StatusInternalServerError )
return nil , err
return nil , err
}
}
if err := s . storage . CreateRefresh ( ctx , refresh ) ; err != nil {
if err := s . storage . CreateRefresh ( ctx , refresh ) ; err != nil {
s . logger . Errorf ( "failed to create refresh token: %v " , err )
s . logger . Error ( "failed to create refresh token" , "err " , err )
s . tokenErrHelper ( w , errServerError , "" , http . StatusInternalServerError )
s . tokenErrHelper ( w , errServerError , "" , http . StatusInternalServerError )
return nil , err
return nil , err
}
}
@ -1019,7 +1020,7 @@ func (s *Server) exchangeAuthCode(ctx context.Context, w http.ResponseWriter, au
if deleteToken {
if deleteToken {
// Delete newly created refresh token from storage.
// Delete newly created refresh token from storage.
if err := s . storage . DeleteRefresh ( refresh . ID ) ; err != nil {
if err := s . storage . DeleteRefresh ( refresh . ID ) ; err != nil {
s . logger . Errorf ( "failed to delete refresh token: %v " , err )
s . logger . Error ( "failed to delete refresh token" , "err " , err )
s . tokenErrHelper ( w , errServerError , "" , http . StatusInternalServerError )
s . tokenErrHelper ( w , errServerError , "" , http . StatusInternalServerError )
return
return
}
}
@ -1036,7 +1037,7 @@ func (s *Server) exchangeAuthCode(ctx context.Context, w http.ResponseWriter, au
// Try to retrieve an existing OfflineSession object for the corresponding user.
// Try to retrieve an existing OfflineSession object for the corresponding user.
if session , err := s . storage . GetOfflineSessions ( refresh . Claims . UserID , refresh . ConnectorID ) ; err != nil {
if session , err := s . storage . GetOfflineSessions ( refresh . Claims . UserID , refresh . ConnectorID ) ; err != nil {
if err != storage . ErrNotFound {
if err != storage . ErrNotFound {
s . logger . Errorf ( "failed to get offline session: %v " , err )
s . logger . Error ( "failed to get offline session" , "err " , err )
s . tokenErrHelper ( w , errServerError , "" , http . StatusInternalServerError )
s . tokenErrHelper ( w , errServerError , "" , http . StatusInternalServerError )
deleteToken = true
deleteToken = true
return nil , err
return nil , err
@ -1051,7 +1052,7 @@ func (s *Server) exchangeAuthCode(ctx context.Context, w http.ResponseWriter, au
// Create a new OfflineSession object for the user and add a reference object for
// Create a new OfflineSession object for the user and add a reference object for
// the newly received refreshtoken.
// the newly received refreshtoken.
if err := s . storage . CreateOfflineSessions ( ctx , offlineSessions ) ; err != nil {
if err := s . storage . CreateOfflineSessions ( ctx , offlineSessions ) ; err != nil {
s . logger . Errorf ( "failed to create offline session: %v " , err )
s . logger . Error ( "failed to create offline session" , "err " , err )
s . tokenErrHelper ( w , errServerError , "" , http . StatusInternalServerError )
s . tokenErrHelper ( w , errServerError , "" , http . StatusInternalServerError )
deleteToken = true
deleteToken = true
return nil , err
return nil , err
@ -1060,7 +1061,7 @@ func (s *Server) exchangeAuthCode(ctx context.Context, w http.ResponseWriter, au
if oldTokenRef , ok := session . Refresh [ tokenRef . ClientID ] ; ok {
if oldTokenRef , ok := session . Refresh [ tokenRef . ClientID ] ; ok {
// Delete old refresh token from storage.
// Delete old refresh token from storage.
if err := s . storage . DeleteRefresh ( oldTokenRef . ID ) ; err != nil && err != storage . ErrNotFound {
if err := s . storage . DeleteRefresh ( oldTokenRef . ID ) ; err != nil && err != storage . ErrNotFound {
s . logger . Errorf ( "failed to delete refresh token: %v " , err )
s . logger . Error ( "failed to delete refresh token" , "err " , err )
s . tokenErrHelper ( w , errServerError , "" , http . StatusInternalServerError )
s . tokenErrHelper ( w , errServerError , "" , http . StatusInternalServerError )
deleteToken = true
deleteToken = true
return nil , err
return nil , err
@ -1072,7 +1073,7 @@ func (s *Server) exchangeAuthCode(ctx context.Context, w http.ResponseWriter, au
old . Refresh [ tokenRef . ClientID ] = & tokenRef
old . Refresh [ tokenRef . ClientID ] = & tokenRef
return old , nil
return old , nil
} ) ; err != nil {
} ) ; err != nil {
s . logger . Errorf ( "failed to update offline session: %v " , err )
s . logger . Error ( "failed to update offline session" , "err " , err )
s . tokenErrHelper ( w , errServerError , "" , http . StatusInternalServerError )
s . tokenErrHelper ( w , errServerError , "" , http . StatusInternalServerError )
deleteToken = true
deleteToken = true
return nil , err
return nil , err
@ -1184,7 +1185,7 @@ func (s *Server) handlePasswordGrant(w http.ResponseWriter, r *http.Request, cli
password := q . Get ( "password" )
password := q . Get ( "password" )
identity , ok , err := passwordConnector . Login ( ctx , parseScopes ( scopes ) , username , password )
identity , ok , err := passwordConnector . Login ( ctx , parseScopes ( scopes ) , username , password )
if err != nil {
if err != nil {
s . logger . Errorf ( "Failed to login user: %v " , err )
s . logger . Error ( "failed to login user" , "err " , err )
s . tokenErrHelper ( w , errInvalidRequest , "Could not login user" , http . StatusBadRequest )
s . tokenErrHelper ( w , errInvalidRequest , "Could not login user" , http . StatusBadRequest )
return
return
}
}
@ -1205,14 +1206,14 @@ func (s *Server) handlePasswordGrant(w http.ResponseWriter, r *http.Request, cli
accessToken , _ , err := s . newAccessToken ( client . ID , claims , scopes , nonce , connID )
accessToken , _ , err := s . newAccessToken ( client . ID , claims , scopes , nonce , connID )
if err != nil {
if err != nil {
s . logger . Errorf ( "password grant failed to create new access token: %v " , err )
s . logger . Error ( "password grant failed to create new access token" , "err " , err )
s . tokenErrHelper ( w , errServerError , "" , http . StatusInternalServerError )
s . tokenErrHelper ( w , errServerError , "" , http . StatusInternalServerError )
return
return
}
}
idToken , expiry , err := s . newIDToken ( client . ID , claims , scopes , nonce , accessToken , "" , connID )
idToken , expiry , err := s . newIDToken ( client . ID , claims , scopes , nonce , accessToken , "" , connID )
if err != nil {
if err != nil {
s . logger . Errorf ( "password grant failed to create new ID token: %v " , err )
s . logger . Error ( "password grant failed to create new ID token" , "err " , err )
s . tokenErrHelper ( w , errServerError , "" , http . StatusInternalServerError )
s . tokenErrHelper ( w , errServerError , "" , http . StatusInternalServerError )
return
return
}
}
@ -1252,13 +1253,13 @@ func (s *Server) handlePasswordGrant(w http.ResponseWriter, r *http.Request, cli
Token : refresh . Token ,
Token : refresh . Token ,
}
}
if refreshToken , err = internal . Marshal ( token ) ; err != nil {
if refreshToken , err = internal . Marshal ( token ) ; err != nil {
s . logger . Errorf ( "failed to marshal refresh token: %v " , err )
s . logger . Error ( "failed to marshal refresh token" , "err " , err )
s . tokenErrHelper ( w , errServerError , "" , http . StatusInternalServerError )
s . tokenErrHelper ( w , errServerError , "" , http . StatusInternalServerError )
return
return
}
}
if err := s . storage . CreateRefresh ( ctx , refresh ) ; err != nil {
if err := s . storage . CreateRefresh ( ctx , refresh ) ; err != nil {
s . logger . Errorf ( "failed to create refresh token: %v " , err )
s . logger . Error ( "failed to create refresh token" , "err " , err )
s . tokenErrHelper ( w , errServerError , "" , http . StatusInternalServerError )
s . tokenErrHelper ( w , errServerError , "" , http . StatusInternalServerError )
return
return
}
}
@ -1271,7 +1272,7 @@ func (s *Server) handlePasswordGrant(w http.ResponseWriter, r *http.Request, cli
if deleteToken {
if deleteToken {
// Delete newly created refresh token from storage.
// Delete newly created refresh token from storage.
if err := s . storage . DeleteRefresh ( refresh . ID ) ; err != nil {
if err := s . storage . DeleteRefresh ( refresh . ID ) ; err != nil {
s . logger . Errorf ( "failed to delete refresh token: %v " , err )
s . logger . Error ( "failed to delete refresh token" , "err " , err )
s . tokenErrHelper ( w , errServerError , "" , http . StatusInternalServerError )
s . tokenErrHelper ( w , errServerError , "" , http . StatusInternalServerError )
return
return
}
}
@ -1288,7 +1289,7 @@ func (s *Server) handlePasswordGrant(w http.ResponseWriter, r *http.Request, cli
// Try to retrieve an existing OfflineSession object for the corresponding user.
// Try to retrieve an existing OfflineSession object for the corresponding user.
if session , err := s . storage . GetOfflineSessions ( refresh . Claims . UserID , refresh . ConnectorID ) ; err != nil {
if session , err := s . storage . GetOfflineSessions ( refresh . Claims . UserID , refresh . ConnectorID ) ; err != nil {
if err != storage . ErrNotFound {
if err != storage . ErrNotFound {
s . logger . Errorf ( "failed to get offline session: %v " , err )
s . logger . Error ( "failed to get offline session" , "err " , err )
s . tokenErrHelper ( w , errServerError , "" , http . StatusInternalServerError )
s . tokenErrHelper ( w , errServerError , "" , http . StatusInternalServerError )
deleteToken = true
deleteToken = true
return
return
@ -1304,7 +1305,7 @@ func (s *Server) handlePasswordGrant(w http.ResponseWriter, r *http.Request, cli
// Create a new OfflineSession object for the user and add a reference object for
// Create a new OfflineSession object for the user and add a reference object for
// the newly received refreshtoken.
// the newly received refreshtoken.
if err := s . storage . CreateOfflineSessions ( ctx , offlineSessions ) ; err != nil {
if err := s . storage . CreateOfflineSessions ( ctx , offlineSessions ) ; err != nil {
s . logger . Errorf ( "failed to create offline session: %v " , err )
s . logger . Error ( "failed to create offline session" , "err " , err )
s . tokenErrHelper ( w , errServerError , "" , http . StatusInternalServerError )
s . tokenErrHelper ( w , errServerError , "" , http . StatusInternalServerError )
deleteToken = true
deleteToken = true
return
return
@ -1314,9 +1315,9 @@ func (s *Server) handlePasswordGrant(w http.ResponseWriter, r *http.Request, cli
// Delete old refresh token from storage.
// Delete old refresh token from storage.
if err := s . storage . DeleteRefresh ( oldTokenRef . ID ) ; err != nil {
if err := s . storage . DeleteRefresh ( oldTokenRef . ID ) ; err != nil {
if err == storage . ErrNotFound {
if err == storage . ErrNotFound {
s . logger . Warnf ( "database inconsistent, refresh token missing: %v " , oldTokenRef . ID )
s . logger . Warn ( "database inconsistent, refresh token missing" , "token_id " , oldTokenRef . ID )
} else {
} else {
s . logger . Errorf ( "failed to delete refresh token: %v " , err )
s . logger . Error ( "failed to delete refresh token" , "err " , err )
s . tokenErrHelper ( w , errServerError , "" , http . StatusInternalServerError )
s . tokenErrHelper ( w , errServerError , "" , http . StatusInternalServerError )
deleteToken = true
deleteToken = true
return
return
@ -1330,7 +1331,7 @@ func (s *Server) handlePasswordGrant(w http.ResponseWriter, r *http.Request, cli
old . ConnectorData = identity . ConnectorData
old . ConnectorData = identity . ConnectorData
return old , nil
return old , nil
} ) ; err != nil {
} ) ; err != nil {
s . logger . Errorf ( "failed to update offline session: %v " , err )
s . logger . Error ( "failed to update offline session" , "err " , err )
s . tokenErrHelper ( w , errServerError , "" , http . StatusInternalServerError )
s . tokenErrHelper ( w , errServerError , "" , http . StatusInternalServerError )
deleteToken = true
deleteToken = true
return
return
@ -1346,7 +1347,7 @@ func (s *Server) handleTokenExchange(w http.ResponseWriter, r *http.Request, cli
ctx := r . Context ( )
ctx := r . Context ( )
if err := r . ParseForm ( ) ; err != nil {
if err := r . ParseForm ( ) ; err != nil {
s . logger . Errorf ( "could not parse request body: %v " , err )
s . logger . Error ( "could not parse request body" , "err " , err )
s . tokenErrHelper ( w , errInvalidRequest , "" , http . StatusBadRequest )
s . tokenErrHelper ( w , errInvalidRequest , "" , http . StatusBadRequest )
return
return
}
}
@ -1375,19 +1376,19 @@ func (s *Server) handleTokenExchange(w http.ResponseWriter, r *http.Request, cli
conn , err := s . getConnector ( connID )
conn , err := s . getConnector ( connID )
if err != nil {
if err != nil {
s . logger . Errorf ( "failed to get connector: %v " , err )
s . logger . Error ( "failed to get connector" , "err " , err )
s . tokenErrHelper ( w , errInvalidRequest , "Requested connector does not exist." , http . StatusBadRequest )
s . tokenErrHelper ( w , errInvalidRequest , "Requested connector does not exist." , http . StatusBadRequest )
return
return
}
}
teConn , ok := conn . Connector . ( connector . TokenIdentityConnector )
teConn , ok := conn . Connector . ( connector . TokenIdentityConnector )
if ! ok {
if ! ok {
s . logger . Errorf ( "connector doesn't implement token exchange: %v " , connID )
s . logger . Error ( "connector doesn't implement token exchange" , "connector_id " , connID )
s . tokenErrHelper ( w , errInvalidRequest , "Requested connector does not exist." , http . StatusBadRequest )
s . tokenErrHelper ( w , errInvalidRequest , "Requested connector does not exist." , http . StatusBadRequest )
return
return
}
}
identity , err := teConn . TokenIdentity ( ctx , subjectTokenType , subjectToken )
identity , err := teConn . TokenIdentity ( ctx , subjectTokenType , subjectToken )
if err != nil {
if err != nil {
s . logger . Errorf ( "failed to verify subject token: %v " , err )
s . logger . Error ( "failed to verify subject token" , "err " , err )
s . tokenErrHelper ( w , errAccessDenied , "" , http . StatusUnauthorized )
s . tokenErrHelper ( w , errAccessDenied , "" , http . StatusUnauthorized )
return
return
}
}
@ -1415,7 +1416,7 @@ func (s *Server) handleTokenExchange(w http.ResponseWriter, r *http.Request, cli
return
return
}
}
if err != nil {
if err != nil {
s . logger . Errorf ( "token exchange failed to create new %v token: %v " , requestedTokenType , err )
s . logger . Error ( "token exchange failed to create new token" , "requested_token_type " , requestedTokenType , "err" , err )
s . tokenErrHelper ( w , errServerError , "" , http . StatusInternalServerError )
s . tokenErrHelper ( w , errServerError , "" , http . StatusInternalServerError )
return
return
}
}
@ -1451,7 +1452,7 @@ func (s *Server) toAccessTokenResponse(idToken, accessToken, refreshToken string
func ( s * Server ) writeAccessToken ( w http . ResponseWriter , resp * accessTokenResponse ) {
func ( s * Server ) writeAccessToken ( w http . ResponseWriter , resp * accessTokenResponse ) {
data , err := json . Marshal ( resp )
data , err := json . Marshal ( resp )
if err != nil {
if err != nil {
s . logger . Errorf ( "failed to marshal access token response: %v " , err )
s . logger . Error ( "failed to marshal access token response" , "err " , err )
s . tokenErrHelper ( w , errServerError , "" , http . StatusInternalServerError )
s . tokenErrHelper ( w , errServerError , "" , http . StatusInternalServerError )
return
return
}
}
@ -1466,13 +1467,13 @@ func (s *Server) writeAccessToken(w http.ResponseWriter, resp *accessTokenRespon
func ( s * Server ) renderError ( r * http . Request , w http . ResponseWriter , status int , description string ) {
func ( s * Server ) renderError ( r * http . Request , w http . ResponseWriter , status int , description string ) {
if err := s . templates . err ( r , w , status , description ) ; err != nil {
if err := s . templates . err ( r , w , status , description ) ; err != nil {
s . logger . Errorf ( "server template error: %v " , err )
s . logger . Error ( "server template error" , "err " , err )
}
}
}
}
func ( s * Server ) tokenErrHelper ( w http . ResponseWriter , typ string , description string , statusCode int ) {
func ( s * Server ) tokenErrHelper ( w http . ResponseWriter , typ string , description string , statusCode int ) {
if err := tokenErr ( w , typ , description , statusCode ) ; err != nil {
if err := tokenErr ( w , typ , description , statusCode ) ; err != nil {
s . logger . Errorf ( "token error response: %v " , err )
s . logger . Error ( "token error response" , "err " , err )
}
}
}
}