- templates/org: mirror fix on name output - routers: add missing error checktags/v1.21.12.1
| @@ -93,7 +93,7 @@ func CreateOrganization(org, owner *User) (*User, error) { | |||
| return nil, ErrUserNameIllegal | |||
| } | |||
| isExist, err := IsUserExist(org.Name) | |||
| isExist, err := IsUserExist(0, org.Name) | |||
| if err != nil { | |||
| return nil, err | |||
| } else if isExist { | |||
| @@ -249,11 +249,13 @@ func (u *User) GetFullNameFallback() string { | |||
| // IsUserExist checks if given user name exist, | |||
| // the user name should be noncased unique. | |||
| func IsUserExist(name string) (bool, error) { | |||
| // If uid is presented, then check will rule out that one, | |||
| // it is used when update a user name in settings page. | |||
| func IsUserExist(uid int64, name string) (bool, error) { | |||
| if len(name) == 0 { | |||
| return false, nil | |||
| } | |||
| return x.Get(&User{LowerName: strings.ToLower(name)}) | |||
| return x.Where("id!=?", uid).Get(&User{LowerName: strings.ToLower(name)}) | |||
| } | |||
| // IsEmailUsed returns true if the e-mail has been used. | |||
| @@ -278,7 +280,7 @@ func CreateUser(u *User) error { | |||
| return ErrUserNameIllegal | |||
| } | |||
| isExist, err := IsUserExist(u.Name) | |||
| isExist, err := IsUserExist(0, u.Name) | |||
| if err != nil { | |||
| return err | |||
| } else if isExist { | |||
| @@ -397,6 +399,10 @@ func ChangeUserName(u *User, newUserName string) (err error) { | |||
| } | |||
| newUserName = strings.ToLower(newUserName) | |||
| if u.LowerName == newUserName { | |||
| // User only change letter cases. | |||
| return nil | |||
| } | |||
| // Update accesses of user. | |||
| accesses := make([]Access, 0, 10) | |||
| @@ -453,7 +459,7 @@ func ChangeUserName(u *User, newUserName string) (err error) { | |||
| // UpdateUser updates user's information. | |||
| func UpdateUser(u *User) error { | |||
| has, err := x.Where("id!=?", u.Id).And("type=?", INDIVIDUAL).And("email=?", u.Email).Get(new(User)) | |||
| has, err := x.Where("id!=?", u.Id).And("type=?", u.Type).And("email=?", u.Email).Get(new(User)) | |||
| if err != nil { | |||
| return err | |||
| } else if has { | |||
| @@ -39,18 +39,18 @@ func SettingsPost(ctx *middleware.Context, form auth.UpdateOrgSettingForm) { | |||
| // Check if organization name has been changed. | |||
| if org.Name != form.OrgUserName { | |||
| isExist, err := models.IsUserExist(form.OrgUserName) | |||
| isExist, err := models.IsUserExist(org.Id, form.OrgUserName) | |||
| if err != nil { | |||
| ctx.Handle(500, "IsUserExist", err) | |||
| return | |||
| } else if isExist { | |||
| ctx.Data["Err_UserName"] = true | |||
| ctx.RenderWithErr(ctx.Tr("form.username_been_taken"), SETTINGS_OPTIONS, &form) | |||
| return | |||
| } else if err = models.ChangeUserName(org, form.OrgUserName); err != nil { | |||
| if err == models.ErrUserNameIllegal { | |||
| ctx.Flash.Error(ctx.Tr("form.illegal_username")) | |||
| ctx.Redirect(setting.AppSubUrl + "/org/" + org.LowerName + "/settings") | |||
| return | |||
| ctx.Data["Err_UserName"] = true | |||
| ctx.RenderWithErr(ctx.Tr("form.illegal_username"), SETTINGS_OPTIONS, &form) | |||
| } else { | |||
| ctx.Handle(500, "ChangeUserName", err) | |||
| } | |||
| @@ -68,7 +68,12 @@ func SettingsPost(ctx *middleware.Context, form auth.UpdateOrgSettingForm) { | |||
| org.Avatar = base.EncodeMd5(form.Avatar) | |||
| org.AvatarEmail = form.Avatar | |||
| if err := models.UpdateUser(org); err != nil { | |||
| ctx.Handle(500, "UpdateUser", err) | |||
| if err == models.ErrEmailAlreadyUsed { | |||
| ctx.Data["Err_Email"] = true | |||
| ctx.RenderWithErr(ctx.Tr("form.email_been_used"), SETTINGS_OPTIONS, &form) | |||
| } else { | |||
| ctx.Handle(500, "UpdateUser", err) | |||
| } | |||
| return | |||
| } | |||
| log.Trace("Organization setting updated: %s", org.Name) | |||
| @@ -109,7 +109,7 @@ func SettingsPost(ctx *middleware.Context, form auth.RepoSettingForm) { | |||
| } | |||
| newOwner := ctx.Query("new_owner_name") | |||
| isExist, err := models.IsUserExist(newOwner) | |||
| isExist, err := models.IsUserExist(0, newOwner) | |||
| if err != nil { | |||
| ctx.Handle(500, "IsUserExist", err) | |||
| return | |||
| @@ -50,7 +50,7 @@ func SettingsPost(ctx *middleware.Context, form auth.UpdateProfileForm) { | |||
| // Check if user name has been changed. | |||
| if ctx.User.Name != form.UserName { | |||
| isExist, err := models.IsUserExist(form.UserName) | |||
| isExist, err := models.IsUserExist(ctx.User.Id, form.UserName) | |||
| if err != nil { | |||
| ctx.Handle(500, "IsUserExist", err) | |||
| return | |||
| @@ -58,11 +58,14 @@ func SettingsPost(ctx *middleware.Context, form auth.UpdateProfileForm) { | |||
| ctx.RenderWithErr(ctx.Tr("form.username_been_taken"), SETTINGS_PROFILE, &form) | |||
| return | |||
| } else if err = models.ChangeUserName(ctx.User, form.UserName); err != nil { | |||
| if err == models.ErrUserNameIllegal { | |||
| switch err { | |||
| case models.ErrUserNameIllegal: | |||
| ctx.Flash.Error(ctx.Tr("form.illegal_username")) | |||
| ctx.Redirect(setting.AppSubUrl + "/user/settings") | |||
| return | |||
| } else { | |||
| case models.ErrEmailAlreadyUsed: | |||
| ctx.Flash.Error(ctx.Tr("form.email_been_used")) | |||
| ctx.Redirect(setting.AppSubUrl + "/user/settings") | |||
| default: | |||
| ctx.Handle(500, "ChangeUserName", err) | |||
| } | |||
| return | |||
| @@ -2,7 +2,7 @@ | |||
| <div class="container"> | |||
| <a class="text-black left" href="{{AppSubUrl}}/org/{{.Org.LowerName}}"> | |||
| <img class="avatar-48 left" src="{{.Org.AvatarLink}}?s=100"> | |||
| <span class="org-name">{{.Org.FullName}}</span> | |||
| <span class="org-name">{{if .Org.FullName}}{{.Org.FullName}}{{else}}{{.Org.Name}}{{end}}</span> | |||
| </a> | |||
| <ul class="menu menu-line container"> | |||
| <li class="right"> | |||
| @@ -1,12 +1,12 @@ | |||
| <div id="setting-menu" class="grid-1-5 panel panel-radius left"> | |||
| <div class="panel-header"> | |||
| <strong>{{.i18n.Tr "org.settings"}}</strong> | |||
| </div> | |||
| <div class="panel-body"> | |||
| <ul class="menu menu-vertical switching-list grid-1-5 left"> | |||
| <li {{if .PageIsSettingsOptions}}class="current"{{end}}><a href="{{AppSubUrl}}/org/{{.Org.LowerName}}/settings">{{.i18n.Tr "org.settings.options"}}</a></li> | |||
| <li {{if .PageIsSettingsHooks}}class="current"{{end}}><a href="{{AppSubUrl}}/org/{{.Org.LowerName}}/settings/hooks">{{.i18n.Tr "repo.settings.hooks"}}</a></li> | |||
| <li {{if .PageIsSettingsDelete}}class="current"{{end}}><a href="{{AppSubUrl}}/org/{{.Org.LowerName}}/settings/delete">{{.i18n.Tr "org.settings.delete"}}</a></li> | |||
| </ul> | |||
| </div> | |||
| <div class="panel-header"> | |||
| <strong>{{.i18n.Tr "org.settings"}}</strong> | |||
| </div> | |||
| <div class="panel-body"> | |||
| <ul class="menu menu-vertical switching-list grid-1-5 left"> | |||
| <li {{if .PageIsSettingsOptions}}class="current"{{end}}><a href="{{AppSubUrl}}/org/{{.Org.Name}}/settings">{{.i18n.Tr "org.settings.options"}}</a></li> | |||
| <li {{if .PageIsSettingsHooks}}class="current"{{end}}><a href="{{AppSubUrl}}/org/{{.Org.Name}}/settings/hooks">{{.i18n.Tr "repo.settings.hooks"}}</a></li> | |||
| <li {{if .PageIsSettingsDelete}}class="current"{{end}}><a href="{{AppSubUrl}}/org/{{.Org.Name}}/settings/delete">{{.i18n.Tr "org.settings.delete"}}</a></li> | |||
| </ul> | |||
| </div> | |||
| </div> | |||
| @@ -2,63 +2,63 @@ | |||
| {{template "ng/base/header" .}} | |||
| {{template "org/base/header" .}} | |||
| <div id="setting-wrapper" class="main-wrapper"> | |||
| <div id="org-setting" class="container clear"> | |||
| {{template "org/settings/nav" .}} | |||
| <div class="grid-4-5 left"> | |||
| <div class="setting-content"> | |||
| {{template "ng/base/alert" .}} | |||
| <div id="setting-content"> | |||
| <div id="user-profile-setting-content" class="panel panel-radius"> | |||
| <div class="panel-header"> | |||
| <strong>{{.i18n.Tr "org.settings.options"}}</strong> | |||
| </div> | |||
| <form class="form form-align panel-body" id="org-setting-form" action="{{AppSubUrl}}/org/{{.Org.LowerName}}/settings" method="post"> | |||
| {{.CsrfTokenHtml}} | |||
| <input type="hidden" name="action" value="update"> | |||
| <div class="field"> | |||
| <label class="req" for="orgname">{{.i18n.Tr "username"}}</label> | |||
| <input class="ipt ipt-large ipt-radius {{if .Err_UserName}}ipt-error{{end}}" id="orgname" name="uname" value="{{.Org.Name}}" data-orgname="{{.Org.Name}}" required /> | |||
| </div> | |||
| <div class="white-popup-block mfp-hide" id="change-orgname-modal"> | |||
| <h1 class="text-red">{{.i18n.Tr "org.settings.change_orgname"}}</h1> | |||
| <p>{{.i18n.Tr "org.settings.change_orgname_desc"}}</p> | |||
| <br> | |||
| <button class="btn btn-red btn-large btn-radius" id="change-orgname-submit">{{.i18n.Tr "settings.continue"}}</button> | |||
| <button class="btn btn-large btn-radius popup-modal-dismiss">{{.i18n.Tr "settings.cancel"}}</button> | |||
| </div> | |||
| <div class="field"> | |||
| <label for="full-name">{{.i18n.Tr "org.settings.full_name"}}</label> | |||
| <input class="ipt ipt-large ipt-radius {{if .Err_FullName}}ipt-error{{end}}" id="full-name" name="fullname" value="{{.Org.FullName}}" /> | |||
| </div> | |||
| <div class="field"> | |||
| <label class="req" for="email">{{.i18n.Tr "email"}}</label> | |||
| <input class="ipt ipt-large ipt-radius {{if .Err_Email}}ipt-error{{end}}" id="email" name="email" type="email" value="{{.Org.Email}}" required /> | |||
| </div> | |||
| <div class="field clear"> | |||
| <label class="left" for="desc">{{.i18n.Tr "org.org_desc"}}</label> | |||
| <textarea class="ipt ipt-large ipt-radius {{if .Err_Description}}ipt-error{{end}}" id="desc" name="desc">{{.Org.Description}}</textarea> | |||
| </div> | |||
| <div class="field"> | |||
| <label for="website">{{.i18n.Tr "org.settings.website"}}</label> | |||
| <input class="ipt ipt-large ipt-radius {{if .Err_Website}}ipt-error{{end}}" id="website" name="website" type="url" value="{{.Org.Website}}" /> | |||
| </div> | |||
| <div class="field"> | |||
| <label for="location">{{.i18n.Tr "org.settings.location"}}</label> | |||
| <input class="ipt ipt-large ipt-radius {{if .Err_Location}}ipt-error{{end}}" id="location" name="location" type="text" value="{{.Org.Location}}" /> | |||
| </div> | |||
| <div class="field"> | |||
| <label for="gravatar-email">Gravatar {{.i18n.Tr "email"}}</label> | |||
| <input class="ipt ipt-large ipt-radius {{if .Err_Avatar}}ipt-error{{end}}" id="gravatar-email" name="avatar" type="text" value="{{.Org.AvatarEmail}}" /> | |||
| </div> | |||
| <div class="field"> | |||
| <span class="form-label"></span> | |||
| <button class="btn btn-green btn-large btn-radius" id="change-orgname-btn" href="#change-orgname-modal">{{.i18n.Tr "org.settings.update_settings"}}</button> | |||
| </div> | |||
| </form> | |||
| </div> | |||
| </div> | |||
| <div id="org-setting" class="container clear"> | |||
| {{template "org/settings/nav" .}} | |||
| <div class="grid-4-5 left"> | |||
| <div class="setting-content"> | |||
| {{template "ng/base/alert" .}} | |||
| <div id="setting-content"> | |||
| <div id="user-profile-setting-content" class="panel panel-radius"> | |||
| <div class="panel-header"> | |||
| <strong>{{.i18n.Tr "org.settings.options"}}</strong> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| <form class="form form-align panel-body" id="org-setting-form" action="{{AppSubUrl}}/org/{{.Org.LowerName}}/settings" method="post"> | |||
| {{.CsrfTokenHtml}} | |||
| <input type="hidden" name="action" value="update"> | |||
| <div class="field"> | |||
| <label class="req" for="orgname">{{.i18n.Tr "username"}}</label> | |||
| <input class="ipt ipt-large ipt-radius {{if .Err_UserName}}ipt-error{{end}}" id="orgname" name="uname" value="{{.Org.Name}}" data-orgname="{{.Org.Name}}" required /> | |||
| </div> | |||
| <div class="white-popup-block mfp-hide" id="change-orgname-modal"> | |||
| <h1 class="text-red">{{.i18n.Tr "org.settings.change_orgname"}}</h1> | |||
| <p>{{.i18n.Tr "org.settings.change_orgname_desc"}}</p> | |||
| <br> | |||
| <button class="btn btn-red btn-large btn-radius" id="change-orgname-submit">{{.i18n.Tr "settings.continue"}}</button> | |||
| <button class="btn btn-large btn-radius popup-modal-dismiss">{{.i18n.Tr "settings.cancel"}}</button> | |||
| </div> | |||
| <div class="field"> | |||
| <label for="full-name">{{.i18n.Tr "org.settings.full_name"}}</label> | |||
| <input class="ipt ipt-large ipt-radius {{if .Err_FullName}}ipt-error{{end}}" id="full-name" name="fullname" value="{{.Org.FullName}}" /> | |||
| </div> | |||
| <div class="field"> | |||
| <label class="req" for="email">{{.i18n.Tr "email"}}</label> | |||
| <input class="ipt ipt-large ipt-radius {{if .Err_Email}}ipt-error{{end}}" id="email" name="email" type="email" value="{{.Org.Email}}" required /> | |||
| </div> | |||
| <div class="field clear"> | |||
| <label class="left" for="desc">{{.i18n.Tr "org.org_desc"}}</label> | |||
| <textarea class="ipt ipt-large ipt-radius {{if .Err_Description}}ipt-error{{end}}" id="desc" name="desc">{{.Org.Description}}</textarea> | |||
| </div> | |||
| <div class="field"> | |||
| <label for="website">{{.i18n.Tr "org.settings.website"}}</label> | |||
| <input class="ipt ipt-large ipt-radius {{if .Err_Website}}ipt-error{{end}}" id="website" name="website" type="url" value="{{.Org.Website}}" /> | |||
| </div> | |||
| <div class="field"> | |||
| <label for="location">{{.i18n.Tr "org.settings.location"}}</label> | |||
| <input class="ipt ipt-large ipt-radius {{if .Err_Location}}ipt-error{{end}}" id="location" name="location" type="text" value="{{.Org.Location}}" /> | |||
| </div> | |||
| <div class="field"> | |||
| <label for="gravatar-email">Gravatar {{.i18n.Tr "email"}}</label> | |||
| <input class="ipt ipt-large ipt-radius {{if .Err_Avatar}}ipt-error{{end}}" id="gravatar-email" name="avatar" type="text" value="{{.Org.AvatarEmail}}" /> | |||
| </div> | |||
| <div class="field"> | |||
| <span class="form-label"></span> | |||
| <button class="btn btn-green btn-large btn-radius" id="change-orgname-btn" href="#change-orgname-modal">{{.i18n.Tr "org.settings.update_settings"}}</button> | |||
| </div> | |||
| </form> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| {{template "ng/base/footer" .}} | |||