mirror of
https://github.com/zitadel/zitadel.git
synced 2025-08-15 05:47:34 +00:00
feat: project roles (#843)
* fix logging * token verification * feat: assert roles * feat: add project role assertion on project and token type on app * id and access token role assertion * add project role check * user grant required step in login * update library * fix merge * fix merge * fix merge * update oidc library * fix tests * add tests for GrantRequiredStep * add missing field ProjectRoleCheck on project view model * fix project create * fix project create
This commit is contained in:
@@ -222,32 +222,32 @@ func (l *Login) handleAutoRegister(w http.ResponseWriter, r *http.Request, authR
|
||||
}
|
||||
|
||||
func (l *Login) mapTokenToLoginUser(tokens *oidc.Tokens, idpConfig *iam_model.IDPConfigView) *model.ExternalUser {
|
||||
displayName := tokens.IDTokenClaims.PreferredUsername
|
||||
if displayName == "" && tokens.IDTokenClaims.Email != "" {
|
||||
displayName = tokens.IDTokenClaims.Email
|
||||
displayName := tokens.IDTokenClaims.GetPreferredUsername()
|
||||
if displayName == "" && tokens.IDTokenClaims.GetEmail() != "" {
|
||||
displayName = tokens.IDTokenClaims.GetEmail()
|
||||
}
|
||||
switch idpConfig.OIDCIDPDisplayNameMapping {
|
||||
case iam_model.OIDCMappingFieldEmail:
|
||||
if tokens.IDTokenClaims.EmailVerified && tokens.IDTokenClaims.Email != "" {
|
||||
displayName = tokens.IDTokenClaims.Email
|
||||
if tokens.IDTokenClaims.IsEmailVerified() && tokens.IDTokenClaims.GetEmail() != "" {
|
||||
displayName = tokens.IDTokenClaims.GetEmail()
|
||||
}
|
||||
}
|
||||
|
||||
externalUser := &model.ExternalUser{
|
||||
IDPConfigID: idpConfig.IDPConfigID,
|
||||
ExternalUserID: tokens.IDTokenClaims.Subject,
|
||||
PreferredUsername: tokens.IDTokenClaims.PreferredUsername,
|
||||
ExternalUserID: tokens.IDTokenClaims.GetSubject(),
|
||||
PreferredUsername: tokens.IDTokenClaims.GetPreferredUsername(),
|
||||
DisplayName: displayName,
|
||||
FirstName: tokens.IDTokenClaims.GivenName,
|
||||
LastName: tokens.IDTokenClaims.FamilyName,
|
||||
NickName: tokens.IDTokenClaims.Nickname,
|
||||
Email: tokens.IDTokenClaims.Email,
|
||||
IsEmailVerified: tokens.IDTokenClaims.EmailVerified,
|
||||
FirstName: tokens.IDTokenClaims.GetGivenName(),
|
||||
LastName: tokens.IDTokenClaims.GetFamilyName(),
|
||||
NickName: tokens.IDTokenClaims.GetNickname(),
|
||||
Email: tokens.IDTokenClaims.GetEmail(),
|
||||
IsEmailVerified: tokens.IDTokenClaims.IsEmailVerified(),
|
||||
}
|
||||
|
||||
if tokens.IDTokenClaims.PhoneNumber != "" {
|
||||
externalUser.Phone = tokens.IDTokenClaims.PhoneNumber
|
||||
externalUser.IsPhoneVerified = tokens.IDTokenClaims.PhoneNumberVerified
|
||||
if tokens.IDTokenClaims.GetPhoneNumber() != "" {
|
||||
externalUser.Phone = tokens.IDTokenClaims.GetPhoneNumber()
|
||||
externalUser.IsPhoneVerified = tokens.IDTokenClaims.IsPhoneNumberVerified()
|
||||
}
|
||||
return externalUser
|
||||
}
|
||||
|
@@ -1,8 +1,13 @@
|
||||
package handler
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
"github.com/caos/oidc/pkg/oidc"
|
||||
"github.com/caos/oidc/pkg/rp"
|
||||
"golang.org/x/text/language"
|
||||
|
||||
http_mw "github.com/caos/zitadel/internal/api/http/middleware"
|
||||
"github.com/caos/zitadel/internal/auth_request/model"
|
||||
caos_errors "github.com/caos/zitadel/internal/errors"
|
||||
@@ -10,8 +15,6 @@ import (
|
||||
iam_model "github.com/caos/zitadel/internal/iam/model"
|
||||
org_model "github.com/caos/zitadel/internal/org/model"
|
||||
usr_model "github.com/caos/zitadel/internal/user/model"
|
||||
"net/http"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func (l *Login) handleExternalRegister(w http.ResponseWriter, r *http.Request) {
|
||||
@@ -109,11 +112,11 @@ func (l *Login) handleExternalUserRegister(w http.ResponseWriter, r *http.Reques
|
||||
}
|
||||
|
||||
func (l *Login) mapTokenToLoginUserAndExternalIDP(orgIamPolicy *iam_model.OrgIAMPolicyView, tokens *oidc.Tokens, idpConfig *iam_model.IDPConfigView) (*usr_model.User, *usr_model.ExternalIDP) {
|
||||
username := tokens.IDTokenClaims.PreferredUsername
|
||||
username := tokens.IDTokenClaims.GetPreferredUsername()
|
||||
switch idpConfig.OIDCUsernameMapping {
|
||||
case iam_model.OIDCMappingFieldEmail:
|
||||
if tokens.IDTokenClaims.EmailVerified && tokens.IDTokenClaims.Email != "" {
|
||||
username = tokens.IDTokenClaims.Email
|
||||
if tokens.IDTokenClaims.IsEmailVerified() && tokens.IDTokenClaims.GetEmail() != "" {
|
||||
username = tokens.IDTokenClaims.GetEmail()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -128,35 +131,35 @@ func (l *Login) mapTokenToLoginUserAndExternalIDP(orgIamPolicy *iam_model.OrgIAM
|
||||
UserName: username,
|
||||
Human: &usr_model.Human{
|
||||
Profile: &usr_model.Profile{
|
||||
FirstName: tokens.IDTokenClaims.GivenName,
|
||||
LastName: tokens.IDTokenClaims.FamilyName,
|
||||
PreferredLanguage: tokens.IDTokenClaims.Locale,
|
||||
NickName: tokens.IDTokenClaims.Nickname,
|
||||
FirstName: tokens.IDTokenClaims.GetGivenName(),
|
||||
LastName: tokens.IDTokenClaims.GetFamilyName(),
|
||||
PreferredLanguage: language.Tag(tokens.IDTokenClaims.GetLocale()),
|
||||
NickName: tokens.IDTokenClaims.GetNickname(),
|
||||
},
|
||||
Email: &usr_model.Email{
|
||||
EmailAddress: tokens.IDTokenClaims.Email,
|
||||
IsEmailVerified: tokens.IDTokenClaims.EmailVerified,
|
||||
EmailAddress: tokens.IDTokenClaims.GetEmail(),
|
||||
IsEmailVerified: tokens.IDTokenClaims.IsEmailVerified(),
|
||||
},
|
||||
},
|
||||
}
|
||||
if tokens.IDTokenClaims.PhoneNumber != "" {
|
||||
if tokens.IDTokenClaims.GetPhoneNumber() != "" {
|
||||
user.Phone = &usr_model.Phone{
|
||||
PhoneNumber: tokens.IDTokenClaims.PhoneNumber,
|
||||
IsPhoneVerified: tokens.IDTokenClaims.PhoneNumberVerified,
|
||||
PhoneNumber: tokens.IDTokenClaims.GetPhoneNumber(),
|
||||
IsPhoneVerified: tokens.IDTokenClaims.IsPhoneNumberVerified(),
|
||||
}
|
||||
}
|
||||
|
||||
displayName := tokens.IDTokenClaims.PreferredUsername
|
||||
displayName := tokens.IDTokenClaims.GetPreferredUsername()
|
||||
switch idpConfig.OIDCIDPDisplayNameMapping {
|
||||
case iam_model.OIDCMappingFieldEmail:
|
||||
if tokens.IDTokenClaims.EmailVerified && tokens.IDTokenClaims.Email != "" {
|
||||
displayName = tokens.IDTokenClaims.Email
|
||||
if tokens.IDTokenClaims.IsEmailVerified() && tokens.IDTokenClaims.GetEmail() != "" {
|
||||
displayName = tokens.IDTokenClaims.GetEmail()
|
||||
}
|
||||
}
|
||||
|
||||
externalIDP := &usr_model.ExternalIDP{
|
||||
IDPConfigID: idpConfig.IDPConfigID,
|
||||
UserID: tokens.IDTokenClaims.Subject,
|
||||
UserID: tokens.IDTokenClaims.GetSubject(),
|
||||
DisplayName: displayName,
|
||||
}
|
||||
return user, externalIDP
|
||||
|
@@ -211,6 +211,8 @@ func (l *Login) chooseNextStep(w http.ResponseWriter, r *http.Request, authReq *
|
||||
l.renderExternalNotFoundOption(w, r, authReq, err)
|
||||
case *model.ExternalLoginStep:
|
||||
l.handleExternalLoginStep(w, r, authReq, step.SelectedIDPConfigID)
|
||||
case *model.GrantRequiredStep:
|
||||
l.renderInternalError(w, r, authReq, caos_errs.ThrowPreconditionFailed(nil, "APP-asb43", "Errors.User.GrantRequired"))
|
||||
default:
|
||||
l.renderInternalError(w, r, authReq, caos_errs.ThrowInternal(nil, "APP-ds3QF", "step no possible"))
|
||||
}
|
||||
|
@@ -187,6 +187,7 @@ Errors:
|
||||
AuthRequest:
|
||||
NotFound: AuthRequest konnte nicht gefunden werden
|
||||
UserAgentNotCorresponding: User Agent stimmt nicht überein
|
||||
RequestTypeNotSupported: Requesttyp wird nicht unterstürzt
|
||||
User:
|
||||
NotFound: Benutzer konnte nicht gefunden werden
|
||||
NotMatchingUserID: User stimm nicht mit User in Auth Request überein
|
||||
@@ -226,5 +227,6 @@ Errors:
|
||||
ExternalIDP:
|
||||
IDPTypeNotImplemented: IDP Typ ist nicht implementiert
|
||||
NotAllowed: Externer Login Provider ist nicht erlaubt
|
||||
GrantRequired: Der Login an diese Applikation ist nicht möglich. Der Benutzer benötigt mindestens eine Berechtigung an der Applikation. Bitte melde dich bei deinem Administrator.
|
||||
|
||||
optional: (optional)
|
||||
|
@@ -187,6 +187,7 @@ Errors:
|
||||
AuthRequest:
|
||||
NotFound: Could not find authrequest
|
||||
UserAgentNotCorresponding: User Agent does not correspond
|
||||
RequestTypeNotSupported: Request type is not supported
|
||||
User:
|
||||
NotFound: User could not be found
|
||||
NotMatchingUserID: User and user in authrequest don't match
|
||||
@@ -226,6 +227,7 @@ Errors:
|
||||
ExternalIDP:
|
||||
IDPTypeNotImplemented: IDP Type is not implemented
|
||||
NotAllowed: External Login Provider not allowed
|
||||
GrantRequired: Login not possible. The user is required to have at least one grant on the application. Please contact your administrator.
|
||||
|
||||
|
||||
optional: (optional)
|
||||
|
@@ -1,6 +1,6 @@
|
||||
{{template "main-top" .}}
|
||||
|
||||
<div>
|
||||
<div class="head">
|
||||
{{ .ErrType }}
|
||||
{{ .ErrMessage }}
|
||||
</div>
|
||||
|
Reference in New Issue
Block a user