fix: import user, hide login name suffix (#1474)

* fix: import user, and label policy command side

* feat: Import user and hide loginname suffix (#1464)

* fix: import user

* fix: label policy

* fix: label policy

* fix: label policy

* fix: migrations

* fix: migrations

* fix: migrations

* fix: label policy

* loginSuffix in login ui

* suffix

* fix cursor on disabled user selection

Co-authored-by: Livio Amstutz <livio.a@gmail.com>

(cherry picked from commit 03ddb8fc38)

* feat: Import user and hide loginname suffix (#1464)

* fix: import user

* fix: label policy

* fix: label policy

* fix: label policy

* fix: migrations

* fix: migrations

* fix: migrations

* fix: label policy

* loginSuffix in login ui

* suffix

* fix cursor on disabled user selection

Co-authored-by: Livio Amstutz <livio.a@gmail.com>

(cherry picked from commit 03ddb8fc38)

* feat: Import user and hide loginname suffix (#1464)

* fix: import user

* fix: label policy

* fix: label policy

* fix: label policy

* fix: migrations

* fix: migrations

* fix: migrations

* fix: label policy

* loginSuffix in login ui

* suffix

* fix cursor on disabled user selection

Co-authored-by: Livio Amstutz <livio.a@gmail.com>

(cherry picked from commit 03ddb8fc38)

* fix: label policy events

* loginname placeholder

* fix: tests

* fix: tests

* Update internal/command/iam_policy_label_model.go

Co-authored-by: Livio Amstutz <livio.a@gmail.com>

Co-authored-by: Livio Amstutz <livio.a@gmail.com>
This commit is contained in:
Fabi
2021-03-25 14:41:07 +01:00
committed by GitHub
parent d7255130a4
commit 4d10f3e715
58 changed files with 1444 additions and 309 deletions

View File

@@ -54,7 +54,8 @@ func (l *Login) handleLoginNameCheck(w http.ResponseWriter, r *http.Request) {
return
}
userAgentID, _ := http_mw.UserAgentIDFromCtx(r.Context())
err = l.authRepo.CheckLoginName(r.Context(), authReq.ID, data.LoginName, userAgentID)
loginName := data.LoginName
err = l.authRepo.CheckLoginName(r.Context(), authReq.ID, loginName, userAgentID)
if err != nil {
l.renderLogin(w, r, authReq, err)
return
@@ -73,7 +74,7 @@ func (l *Login) renderLogin(w http.ResponseWriter, r *http.Request, authReq *dom
return authReq.LoginPolicy != nil && authReq.LoginPolicy.AllowUsernamePassword
},
"hasExternalLogin": func() bool {
return authReq.LoginPolicy.AllowExternalIDP && authReq.AllowedExternalIDPs != nil && len(authReq.AllowedExternalIDPs) > 0
return authReq.LoginPolicy != nil && authReq.LoginPolicy.AllowExternalIDP && authReq.AllowedExternalIDPs != nil && len(authReq.AllowedExternalIDPs) > 0
},
}
l.renderer.RenderTemplate(w, r, l.renderer.Templates[tmplLogin], data, funcs)

View File

@@ -265,15 +265,17 @@ func (l *Login) getBaseData(r *http.Request, authReq *domain.AuthRequest, title
ErrType: errType,
ErrMessage: errMessage,
},
Lang: l.renderer.Lang(r).String(),
Title: title,
Theme: l.getTheme(r),
ThemeMode: l.getThemeMode(r),
OrgID: l.getOrgID(authReq),
OrgName: l.getOrgName(authReq),
AuthReqID: getRequestID(authReq, r),
CSRF: csrf.TemplateField(r),
Nonce: http_mw.GetNonce(r),
Lang: l.renderer.Lang(r).String(),
Title: title,
Theme: l.getTheme(r),
ThemeMode: l.getThemeMode(r),
OrgID: l.getOrgID(authReq),
OrgName: l.getOrgName(authReq),
PrimaryDomain: l.getOrgPrimaryDomain(authReq),
DisplayLoginNameSuffix: l.isDisplayLoginNameSuffix(authReq),
AuthReqID: getRequestID(authReq, r),
CSRF: csrf.TemplateField(r),
Nonce: http_mw.GetNonce(r),
}
if authReq != nil {
baseData.LoginPolicy = authReq.LoginPolicy
@@ -283,12 +285,14 @@ func (l *Login) getBaseData(r *http.Request, authReq *domain.AuthRequest, title
}
func (l *Login) getProfileData(authReq *domain.AuthRequest) profileData {
var loginName, displayName string
var userName, loginName, displayName string
if authReq != nil {
userName = authReq.UserName
loginName = authReq.LoginName
displayName = authReq.DisplayName
}
return profileData{
UserName: userName,
LoginName: loginName,
DisplayName: displayName,
}
@@ -329,6 +333,23 @@ func (l *Login) getOrgName(authReq *domain.AuthRequest) string {
return authReq.RequestedOrgName
}
func (l *Login) getOrgPrimaryDomain(authReq *domain.AuthRequest) string {
if authReq == nil {
return ""
}
return authReq.RequestedPrimaryDomain
}
func (l *Login) isDisplayLoginNameSuffix(authReq *domain.AuthRequest) bool {
if authReq == nil {
return false
}
if authReq.RequestedOrgID == "" {
return false
}
return authReq.LabelPolicy != nil && !authReq.LabelPolicy.HideLoginNameSuffix
}
func getRequestID(authReq *domain.AuthRequest, r *http.Request) string {
if authReq != nil {
return authReq.ID
@@ -351,17 +372,19 @@ func (l *Login) cspErrorHandler(err error) http.Handler {
type baseData struct {
errorData
Lang string
Title string
Theme string
ThemeMode string
OrgID string
OrgName string
AuthReqID string
CSRF template.HTML
Nonce string
LoginPolicy *domain.LoginPolicy
IDPProviders []*domain.IDPProvider
Lang string
Title string
Theme string
ThemeMode string
OrgID string
OrgName string
PrimaryDomain string
DisplayLoginNameSuffix bool
AuthReqID string
CSRF template.HTML
Nonce string
LoginPolicy *domain.LoginPolicy
IDPProviders []*domain.IDPProvider
}
type errorData struct {
@@ -380,6 +403,7 @@ type userData struct {
type profileData struct {
LoginName string
UserName string
DisplayName string
}

View File

@@ -1,19 +1,10 @@
Password:
Title: Willkommen zurück!
Description: Gib deine Benutzerdaten ein.
Password: Passwort
MinLength: Mindestlänge
HasUppercase: Grossbuchstaben
HasLowercase: Kleinbuchstaben
HasNumber: Nummer
HasSymbol: Symbol
Login:
Title: Anmeldung
Description: Mit ZITADEL-Konto anmelden.
TitleLinking: Anmeldung für Benutzer Linking
DescriptionLinking: Gib deine Benutzerdaten ein um den externen Benutzer mit einem ZITADEL Benutzer zu linken.
Loginname: Loginname
UsernamePlaceHolder: username
LoginnamePlaceHolder: username@domain
ExternalLogin: Melde dich mit einem externen Benutzer an
MustBeMemberOfOrg: Der Benutzer muss der Organisation {{.OrgName}} angehören.
@@ -28,6 +19,16 @@ UserSelection:
SessionState1: inaktiv
MustBeMemberOfOrg: Der Benutzer muss der Organisation {{.OrgName}} angehören.
Password:
Title: Willkommen zurück!
Description: Gib deine Benutzerdaten ein.
Password: Passwort
MinLength: Mindestlänge
HasUppercase: Grossbuchstaben
HasLowercase: Kleinbuchstaben
HasNumber: Nummer
HasSymbol: Symbol
UsernameChange:
Title: Usernamen ändern
Description: Wähle deinen neuen Benutzernamen

View File

@@ -4,9 +4,10 @@ Login:
TitleLinking: Login for userlinking
DescriptionLinking: Enter your login data to link your external user with a ZITADEL user.
Loginname: Loginname
UsernamePlaceHolder: username
LoginnamePlaceHolder: username@domain
ExternalLogin: Login with an external user.
MustBeMemberOfOrg: The user must be mermber of the {{.OrgDomain}} organisation.
MustBeMemberOfOrg: The user must be mermber of the {{.OrgName}} organisation.
UserSelection:
Title: Select account
@@ -16,7 +17,7 @@ UserSelection:
OtherUser: Other User
SessionState0: active
SessionState1: inactive
MustBeMemberOfOrg: The user must be mermber of the {{.OrgDomain}} organisation.
MustBeMemberOfOrg: The user must be mermber of the {{.OrgName}} organisation.
Password:
Title: Password

View File

@@ -12,6 +12,11 @@ $lgn-container-margin: 0px auto 50px auto;
align-items: center;
border: none;
outline: none;
cursor: pointer;
&:disabled {
cursor: not-allowed;
}
.left {
padding: .5rem 1rem;

View File

@@ -25,7 +25,6 @@
color: inherit;
background: transparent;
box-shadow: inset 0 -1px lgn-color($foreground, footer-line);
cursor: pointer;
&:hover {
$primary: map-get($config, primary);

View File

@@ -440,6 +440,10 @@ i {
align-items: center;
border: none;
outline: none;
cursor: pointer;
}
.lgn-account-selection .lgn-account:disabled {
cursor: not-allowed;
}
.lgn-account-selection .lgn-account .left {
padding: 0.5rem 1rem;
@@ -1298,6 +1302,10 @@ i {
align-items: center;
border: none;
outline: none;
cursor: pointer;
}
.lgn-account-selection .lgn-account:disabled {
cursor: not-allowed;
}
.lgn-account-selection .lgn-account .left {
padding: 0.5rem 1rem;

File diff suppressed because one or more lines are too long

View File

@@ -440,6 +440,10 @@ i {
align-items: center;
border: none;
outline: none;
cursor: pointer;
}
.lgn-account-selection .lgn-account:disabled {
cursor: not-allowed;
}
.lgn-account-selection .lgn-account .left {
padding: 0.5rem 1rem;
@@ -1202,7 +1206,6 @@ a:hover, a:active {
color: inherit;
background: transparent;
box-shadow: inset 0 -1px #303131;
cursor: pointer;
}
.lgn-account-selection .lgn-account:hover {
background-color: rgba(255, 255, 255, 0.02);
@@ -1522,7 +1525,6 @@ a:hover, a:active {
color: inherit;
background: transparent;
box-shadow: inset 0 -1px #303131;
cursor: pointer;
}
.lgn-dark-theme .lgn-account-selection .lgn-account:hover {
background-color: rgba(255, 255, 255, 0.02);
@@ -1836,7 +1838,6 @@ a:hover, a:active {
color: inherit;
background: transparent;
box-shadow: inset 0 -1px #e3e8ee;
cursor: pointer;
}
.lgn-light-theme .lgn-account-selection .lgn-account:hover {
background-color: rgba(0, 0, 0, 0.02);

File diff suppressed because one or more lines are too long

View File

@@ -20,8 +20,13 @@
{{if hasUsernamePasswordLogin }}
<div class="fields">
<label class="lgn-label" for="loginName">{{t "Login.Loginname"}}</label>
<input class="lgn-input lgn-suffix-input" type="text" id="loginName" name="loginName" placeholder="{{t "Login.LoginnamePlaceHolder"}}"
value="{{ .LoginName }}" {{if .ErrMessage}}shake {{end}} autocomplete="username" autofocus required>
<div class="lgn-suffix-wrapper">
<input class="lgn-input lgn-suffix-input" type="text" id="loginName" name="loginName" placeholder="{{if .OrgID }}{{t "Login.UsernamePlaceHolder"}}{{else}}{{t "Login.LoginnamePlaceHolder"}}{{end}}"
value="{{ .UserName }}" {{if .ErrMessage}}shake {{end}} autocomplete="username" autofocus required>
{{if .DisplayLoginNameSuffix}}
<span id="default-login-suffix" lgnsuffix class="loginname-suffix">@{{.PrimaryDomain}}</span>
{{end}}
</div>
</div>
{{end}}
@@ -53,5 +58,6 @@
<script src="{{ resourceUrl "scripts/form_submit.js" }}"></script>
<script src="{{ resourceUrl "scripts/default_form_validation.js" }}"></script>
<script src="{{ resourceUrl "scripts/input_suffix_offset.js" }}"></script>
{{template "main-bottom" .}}

View File

@@ -23,10 +23,11 @@
<div class="lgn-account-selection">
{{ if .Users }}
{{ $displayLoginNameSuffix := and .OrgID (not .DisplayLoginNameSuffix)}}
{{ range $user := .Users }}
{{ $sessionState := (printf "UserSelection.SessionState%v" $user.UserSessionState) }}
<button type="submit" name="userID" value="{{$user.UserID}}" class="lgn-account"
{{if not $user.SelectionPossible}}disabled title="{{t " Errors.User.NotAllowedOrg"}}"{{end}}>
{{if not $user.SelectionPossible}}disabled title="{{t "Errors.User.NotAllowedOrg"}}"{{end}}>
<div class="left">
<div class="lgn-avatar" displayname="{{$user.DisplayName}}">
<span class="initials">A</span>
@@ -34,7 +35,7 @@
</div>
<div class="lgn-names">
<p class="lgn-displayname">{{$user.DisplayName}}</p>
<p class="lgn-loginname">{{$user.LoginName}}</p>
<p class="lgn-loginname">{{if and $displayLoginNameSuffix $user.SelectionPossible}}{{$user.UserName}}{{else}}{{$user.LoginName}}{{end}}</p>
<p class="lgn-session-state i{{$user.UserSessionState}}">{{t $sessionState}}</p>
</div>
<span class="fill-space"></span>

View File

@@ -1,5 +1,5 @@
{{define "user-profile"}}
{{if .LoginName}}
{{if or .LoginName .UserName}}
<div class="lgn-login-profile">
<div class="lgn-profile-image"></div>
<div class="lgn-names">
@@ -9,7 +9,7 @@
</div>
</div>
<div class="lgn-loginname">
<p>{{.LoginName}}</p>
<p>{{if .DisplayLoginNameSuffix}}{{.LoginName}}{{else}}{{.UserName}}{{end}}</p>
</div>
</div>
</div>