Skip to content

Commit

Permalink
fix: allow start and retrieve IdP intents with IdPs from other organi…
Browse files Browse the repository at this point in the history
…zations (#7871)

* fix: correct resourceowner of intent to instance

* fix: correct resourceowner of intent to instance

* fix: correct resourceowner of intent to instance

* fix: correct resourceowner of intent to instance

* fix: correct resourceowner of intent to instance

* docs: expand the login example with org specific parameters

* fix: existence of idp is not checked through resourceowner

* fix: existence of idp is not checked through resourceowner

* fix: existence of idp is not checked through resourceowner

---------

Co-authored-by: Livio Spring <livio.a@gmail.com>
  • Loading branch information
stebenz and livio-a committed May 7, 2024
1 parent 5bf195d commit 72c5b05
Show file tree
Hide file tree
Showing 13 changed files with 438 additions and 155 deletions.
2 changes: 1 addition & 1 deletion internal/api/grpc/org/v2/org_integration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ func TestMain(m *testing.M) {
}

func TestServer_AddOrganization(t *testing.T) {
idpID := Tester.AddGenericOAuthProvider(t)
idpID := Tester.AddGenericOAuthProvider(t, CTX)

tests := []struct {
name string
Expand Down
18 changes: 9 additions & 9 deletions internal/api/grpc/session/v2/session_integration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -361,8 +361,7 @@ func TestServer_CreateSession_webauthn(t *testing.T) {
}

func TestServer_CreateSession_successfulIntent(t *testing.T) {
idpID := Tester.AddGenericOAuthProvider(t)

idpID := Tester.AddGenericOAuthProvider(t, CTX)
createResp, err := Client.CreateSession(CTX, &session.CreateSessionRequest{
Checks: &session.Checks{
User: &session.CheckUser{
Expand All @@ -375,7 +374,7 @@ func TestServer_CreateSession_successfulIntent(t *testing.T) {
require.NoError(t, err)
verifyCurrentSession(t, createResp.GetSessionId(), createResp.GetSessionToken(), createResp.GetDetails().GetSequence(), time.Minute, nil, nil, 0)

intentID, token, _, _ := Tester.CreateSuccessfulOAuthIntent(t, idpID, User.GetUserId(), "id")
intentID, token, _, _ := Tester.CreateSuccessfulOAuthIntent(t, CTX, idpID, User.GetUserId(), "id")
updateResp, err := Client.SetSession(CTX, &session.SetSessionRequest{
SessionId: createResp.GetSessionId(),
SessionToken: createResp.GetSessionToken(),
Expand All @@ -391,9 +390,9 @@ func TestServer_CreateSession_successfulIntent(t *testing.T) {
}

func TestServer_CreateSession_successfulIntent_instant(t *testing.T) {
idpID := Tester.AddGenericOAuthProvider(t)
idpID := Tester.AddGenericOAuthProvider(t, CTX)

intentID, token, _, _ := Tester.CreateSuccessfulOAuthIntent(t, idpID, User.GetUserId(), "id")
intentID, token, _, _ := Tester.CreateSuccessfulOAuthIntent(t, CTX, idpID, User.GetUserId(), "id")
createResp, err := Client.CreateSession(CTX, &session.CreateSessionRequest{
Checks: &session.Checks{
User: &session.CheckUser{
Expand All @@ -412,7 +411,7 @@ func TestServer_CreateSession_successfulIntent_instant(t *testing.T) {
}

func TestServer_CreateSession_successfulIntentUnknownUserID(t *testing.T) {
idpID := Tester.AddGenericOAuthProvider(t)
idpID := Tester.AddGenericOAuthProvider(t, CTX)

createResp, err := Client.CreateSession(CTX, &session.CreateSessionRequest{
Checks: &session.Checks{
Expand All @@ -427,7 +426,7 @@ func TestServer_CreateSession_successfulIntentUnknownUserID(t *testing.T) {
verifyCurrentSession(t, createResp.GetSessionId(), createResp.GetSessionToken(), createResp.GetDetails().GetSequence(), time.Minute, nil, nil, 0)

idpUserID := "id"
intentID, token, _, _ := Tester.CreateSuccessfulOAuthIntent(t, idpID, "", idpUserID)
intentID, token, _, _ := Tester.CreateSuccessfulOAuthIntent(t, CTX, idpID, "", idpUserID)
updateResp, err := Client.SetSession(CTX, &session.SetSessionRequest{
SessionId: createResp.GetSessionId(),
SessionToken: createResp.GetSessionToken(),
Expand All @@ -440,6 +439,7 @@ func TestServer_CreateSession_successfulIntentUnknownUserID(t *testing.T) {
})
require.Error(t, err)
Tester.CreateUserIDPlink(CTX, User.GetUserId(), idpUserID, idpID, User.GetUserId())
intentID, token, _, _ = Tester.CreateSuccessfulOAuthIntent(t, CTX, idpID, User.GetUserId(), idpUserID)
updateResp, err = Client.SetSession(CTX, &session.SetSessionRequest{
SessionId: createResp.GetSessionId(),
SessionToken: createResp.GetSessionToken(),
Expand All @@ -455,7 +455,7 @@ func TestServer_CreateSession_successfulIntentUnknownUserID(t *testing.T) {
}

func TestServer_CreateSession_startedIntentFalseToken(t *testing.T) {
idpID := Tester.AddGenericOAuthProvider(t)
idpID := Tester.AddGenericOAuthProvider(t, CTX)

createResp, err := Client.CreateSession(CTX, &session.CreateSessionRequest{
Checks: &session.Checks{
Expand All @@ -469,7 +469,7 @@ func TestServer_CreateSession_startedIntentFalseToken(t *testing.T) {
require.NoError(t, err)
verifyCurrentSession(t, createResp.GetSessionId(), createResp.GetSessionToken(), createResp.GetDetails().GetSequence(), time.Minute, nil, nil, 0)

intentID := Tester.CreateIntent(t, idpID)
intentID := Tester.CreateIntent(t, CTX, idpID)
_, err = Client.SetSession(CTX, &session.SetSessionRequest{
SessionId: createResp.GetSessionId(),
SessionToken: createResp.GetSessionToken(),
Expand Down
8 changes: 4 additions & 4 deletions internal/api/grpc/user/v2/user.go
Original file line number Diff line number Diff line change
Expand Up @@ -370,7 +370,7 @@ func (s *Server) StartIdentityProviderIntent(ctx context.Context, req *user.Star
}

func (s *Server) startIDPIntent(ctx context.Context, idpID string, urls *user.RedirectURLs) (*user.StartIdentityProviderIntentResponse, error) {
intentWriteModel, details, err := s.command.CreateIntent(ctx, idpID, urls.GetSuccessUrl(), urls.GetFailureUrl(), authz.GetCtxData(ctx).OrgID)
intentWriteModel, details, err := s.command.CreateIntent(ctx, idpID, urls.GetSuccessUrl(), urls.GetFailureUrl(), authz.GetInstance(ctx).InstanceID())
if err != nil {
return nil, err
}
Expand All @@ -394,7 +394,7 @@ func (s *Server) startIDPIntent(ctx context.Context, idpID string, urls *user.Re
}

func (s *Server) startLDAPIntent(ctx context.Context, idpID string, ldapCredentials *user.LDAPCredentials) (*user.StartIdentityProviderIntentResponse, error) {
intentWriteModel, details, err := s.command.CreateIntent(ctx, idpID, "", "", authz.GetCtxData(ctx).OrgID)
intentWriteModel, details, err := s.command.CreateIntent(ctx, idpID, "", "", authz.GetInstance(ctx).InstanceID())
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -473,15 +473,15 @@ func (s *Server) ldapLogin(ctx context.Context, idpID, username, password string
}

func (s *Server) RetrieveIdentityProviderIntent(ctx context.Context, req *user.RetrieveIdentityProviderIntentRequest) (_ *user.RetrieveIdentityProviderIntentResponse, err error) {
intent, err := s.command.GetIntentWriteModel(ctx, req.GetIdpIntentId(), authz.GetCtxData(ctx).OrgID)
intent, err := s.command.GetIntentWriteModel(ctx, req.GetIdpIntentId(), "")
if err != nil {
return nil, err
}
if err := s.checkIntentToken(req.GetIdpIntentToken(), intent.AggregateID); err != nil {
return nil, err
}
if intent.State != domain.IDPIntentStateSucceeded {
return nil, zerrors.ThrowPreconditionFailed(nil, "IDP-Hk38e", "Errors.Intent.NotSucceeded")
return nil, zerrors.ThrowPreconditionFailed(nil, "IDP-nme4gszsvx", "Errors.Intent.NotSucceeded")
}
return idpIntentToIDPIntentPb(intent, s.idpAlg)
}
Expand Down
146 changes: 121 additions & 25 deletions internal/api/grpc/user/v2/user_integration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ func TestMain(m *testing.M) {
}

func TestServer_AddHumanUser(t *testing.T) {
idpID := Tester.AddGenericOAuthProvider(t)
idpID := Tester.AddGenericOAuthProvider(t, CTX)
type args struct {
ctx context.Context
req *user.AddHumanUserRequest
Expand Down Expand Up @@ -1752,7 +1752,7 @@ func TestServer_DeleteUser(t *testing.T) {
}

func TestServer_AddIDPLink(t *testing.T) {
idpID := Tester.AddGenericOAuthProvider(t)
idpID := Tester.AddGenericOAuthProvider(t, CTX)
type args struct {
ctx context.Context
req *user.AddIDPLinkRequest
Expand Down Expand Up @@ -1832,10 +1832,13 @@ func TestServer_AddIDPLink(t *testing.T) {
}

func TestServer_StartIdentityProviderIntent(t *testing.T) {
idpID := Tester.AddGenericOAuthProvider(t)
samlIdpID := Tester.AddSAMLProvider(t)
samlRedirectIdpID := Tester.AddSAMLRedirectProvider(t)
samlPostIdpID := Tester.AddSAMLPostProvider(t)
idpID := Tester.AddGenericOAuthProvider(t, CTX)
orgIdpID := Tester.AddOrgGenericOAuthProvider(t, CTX, Tester.Organisation.ID)
orgResp := Tester.CreateOrganization(IamCTX, fmt.Sprintf("NotDefaultOrg%d", time.Now().UnixNano()), fmt.Sprintf("%d@mouse.com", time.Now().UnixNano()))
notDefaultOrgIdpID := Tester.AddOrgGenericOAuthProvider(t, CTX, orgResp.OrganizationId)
samlIdpID := Tester.AddSAMLProvider(t, CTX)
samlRedirectIdpID := Tester.AddSAMLRedirectProvider(t, CTX)
samlPostIdpID := Tester.AddSAMLPostProvider(t, CTX)
type args struct {
ctx context.Context
req *user.StartIdentityProviderIntentRequest
Expand Down Expand Up @@ -1880,7 +1883,100 @@ func TestServer_StartIdentityProviderIntent(t *testing.T) {
want: want{
details: &object.Details{
ChangeDate: timestamppb.Now(),
ResourceOwner: Tester.Organisation.ID,
ResourceOwner: Tester.Instance.InstanceID(),
},
url: "https://example.com/oauth/v2/authorize",
parametersEqual: map[string]string{
"client_id": "clientID",
"prompt": "select_account",
"redirect_uri": "http://" + Tester.Config.ExternalDomain + ":8080/idps/callback",
"response_type": "code",
"scope": "openid profile email",
},
parametersExisting: []string{"state"},
},
wantErr: false,
},
{
name: "next step oauth auth url, default org",
args: args{
CTX,
&user.StartIdentityProviderIntentRequest{
IdpId: orgIdpID,
Content: &user.StartIdentityProviderIntentRequest_Urls{
Urls: &user.RedirectURLs{
SuccessUrl: "https://example.com/success",
FailureUrl: "https://example.com/failure",
},
},
},
},
want: want{
details: &object.Details{
ChangeDate: timestamppb.Now(),
ResourceOwner: Tester.Instance.InstanceID(),
},
url: "https://example.com/oauth/v2/authorize",
parametersEqual: map[string]string{
"client_id": "clientID",
"prompt": "select_account",
"redirect_uri": "http://" + Tester.Config.ExternalDomain + ":8080/idps/callback",
"response_type": "code",
"scope": "openid profile email",
},
parametersExisting: []string{"state"},
},
wantErr: false,
},
{
name: "next step oauth auth url, default org",
args: args{
CTX,
&user.StartIdentityProviderIntentRequest{
IdpId: notDefaultOrgIdpID,
Content: &user.StartIdentityProviderIntentRequest_Urls{
Urls: &user.RedirectURLs{
SuccessUrl: "https://example.com/success",
FailureUrl: "https://example.com/failure",
},
},
},
},
want: want{
details: &object.Details{
ChangeDate: timestamppb.Now(),
ResourceOwner: Tester.Instance.InstanceID(),
},
url: "https://example.com/oauth/v2/authorize",
parametersEqual: map[string]string{
"client_id": "clientID",
"prompt": "select_account",
"redirect_uri": "http://" + Tester.Config.ExternalDomain + ":8080/idps/callback",
"response_type": "code",
"scope": "openid profile email",
},
parametersExisting: []string{"state"},
},
wantErr: false,
},
{
name: "next step oauth auth url org",
args: args{
CTX,
&user.StartIdentityProviderIntentRequest{
IdpId: orgIdpID,
Content: &user.StartIdentityProviderIntentRequest_Urls{
Urls: &user.RedirectURLs{
SuccessUrl: "https://example.com/success",
FailureUrl: "https://example.com/failure",
},
},
},
},
want: want{
details: &object.Details{
ChangeDate: timestamppb.Now(),
ResourceOwner: Tester.Instance.InstanceID(),
},
url: "https://example.com/oauth/v2/authorize",
parametersEqual: map[string]string{
Expand Down Expand Up @@ -1911,7 +2007,7 @@ func TestServer_StartIdentityProviderIntent(t *testing.T) {
want: want{
details: &object.Details{
ChangeDate: timestamppb.Now(),
ResourceOwner: Tester.Organisation.ID,
ResourceOwner: Tester.Instance.InstanceID(),
},
url: "http://" + Tester.Config.ExternalDomain + ":8000/sso",
parametersExisting: []string{"RelayState", "SAMLRequest"},
Expand All @@ -1935,7 +2031,7 @@ func TestServer_StartIdentityProviderIntent(t *testing.T) {
want: want{
details: &object.Details{
ChangeDate: timestamppb.Now(),
ResourceOwner: Tester.Organisation.ID,
ResourceOwner: Tester.Instance.InstanceID(),
},
url: "http://" + Tester.Config.ExternalDomain + ":8000/sso",
parametersExisting: []string{"RelayState", "SAMLRequest"},
Expand All @@ -1959,7 +2055,7 @@ func TestServer_StartIdentityProviderIntent(t *testing.T) {
want: want{
details: &object.Details{
ChangeDate: timestamppb.Now(),
ResourceOwner: Tester.Organisation.ID,
ResourceOwner: Tester.Instance.InstanceID(),
},
postForm: true,
},
Expand Down Expand Up @@ -1999,13 +2095,13 @@ func TestServer_StartIdentityProviderIntent(t *testing.T) {
}

func TestServer_RetrieveIdentityProviderIntent(t *testing.T) {
idpID := Tester.AddGenericOAuthProvider(t)
intentID := Tester.CreateIntent(t, idpID)
successfulID, token, changeDate, sequence := Tester.CreateSuccessfulOAuthIntent(t, idpID, "", "id")
successfulWithUserID, WithUsertoken, WithUserchangeDate, WithUsersequence := Tester.CreateSuccessfulOAuthIntent(t, idpID, "user", "id")
ldapSuccessfulID, ldapToken, ldapChangeDate, ldapSequence := Tester.CreateSuccessfulLDAPIntent(t, idpID, "", "id")
ldapSuccessfulWithUserID, ldapWithUserToken, ldapWithUserChangeDate, ldapWithUserSequence := Tester.CreateSuccessfulLDAPIntent(t, idpID, "user", "id")
samlSuccessfulID, samlToken, samlChangeDate, samlSequence := Tester.CreateSuccessfulSAMLIntent(t, idpID, "", "id")
idpID := Tester.AddGenericOAuthProvider(t, CTX)
intentID := Tester.CreateIntent(t, CTX, idpID)
successfulID, token, changeDate, sequence := Tester.CreateSuccessfulOAuthIntent(t, CTX, idpID, "", "id")
successfulWithUserID, withUsertoken, withUserchangeDate, withUsersequence := Tester.CreateSuccessfulOAuthIntent(t, CTX, idpID, "user", "id")
ldapSuccessfulID, ldapToken, ldapChangeDate, ldapSequence := Tester.CreateSuccessfulLDAPIntent(t, CTX, idpID, "", "id")
ldapSuccessfulWithUserID, ldapWithUserToken, ldapWithUserChangeDate, ldapWithUserSequence := Tester.CreateSuccessfulLDAPIntent(t, CTX, idpID, "user", "id")
samlSuccessfulID, samlToken, samlChangeDate, samlSequence := Tester.CreateSuccessfulSAMLIntent(t, CTX, idpID, "", "id")
type args struct {
ctx context.Context
req *user.RetrieveIdentityProviderIntentRequest
Expand Down Expand Up @@ -2050,7 +2146,7 @@ func TestServer_RetrieveIdentityProviderIntent(t *testing.T) {
want: &user.RetrieveIdentityProviderIntentResponse{
Details: &object.Details{
ChangeDate: timestamppb.New(changeDate),
ResourceOwner: Tester.Organisation.ID,
ResourceOwner: Tester.Instance.InstanceID(),
Sequence: sequence,
},
IdpInformation: &user.IDPInformation{
Expand Down Expand Up @@ -2081,14 +2177,14 @@ func TestServer_RetrieveIdentityProviderIntent(t *testing.T) {
CTX,
&user.RetrieveIdentityProviderIntentRequest{
IdpIntentId: successfulWithUserID,
IdpIntentToken: WithUsertoken,
IdpIntentToken: withUsertoken,
},
},
want: &user.RetrieveIdentityProviderIntentResponse{
Details: &object.Details{
ChangeDate: timestamppb.New(WithUserchangeDate),
ResourceOwner: Tester.Organisation.ID,
Sequence: WithUsersequence,
ChangeDate: timestamppb.New(withUserchangeDate),
ResourceOwner: Tester.Instance.InstanceID(),
Sequence: withUsersequence,
},
UserId: "user",
IdpInformation: &user.IDPInformation{
Expand Down Expand Up @@ -2125,7 +2221,7 @@ func TestServer_RetrieveIdentityProviderIntent(t *testing.T) {
want: &user.RetrieveIdentityProviderIntentResponse{
Details: &object.Details{
ChangeDate: timestamppb.New(ldapChangeDate),
ResourceOwner: Tester.Organisation.ID,
ResourceOwner: Tester.Instance.InstanceID(),
Sequence: ldapSequence,
},
IdpInformation: &user.IDPInformation{
Expand Down Expand Up @@ -2170,7 +2266,7 @@ func TestServer_RetrieveIdentityProviderIntent(t *testing.T) {
want: &user.RetrieveIdentityProviderIntentResponse{
Details: &object.Details{
ChangeDate: timestamppb.New(ldapWithUserChangeDate),
ResourceOwner: Tester.Organisation.ID,
ResourceOwner: Tester.Instance.InstanceID(),
Sequence: ldapWithUserSequence,
},
UserId: "user",
Expand Down Expand Up @@ -2216,7 +2312,7 @@ func TestServer_RetrieveIdentityProviderIntent(t *testing.T) {
want: &user.RetrieveIdentityProviderIntentResponse{
Details: &object.Details{
ChangeDate: timestamppb.New(samlChangeDate),
ResourceOwner: Tester.Organisation.ID,
ResourceOwner: Tester.Instance.InstanceID(),
Sequence: samlSequence,
},
IdpInformation: &user.IDPInformation{
Expand Down
10 changes: 5 additions & 5 deletions internal/api/idp/idp_integration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,8 @@ func TestMain(m *testing.M) {
}

func TestServer_SAMLCertificate(t *testing.T) {
samlRedirectIdpID := Tester.AddSAMLRedirectProvider(t)
oauthIdpID := Tester.AddGenericOAuthProvider(t)
samlRedirectIdpID := Tester.AddSAMLRedirectProvider(t, CTX)
oauthIdpID := Tester.AddGenericOAuthProvider(t, CTX)

type args struct {
ctx context.Context
Expand Down Expand Up @@ -109,8 +109,8 @@ func TestServer_SAMLCertificate(t *testing.T) {
}

func TestServer_SAMLMetadata(t *testing.T) {
samlRedirectIdpID := Tester.AddSAMLRedirectProvider(t)
oauthIdpID := Tester.AddGenericOAuthProvider(t)
samlRedirectIdpID := Tester.AddSAMLRedirectProvider(t, CTX)
oauthIdpID := Tester.AddGenericOAuthProvider(t, CTX)

type args struct {
ctx context.Context
Expand Down Expand Up @@ -167,7 +167,7 @@ func TestServer_SAMLMetadata(t *testing.T) {

func TestServer_SAMLACS(t *testing.T) {
userHuman := Tester.CreateHumanUser(CTX)
samlRedirectIdpID := Tester.AddSAMLRedirectProvider(t)
samlRedirectIdpID := Tester.AddSAMLRedirectProvider(t, CTX)
externalUserID := "test1"
linkedExternalUserID := "test2"
Tester.CreateUserIDPlink(CTX, userHuman.UserId, linkedExternalUserID, samlRedirectIdpID, linkedExternalUserID)
Expand Down
Loading

0 comments on commit 72c5b05

Please sign in to comment.