Skip to content

Commit

Permalink
add redirect uri to oidc and oauth2 configs, fix apps and orgs cache …
Browse files Browse the repository at this point in the history
…update bug, add examples to API docs [#523]
  • Loading branch information
roberlander2 committed Aug 23, 2022
1 parent 78cd45a commit 2a42383
Show file tree
Hide file tree
Showing 16 changed files with 208 additions and 60 deletions.
10 changes: 5 additions & 5 deletions .secrets.baseline
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@
"filename": "core/auth/apis.go",
"hashed_secret": "4d55af37dbbb6a42088d917caa1ca25428ec42c9",
"is_verified": false,
"line_number": 1938
"line_number": 1937
}
],
"core/auth/auth.go": [
Expand Down Expand Up @@ -193,7 +193,7 @@
"filename": "core/auth/auth_type_oauth2.go",
"hashed_secret": "15a46c63d80cdc62bb7e988a24b5839ecb624e25",
"is_verified": false,
"line_number": 283
"line_number": 282
}
],
"core/auth/auth_type_oidc.go": [
Expand All @@ -202,7 +202,7 @@
"filename": "core/auth/auth_type_oidc.go",
"hashed_secret": "0ade4f3edccc8888bef404fe6b3c92c13cdfad6b",
"is_verified": false,
"line_number": 377
"line_number": 369
}
],
"driven/emailer/adapter.go": [
Expand All @@ -229,7 +229,7 @@
"filename": "driver/web/docs/gen/def.yaml",
"hashed_secret": "dd29ecf524b030a65261e3059c48ab9e1ecb2585",
"is_verified": false,
"line_number": 1376
"line_number": 1429
}
],
"driver/web/docs/resources/services/application/configs.yaml": [
Expand Down Expand Up @@ -288,5 +288,5 @@
}
]
},
"generated_at": "2022-08-23T18:15:51Z"
"generated_at": "2022-08-23T19:36:01Z"
}
5 changes: 2 additions & 3 deletions core/auth/apis.go
Original file line number Diff line number Diff line change
Expand Up @@ -419,13 +419,12 @@ func (a *Auth) Refresh(refreshToken string, apiKey string, l *logs.Log) (*model.
// authenticationType (string): Name of the authentication method for provided creds (eg. "email", "username", "illinois_oidc")
// appTypeIdentifier (string): Identifier of the app type/client that the user is logging in from
// orgID (string): ID of the organization that the user is logging in
// redirectURI (string): Registered redirect URI where client will receive response
// apiKey (string): API key to validate the specified app
// l (*loglib.Log): Log object pointer for request
// Returns:
// Login URL (string): SSO provider login URL to be launched in a browser
// Params (map[string]interface{}): Params to be sent in subsequent request (if necessary)
func (a *Auth) GetLoginURL(authenticationType string, appTypeIdentifier string, orgID string, redirectURI string, apiKey string, l *logs.Log) (string, map[string]interface{}, error) {
func (a *Auth) GetLoginURL(authenticationType string, appTypeIdentifier string, orgID string, apiKey string, l *logs.Log) (string, map[string]interface{}, error) {
//validate if the provided auth type is supported by the provided application and organization
authType, appType, _, err := a.validateAuthType(authenticationType, appTypeIdentifier, orgID)
if err != nil {
Expand All @@ -445,7 +444,7 @@ func (a *Auth) GetLoginURL(authenticationType string, appTypeIdentifier string,
}

//get login URL
loginURL, params, err := authImpl.getLoginURL(*authType, *appType, redirectURI, l)
loginURL, params, err := authImpl.getLoginURL(*authType, *appType, l)
if err != nil {
return "", nil, errors.WrapErrorAction(logutils.ActionGet, "login url", nil, err)
}
Expand Down
15 changes: 7 additions & 8 deletions core/auth/auth_type_oauth2.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ type oauth2AuthImpl struct {

type oauth2AuthConfig struct {
Host string `json:"host" validate:"required"`
RedirectURI string `json:"redirect_uri" validate:"required"`
AuthorizeURL string `json:"authorize_url"`
TokenURL string `json:"token_url"`
UserInfoURL string `json:"userinfo_url"`
Expand Down Expand Up @@ -139,23 +140,20 @@ func (a *oauth2AuthImpl) refresh(params map[string]interface{}, authType model.A
return a.refreshToken(authType, appType, appOrg, refreshParams, oauth2Config, l)
}

func (a *oauth2AuthImpl) getLoginURL(authType model.AuthType, appType model.ApplicationType, redirectURI string, l *logs.Log) (string, map[string]interface{}, error) {
func (a *oauth2AuthImpl) getLoginURL(authType model.AuthType, appType model.ApplicationType, l *logs.Log) (string, map[string]interface{}, error) {
oauth2Config, err := a.getOAuth2AuthConfig(authType, appType)
if err != nil {
return "", nil, errors.WrapErrorAction(logutils.ActionGet, typeOAuth2AuthConfig, nil, err)
}

responseParams := map[string]interface{}{
"redirect_uri": redirectURI,
}

bodyData := map[string]string{
"client_id": oauth2Config.ClientID,
"redirect_uri": redirectURI,
"redirect_uri": oauth2Config.RedirectURI,
"scope": oauth2Config.Scopes,
"allow_signup": strconv.FormatBool(oauth2Config.AllowSignUp),
}

responseParams := make(map[string]interface{})
if oauth2Config.UseState {
state, err := generateState()
if err != nil {
Expand All @@ -179,8 +177,9 @@ func (a *oauth2AuthImpl) getLoginURL(authType model.AuthType, appType model.Appl

func (a *oauth2AuthImpl) newToken(code string, authType model.AuthType, appType model.ApplicationType, appOrg model.ApplicationOrganization, oauth2Config *oauth2AuthConfig, l *logs.Log) (*model.ExternalSystemUser, map[string]interface{}, error) {
bodyData := map[string]string{
"client_id": oauth2Config.ClientID,
"code": code,
"client_id": oauth2Config.ClientID,
"code": code,
"redirect_uri": oauth2Config.RedirectURI,
}

return a.loadOAuth2TokensAndInfo(bodyData, oauth2Config, authType, appType, appOrg, l)
Expand Down
26 changes: 9 additions & 17 deletions core/auth/auth_type_oidc.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ type oidcAuthImpl struct {

type oidcAuthConfig struct {
Host string `json:"host" validate:"required"`
RedirectURI string `json:"redirect_uri" validate:"required"`
AuthorizeURL string `json:"authorize_url"`
TokenURL string `json:"token_url"`
UserInfoURL string `json:"userinfo_url"`
Expand Down Expand Up @@ -84,7 +85,6 @@ type oidcToken struct {

type oidcRefreshParams struct {
RefreshToken string `json:"refresh_token" bson:"refresh_token" validate:"required"`
RedirectURI string `json:"redirect_uri" bson:"redirect_uri" validate:"required"`
}

func oidcRefreshParamsFromMap(val map[string]interface{}) (*oidcRefreshParams, error) {
Expand All @@ -97,12 +97,8 @@ func oidcRefreshParamsFromMap(val map[string]interface{}) (*oidcRefreshParams, e
if !ok {
return nil, errors.ErrorData(logutils.StatusMissing, "refresh token", nil)
}
redirectURI, ok := val["redirect_uri"].(string)
if !ok {
return nil, errors.ErrorData(logutils.StatusMissing, "redirect uri", nil)
}

return &oidcRefreshParams{RefreshToken: refreshToken, RedirectURI: redirectURI}, nil
return &oidcRefreshParams{RefreshToken: refreshToken}, nil
}

func (a *oidcAuthImpl) externalLogin(authType model.AuthType, appType model.ApplicationType, appOrg model.ApplicationOrganization, creds string, params string, l *logs.Log) (*model.ExternalSystemUser, map[string]interface{}, error) {
Expand Down Expand Up @@ -150,16 +146,12 @@ func (a *oidcAuthImpl) refresh(params map[string]interface{}, authType model.Aut
return a.refreshToken(authType, appType, appOrg, refreshParams, oidcConfig, l)
}

func (a *oidcAuthImpl) getLoginURL(authType model.AuthType, appType model.ApplicationType, redirectURI string, l *logs.Log) (string, map[string]interface{}, error) {
func (a *oidcAuthImpl) getLoginURL(authType model.AuthType, appType model.ApplicationType, l *logs.Log) (string, map[string]interface{}, error) {
oidcConfig, err := a.getOidcAuthConfig(authType, appType)
if err != nil {
return "", nil, errors.WrapErrorAction(logutils.ActionGet, typeOidcAuthConfig, nil, err)
}

responseParams := map[string]interface{}{
"redirect_uri": redirectURI,
}

scopes := oidcConfig.Scopes
if len(scopes) == 0 {
scopes = "openid profile email offline_access"
Expand All @@ -168,14 +160,15 @@ func (a *oidcAuthImpl) getLoginURL(authType model.AuthType, appType model.Applic
bodyData := map[string]string{
"scope": scopes,
"response_type": "code",
"redirect_uri": redirectURI,
"redirect_uri": oidcConfig.RedirectURI,
"client_id": oidcConfig.ClientID,
}

if len(oidcConfig.AuthorizeClaims) > 0 {
bodyData["claims"] = oidcConfig.AuthorizeClaims
}

responseParams := make(map[string]interface{})
if oidcConfig.UsePKCE {
codeChallenge, codeVerifier, err := generatePkceChallenge()
if err != nil {
Expand Down Expand Up @@ -246,7 +239,7 @@ func (a *oidcAuthImpl) newToken(code string, authType model.AuthType, appType mo
bodyData["code_verifier"] = params.CodeVerifier
}

return a.loadOidcTokensAndInfo(bodyData, oidcConfig, authType, appType, appOrg, params.RedirectURI, l)
return a.loadOidcTokensAndInfo(bodyData, oidcConfig, authType, appType, appOrg, l)
}

func (a *oidcAuthImpl) refreshToken(authType model.AuthType, appType model.ApplicationType, appOrg model.ApplicationOrganization,
Expand All @@ -259,15 +252,15 @@ func (a *oidcAuthImpl) refreshToken(authType model.AuthType, appType model.Appli
bodyData := map[string]string{
"refresh_token": params.RefreshToken,
"grant_type": "refresh_token",
"redirect_uri": params.RedirectURI,
"redirect_uri": oidcConfig.RedirectURI,
"client_id": oidcConfig.ClientID,
}

return a.loadOidcTokensAndInfo(bodyData, oidcConfig, authType, appType, appOrg, params.RedirectURI, l)
return a.loadOidcTokensAndInfo(bodyData, oidcConfig, authType, appType, appOrg, l)
}

func (a *oidcAuthImpl) loadOidcTokensAndInfo(bodyData map[string]string, oidcConfig *oidcAuthConfig, authType model.AuthType, appType model.ApplicationType,
appOrg model.ApplicationOrganization, redirectURI string, l *logs.Log) (*model.ExternalSystemUser, map[string]interface{}, error) {
appOrg model.ApplicationOrganization, l *logs.Log) (*model.ExternalSystemUser, map[string]interface{}, error) {
token, err := a.loadOidcTokenWithParams(bodyData, oidcConfig)
if err != nil {
return nil, nil, errors.WrapErrorAction(logutils.ActionGet, typeOidcToken, nil, err)
Expand Down Expand Up @@ -359,7 +352,6 @@ func (a *oidcAuthImpl) loadOidcTokensAndInfo(bodyData map[string]string, oidcCon

params := map[string]interface{}{}
params["oidc_token"] = oidcParams
params["redirect_uri"] = redirectURI
return &externalUser, params, nil
}

Expand Down
2 changes: 1 addition & 1 deletion core/auth/auth_type_saml.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ func (a *samlAuthImpl) externalLogin(authType model.AuthType, appType model.Appl
return nil, nil, nil
}

func (a *samlAuthImpl) getLoginURL(authType model.AuthType, appType model.ApplicationType, redirectURI string, l *logs.Log) (string, map[string]interface{}, error) {
func (a *samlAuthImpl) getLoginURL(authType model.AuthType, appType model.ApplicationType, l *logs.Log) (string, map[string]interface{}, error) {
return "", nil, errors.Newf("get login url operation invalid for auth_type=%s", a.authType)
}

Expand Down
5 changes: 2 additions & 3 deletions core/auth/interfaces.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ type authType interface {
// these are the different identity providers - illinois_oidc etc
type externalAuthType interface {
//getLoginUrl retrieves and pre-formats a login url and params for the SSO provider
getLoginURL(authType model.AuthType, appType model.ApplicationType, redirectURI string, l *logs.Log) (string, map[string]interface{}, error)
getLoginURL(authType model.AuthType, appType model.ApplicationType, l *logs.Log) (string, map[string]interface{}, error)
//externalLogin logins in the external system and provides the authenticated user
externalLogin(authType model.AuthType, appType model.ApplicationType, appOrg model.ApplicationOrganization, creds string, params string, l *logs.Log) (*model.ExternalSystemUser, map[string]interface{}, error)
//refresh refreshes tokens
Expand Down Expand Up @@ -203,13 +203,12 @@ type APIs interface {
// authType (string): Name of the authentication method for provided creds (eg. "email", "username", "illinois_oidc")
// appTypeIdentifier (string): Identifier of the app type/client that the user is logging in from
// orgID (string): ID of the organization that the user is logging in
// redirectURI (string): Registered redirect URI where client will receive response
// apiKey (string): API key to validate the specified app
// l (*loglib.Log): Log object pointer for request
// Returns:
// Login URL (string): SSO provider login URL to be launched in a browser
// Params (map[string]interface{}): Params to be sent in subsequent request (if necessary)
GetLoginURL(authType string, appTypeIdentifier string, orgID string, redirectURI string, apiKey string, l *logs.Log) (string, map[string]interface{}, error)
GetLoginURL(authType string, appTypeIdentifier string, orgID string, apiKey string, l *logs.Log) (string, map[string]interface{}, error)

//LoginMFA verifies a code sent by a user as a final login step for enrolled accounts.
//The MFA type must be one of the supported for the application.
Expand Down
5 changes: 2 additions & 3 deletions driven/storage/adapter.go
Original file line number Diff line number Diff line change
Expand Up @@ -3316,16 +3316,15 @@ func (sl *storageListener) OnServiceRegsUpdated() {

func (sl *storageListener) OnOrganizationsUpdated() {
sl.adapter.cacheOrganizations()
sl.adapter.cacheApplicationsOrganizations()
}

func (sl *storageListener) OnApplicationsUpdated() {
sl.adapter.cacheApplications()
sl.adapter.cacheOrganizations()
sl.adapter.cacheApplicationsOrganizations()
}

func (sl *storageListener) OnApplicationsOrganizationsUpdated() {
sl.adapter.cacheApplications()
sl.adapter.cacheOrganizations()
sl.adapter.cacheApplicationsOrganizations()
}

Expand Down
2 changes: 1 addition & 1 deletion driver/web/apis_admin.go
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,7 @@ func (h AdminApisHandler) loginURL(l *logs.Log, r *http.Request, claims *tokenau
return l.HttpResponseErrorAction(logutils.ActionUnmarshal, "auth login url request", nil, err, http.StatusBadRequest, true)
}

loginURL, params, err := h.coreAPIs.Auth.GetLoginURL(string(requestData.AuthType), requestData.AppTypeIdentifier, requestData.OrgId, requestData.RedirectUri, requestData.ApiKey, l)
loginURL, params, err := h.coreAPIs.Auth.GetLoginURL(string(requestData.AuthType), requestData.AppTypeIdentifier, requestData.OrgId, requestData.ApiKey, l)
if err != nil {
return l.HttpResponseErrorAction(logutils.ActionGet, "login url", nil, err, http.StatusInternalServerError, true)
}
Expand Down
2 changes: 1 addition & 1 deletion driver/web/apis_services.go
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,7 @@ func (h ServicesApisHandler) loginURL(l *logs.Log, r *http.Request, claims *toke
return l.HttpResponseErrorAction(logutils.ActionUnmarshal, "auth login url request", nil, err, http.StatusBadRequest, true)
}

loginURL, params, err := h.coreAPIs.Auth.GetLoginURL(string(requestData.AuthType), requestData.AppTypeIdentifier, requestData.OrgId, requestData.RedirectUri, requestData.ApiKey, l)
loginURL, params, err := h.coreAPIs.Auth.GetLoginURL(string(requestData.AuthType), requestData.AppTypeIdentifier, requestData.OrgId, requestData.ApiKey, l)
if err != nil {
return l.HttpResponseErrorAction(logutils.ActionGet, "login url", nil, err, http.StatusInternalServerError, true)
}
Expand Down

0 comments on commit 2a42383

Please sign in to comment.