From 2b9df564b858a9216ffb7881278f485b35946349 Mon Sep 17 00:00:00 2001 From: silverwind Date: Wed, 23 Feb 2022 21:16:07 +0100 Subject: [PATCH 1/4] Lock gofumpt to v0.3.0 and run it (#18866) We can't depend on `latest` version of gofumpt because the output will not be stable across versions. Lock it down to the latest version released yesterday and run it again. --- Makefile | 4 ++-- models/issue_xref.go | 3 ++- models/migrations/v210.go | 2 +- models/migrations/v210_test.go | 1 + modules/indexer/code/bleve.go | 3 ++- modules/notification/action/action.go | 3 ++- modules/notification/indexer/indexer.go | 3 ++- modules/notification/mail/mail.go | 3 ++- modules/notification/notification.go | 6 ++++-- modules/notification/ui/ui.go | 3 ++- modules/notification/webhook/webhook.go | 6 ++++-- modules/structs/repo.go | 1 - routers/web/repo/branch.go | 3 ++- services/mailer/mail.go | 3 ++- services/release/release.go | 3 ++- 15 files changed, 30 insertions(+), 17 deletions(-) diff --git a/Makefile b/Makefile index a40086b3dc75c..74067597cb119 100644 --- a/Makefile +++ b/Makefile @@ -235,7 +235,7 @@ clean: .PHONY: fmt fmt: @hash gofumpt > /dev/null 2>&1; if [ $$? -ne 0 ]; then \ - $(GO) install mvdan.cc/gofumpt@latest; \ + $(GO) install mvdan.cc/gofumpt@v0.3.0; \ fi @echo "Running gitea-fmt (with gofumpt)..." @$(GO) run build/code-batch-process.go gitea-fmt -w '{file-list}' @@ -287,7 +287,7 @@ errcheck: .PHONY: fmt-check fmt-check: @hash gofumpt > /dev/null 2>&1; if [ $$? -ne 0 ]; then \ - $(GO) install mvdan.cc/gofumpt@latest; \ + $(GO) install mvdan.cc/gofumpt@0.3.0; \ fi # get all go files and run gitea-fmt (with gofmt) on them @diff=$$($(GO) run build/code-batch-process.go gitea-fmt -l '{file-list}'); \ diff --git a/models/issue_xref.go b/models/issue_xref.go index fdabedf29aabe..7b2f097c1cf74 100644 --- a/models/issue_xref.go +++ b/models/issue_xref.go @@ -195,7 +195,8 @@ func (issue *Issue) updateCrossReferenceList(list []*crossReference, xref *cross // verifyReferencedIssue will check if the referenced issue exists, and whether the doer has permission to do what func (issue *Issue) verifyReferencedIssue(stdCtx context.Context, ctx *crossReferencesContext, repo *repo_model.Repository, - ref references.IssueReference) (*Issue, references.XRefAction, error) { + ref references.IssueReference, +) (*Issue, references.XRefAction, error) { refIssue := &Issue{RepoID: repo.ID, Index: ref.Index} refAction := ref.Action e := db.GetEngine(stdCtx) diff --git a/models/migrations/v210.go b/models/migrations/v210.go index cf50760b92c33..9da8ca9db6643 100644 --- a/models/migrations/v210.go +++ b/models/migrations/v210.go @@ -11,8 +11,8 @@ import ( "strings" "code.gitea.io/gitea/modules/timeutil" - "github.com/tstranex/u2f" + "github.com/tstranex/u2f" "xorm.io/xorm" "xorm.io/xorm/schemas" ) diff --git a/models/migrations/v210_test.go b/models/migrations/v210_test.go index 3e10b3ce80a25..70dbe61b06eb7 100644 --- a/models/migrations/v210_test.go +++ b/models/migrations/v210_test.go @@ -8,6 +8,7 @@ import ( "testing" "code.gitea.io/gitea/modules/timeutil" + "github.com/stretchr/testify/assert" "xorm.io/xorm/schemas" ) diff --git a/modules/indexer/code/bleve.go b/modules/indexer/code/bleve.go index 281c14c11e412..309b33bedf1f7 100644 --- a/modules/indexer/code/bleve.go +++ b/modules/indexer/code/bleve.go @@ -182,7 +182,8 @@ func NewBleveIndexer(indexDir string) (*BleveIndexer, bool, error) { } func (b *BleveIndexer) addUpdate(ctx context.Context, batchWriter git.WriteCloserError, batchReader *bufio.Reader, commitSha string, - update fileUpdate, repo *repo_model.Repository, batch *gitea_bleve.FlushingBatch) error { + update fileUpdate, repo *repo_model.Repository, batch *gitea_bleve.FlushingBatch, +) error { // Ignore vendored files in code search if setting.Indexer.ExcludeVendored && analyze.IsVendor(update.Filename) { return nil diff --git a/modules/notification/action/action.go b/modules/notification/action/action.go index ed4ce3dd1aff0..bab28db475445 100644 --- a/modules/notification/action/action.go +++ b/modules/notification/action/action.go @@ -91,7 +91,8 @@ func (a *actionNotifier) NotifyIssueChangeStatus(doer *user_model.User, issue *m // NotifyCreateIssueComment notifies comment on an issue to notifiers func (a *actionNotifier) NotifyCreateIssueComment(doer *user_model.User, repo *repo_model.Repository, - issue *models.Issue, comment *models.Comment, mentions []*user_model.User) { + issue *models.Issue, comment *models.Comment, mentions []*user_model.User, +) { act := &models.Action{ ActUserID: doer.ID, ActUser: doer, diff --git a/modules/notification/indexer/indexer.go b/modules/notification/indexer/indexer.go index 26f19e7791e24..48a491f3f18a4 100644 --- a/modules/notification/indexer/indexer.go +++ b/modules/notification/indexer/indexer.go @@ -30,7 +30,8 @@ func NewNotifier() base.Notifier { } func (r *indexerNotifier) NotifyCreateIssueComment(doer *user_model.User, repo *repo_model.Repository, - issue *models.Issue, comment *models.Comment, mentions []*user_model.User) { + issue *models.Issue, comment *models.Comment, mentions []*user_model.User, +) { if comment.Type == models.CommentTypeComment { if issue.Comments == nil { if err := issue.LoadDiscussComments(); err != nil { diff --git a/modules/notification/mail/mail.go b/modules/notification/mail/mail.go index 4ce2726fc68df..b74482fbf7e21 100644 --- a/modules/notification/mail/mail.go +++ b/modules/notification/mail/mail.go @@ -29,7 +29,8 @@ func NewNotifier() base.Notifier { } func (m *mailNotifier) NotifyCreateIssueComment(doer *user_model.User, repo *repo_model.Repository, - issue *models.Issue, comment *models.Comment, mentions []*user_model.User) { + issue *models.Issue, comment *models.Comment, mentions []*user_model.User, +) { ctx, _, finished := process.GetManager().AddContext(graceful.GetManager().HammerContext(), fmt.Sprintf("mailNotifier.NotifyCreateIssueComment Issue[%d] #%d in [%d]", issue.ID, issue.Index, issue.RepoID)) defer finished() diff --git a/modules/notification/notification.go b/modules/notification/notification.go index a0acd01561ac1..e8d5d07b344c8 100644 --- a/modules/notification/notification.go +++ b/modules/notification/notification.go @@ -39,7 +39,8 @@ func NewContext() { // NotifyCreateIssueComment notifies issue comment related message to notifiers func NotifyCreateIssueComment(doer *user_model.User, repo *repo_model.Repository, - issue *models.Issue, comment *models.Comment, mentions []*user_model.User) { + issue *models.Issue, comment *models.Comment, mentions []*user_model.User, +) { for _, notifier := range notifiers { notifier.NotifyCreateIssueComment(doer, repo, issue, comment, mentions) } @@ -201,7 +202,8 @@ func NotifyIssueChangeRef(doer *user_model.User, issue *models.Issue, oldRef str // NotifyIssueChangeLabels notifies change labels to notifiers func NotifyIssueChangeLabels(doer *user_model.User, issue *models.Issue, - addedLabels, removedLabels []*models.Label) { + addedLabels, removedLabels []*models.Label, +) { for _, notifier := range notifiers { notifier.NotifyIssueChangeLabels(doer, issue, addedLabels, removedLabels) } diff --git a/modules/notification/ui/ui.go b/modules/notification/ui/ui.go index 7f6bfa398e3e3..037167f640b02 100644 --- a/modules/notification/ui/ui.go +++ b/modules/notification/ui/ui.go @@ -53,7 +53,8 @@ func (ns *notificationService) Run() { } func (ns *notificationService) NotifyCreateIssueComment(doer *user_model.User, repo *repo_model.Repository, - issue *models.Issue, comment *models.Comment, mentions []*user_model.User) { + issue *models.Issue, comment *models.Comment, mentions []*user_model.User, +) { opts := issueNotificationOpts{ IssueID: issue.ID, NotificationAuthorID: doer.ID, diff --git a/modules/notification/webhook/webhook.go b/modules/notification/webhook/webhook.go index ea70faa3c769a..d4d5eea6cb83d 100644 --- a/modules/notification/webhook/webhook.go +++ b/modules/notification/webhook/webhook.go @@ -424,7 +424,8 @@ func (m *webhookNotifier) NotifyUpdateComment(doer *user_model.User, c *models.C } func (m *webhookNotifier) NotifyCreateIssueComment(doer *user_model.User, repo *repo_model.Repository, - issue *models.Issue, comment *models.Comment, mentions []*user_model.User) { + issue *models.Issue, comment *models.Comment, mentions []*user_model.User, +) { mode, _ := models.AccessLevel(doer, repo) var err error @@ -498,7 +499,8 @@ func (m *webhookNotifier) NotifyDeleteComment(doer *user_model.User, comment *mo } func (m *webhookNotifier) NotifyIssueChangeLabels(doer *user_model.User, issue *models.Issue, - addedLabels, removedLabels []*models.Label) { + addedLabels, removedLabels []*models.Label, +) { ctx, _, finished := process.GetManager().AddContext(graceful.GetManager().HammerContext(), fmt.Sprintf("webhook.NotifyIssueChangeLabels User: %s[%d] Issue[%d] #%d in [%d]", doer.Name, doer.ID, issue.ID, issue.Index, issue.RepoID)) defer finished() diff --git a/modules/structs/repo.go b/modules/structs/repo.go index 5a1e99e36bea8..087ae941f409f 100644 --- a/modules/structs/repo.go +++ b/modules/structs/repo.go @@ -220,7 +220,6 @@ type GenerateRepoOption struct { // CreateBranchRepoOption options when creating a branch in a repository // swagger:model type CreateBranchRepoOption struct { - // Name of the branch to create // // required: true diff --git a/routers/web/repo/branch.go b/routers/web/repo/branch.go index 5d19fd118547a..489ef9a357943 100644 --- a/routers/web/repo/branch.go +++ b/routers/web/repo/branch.go @@ -233,7 +233,8 @@ func loadBranches(ctx *context.Context, skip, limit int) (*Branch, []*Branch, in func loadOneBranch(ctx *context.Context, rawBranch, defaultBranch *git.Branch, protectedBranches []*models.ProtectedBranch, repoIDToRepo map[int64]*repo_model.Repository, - repoIDToGitRepo map[int64]*git.Repository) *Branch { + repoIDToGitRepo map[int64]*git.Repository, +) *Branch { log.Trace("loadOneBranch: '%s'", rawBranch.Name) commit, err := rawBranch.GetCommit() diff --git a/services/mailer/mail.go b/services/mailer/mail.go index d5f3f2ac03798..3983237fc56ae 100644 --- a/services/mailer/mail.go +++ b/services/mailer/mail.go @@ -427,7 +427,8 @@ func SendIssueAssignedMail(issue *models.Issue, doer *user_model.User, content s // actionToTemplate returns the type and name of the action facing the user // (slightly different from models.ActionType) and the name of the template to use (based on availability) func actionToTemplate(issue *models.Issue, actionType models.ActionType, - commentType models.CommentType, reviewType models.ReviewType) (typeName, name, template string) { + commentType models.CommentType, reviewType models.ReviewType, +) (typeName, name, template string) { if issue.IsPull { typeName = "pull" } else { diff --git a/services/release/release.go b/services/release/release.go index 9e3ea3370a5d9..0df8635230f43 100644 --- a/services/release/release.go +++ b/services/release/release.go @@ -186,7 +186,8 @@ func CreateNewTag(ctx context.Context, doer *user_model.User, repo *repo_model.R // delAttachmentUUIDs accept a slice of attachments' uuids which will be deleted from the release // editAttachments accept a map of attachment uuid to new attachment name which will be updated with attachments. func UpdateRelease(doer *user_model.User, gitRepo *git.Repository, rel *models.Release, - addAttachmentUUIDs, delAttachmentUUIDs []string, editAttachments map[string]string) (err error) { + addAttachmentUUIDs, delAttachmentUUIDs []string, editAttachments map[string]string, +) (err error) { if rel.ID == 0 { return errors.New("UpdateRelease only accepts an exist release") } From f7085f718bf58dc5fc2d843ad1b0171b748fc153 Mon Sep 17 00:00:00 2001 From: Kyle D Date: Wed, 23 Feb 2022 13:17:14 -0700 Subject: [PATCH 2/4] Set max text height to prevent overflow (#18862) Sets a max height for review text boxes to prevent a very annoying bug where users cannot access the "submit" button. Before: ![image](https://user-images.githubusercontent.com/12700993/155253001-e1dab086-aaf3-4338-889d-6a861728274a.png) After: ![image](https://user-images.githubusercontent.com/12700993/155253144-5b9a3547-9582-412f-867f-41a45a14a0fe.png) Interestingly, I don't see this bug on Firefox. --- web_src/js/features/repo-issue.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web_src/js/features/repo-issue.js b/web_src/js/features/repo-issue.js index bdb75842f8552..4f791c7704a6b 100644 --- a/web_src/js/features/repo-issue.js +++ b/web_src/js/features/repo-issue.js @@ -462,7 +462,7 @@ export function initRepoPullRequestReview() { (async () => { // the editor's height is too large in some cases, and the panel cannot be scrolled with page now because there is `.repository .diff-detail-box.sticky { position: sticky; }` // the temporary solution is to make the editor's height smaller (about 4 lines). GitHub also only show 4 lines for default. We can improve the UI (including Dropzone area) in future - await createCommentEasyMDE($reviewBox.find('textarea'), {minHeight: '80px'}); + await createCommentEasyMDE($reviewBox.find('textarea'), {minHeight: '80px', maxHeight: 'calc(100vh - 360px)'}); initCompImagePaste($reviewBox); })(); } From cb41f5cae16c5c11cad717c0d19333c2aa4e3b55 Mon Sep 17 00:00:00 2001 From: zeripath Date: Wed, 23 Feb 2022 22:07:05 +0000 Subject: [PATCH 3/4] Update assignees check to include any writing team and change org sidebar (#18680) Following the merging of #17811 teams can now have differing write and readonly permissions, however the assignee list will not include teams which have mixed perms. Further the org sidebar is no longer helpful as it can't describe these mixed permissions situations. Fix #18572 Signed-off-by: Andrew Thornton --- models/repo.go | 51 +++++++++++++++++++------ routers/web/org/teams.go | 2 + templates/org/team/sidebar.tmpl | 68 ++++++++++++++++++++++----------- 3 files changed, 88 insertions(+), 33 deletions(-) diff --git a/models/repo.go b/models/repo.go index 7b0635074c9b0..02e1a33253a1f 100644 --- a/models/repo.go +++ b/models/repo.go @@ -150,27 +150,56 @@ func getRepoAssignees(ctx context.Context, repo *repo_model.Repository) (_ []*us } e := db.GetEngine(ctx) - accesses := make([]*Access, 0, 10) - if err = e. + userIDs := make([]int64, 0, 10) + if err = e.Table("access"). Where("repo_id = ? AND mode >= ?", repo.ID, perm.AccessModeWrite). - Find(&accesses); err != nil { + Select("id"). + Find(&userIDs); err != nil { return nil, err } - // Leave a seat for owner itself to append later, but if owner is an organization - // and just waste 1 unit is cheaper than re-allocate memory once. - users := make([]*user_model.User, 0, len(accesses)+1) - if len(accesses) > 0 { - userIDs := make([]int64, len(accesses)) - for i := 0; i < len(accesses); i++ { - userIDs[i] = accesses[i].UserID + additionalUserIDs := make([]int64, 0, 10) + if err = e.Table("team_user"). + Join("INNER", "team_repo", "`team_repo`.team_id = `team_user`.team_id"). + Join("INNER", "team_unit", "`team_unit`.team_id = `team_user`.team_id"). + Where("`team_repo`.repo_id = ? AND `team_unit`.access_mode >= ?", repo.ID, perm.AccessModeWrite). + Distinct("`team_user`.uid"). + Select("`team_user`.uid"). + Find(&additionalUserIDs); err != nil { + return nil, err + } + + uidMap := map[int64]bool{} + i := 0 + for _, uid := range userIDs { + if uidMap[uid] { + continue + } + uidMap[uid] = true + userIDs[i] = uid + i++ + } + userIDs = userIDs[:i] + userIDs = append(userIDs, additionalUserIDs...) + + for _, uid := range additionalUserIDs { + if uidMap[uid] { + continue } + userIDs[i] = uid + i++ + } + userIDs = userIDs[:i] + // Leave a seat for owner itself to append later, but if owner is an organization + // and just waste 1 unit is cheaper than re-allocate memory once. + users := make([]*user_model.User, 0, len(userIDs)+1) + if len(userIDs) > 0 { if err = e.In("id", userIDs).Find(&users); err != nil { return nil, err } } - if !repo.Owner.IsOrganization() { + if !repo.Owner.IsOrganization() && !uidMap[repo.OwnerID] { users = append(users, repo.Owner) } diff --git a/routers/web/org/teams.go b/routers/web/org/teams.go index 9b0212e56955a..f6e09eb4c8da1 100644 --- a/routers/web/org/teams.go +++ b/routers/web/org/teams.go @@ -311,6 +311,7 @@ func TeamMembers(ctx *context.Context) { ctx.ServerError("GetMembers", err) return } + ctx.Data["Units"] = unit_model.Units ctx.HTML(http.StatusOK, tplTeamMembers) } @@ -323,6 +324,7 @@ func TeamRepositories(ctx *context.Context) { ctx.ServerError("GetRepositories", err) return } + ctx.Data["Units"] = unit_model.Units ctx.HTML(http.StatusOK, tplTeamRepositories) } diff --git a/templates/org/team/sidebar.tmpl b/templates/org/team/sidebar.tmpl index 6ea08740f714d..2dec681b4c633 100644 --- a/templates/org/team/sidebar.tmpl +++ b/templates/org/team/sidebar.tmpl @@ -25,31 +25,55 @@ {{.i18n.Tr "org.teams.no_desc"}} {{end}} - -
- {{if eq .Team.LowerName "owners"}} + {{if eq .Team.LowerName "owners"}} +
{{.i18n.Tr "org.teams.owners_permission_desc" | Str2html}} - {{else if (eq .Team.AccessMode 1)}} - {{if .Team.IncludesAllRepositories}} - {{.i18n.Tr "org.teams.all_repositories_read_permission_desc" | Str2html}} - {{else}} - {{.i18n.Tr "org.teams.read_permission_desc" | Str2html}} - {{end}} - {{else if (eq .Team.AccessMode 2)}} - {{if .Team.IncludesAllRepositories}} - {{.i18n.Tr "org.teams.all_repositories_write_permission_desc" | Str2html}} +
+ {{else}} +
+

{{.i18n.Tr "org.team_access_desc"}}

+
    + {{if .Team.IncludesAllRepositories}} +
  • {{.i18n.Tr "org.teams.all_repositories" | Str2html}} + {{else}} +
  • {{.i18n.Tr "org.teams.specific_repositories" | Str2html}} + {{end}} + {{if .Team.CanCreateOrgRepo}} +
  • {{.i18n.Tr "org.teams.can_create_org_repo"}} + {{end}} +
+ {{if (eq .Team.AccessMode 2)}} +

{{.i18n.Tr "org.settings.permission"}}

+ {{.i18n.Tr "org.teams.write_permission_desc"}} + {{else if (eq .Team.AccessMode 3)}} +

{{.i18n.Tr "org.settings.permission"}}

+ {{.i18n.Tr "org.teams.admin_permission_desc"}} {{else}} - {{.i18n.Tr "org.teams.write_permission_desc" | Str2html}} + + + + + + + + + {{range $t, $unit := $.Units}} + {{if and (lt $unit.MaxPerm 2) (not $unit.Type.UnitGlobalDisabled)}} + + + + + {{end}} + {{end}} + +
{{.i18n.Tr "units.unit"}}{{.i18n.Tr "org.team_permission_desc"}}
{{$.i18n.Tr $unit.NameKey}}{{if eq ($.Team.UnitAccessMode $unit.Type) 0 -}} + {{$.i18n.Tr "org.teams.none_access"}} + {{- else if or (eq $.Team.ID 0) (eq ($.Team.UnitAccessMode $unit.Type) 1) -}} + {{$.i18n.Tr "org.teams.read_access"}} + {{- else if eq ($.Team.UnitAccessMode $unit.Type) 2 -}} + {{$.i18n.Tr "org.teams.write_access"}} + {{- end}}
{{end}} - {{else if (eq .Team.AccessMode 3)}} - {{if .Team.IncludesAllRepositories}} - {{.i18n.Tr "org.teams.all_repositories_admin_permission_desc" | Str2html}} - {{else}} - {{.i18n.Tr "org.teams.admin_permission_desc" | Str2html}} - {{end}} - {{end}} - {{if .Team.CanCreateOrgRepo}} -

{{.i18n.Tr "org.teams.create_repo_permission_desc" | Str2html}} {{end}}
From f1b1472632e36c3bb5df73f184a6efeef47f5d01 Mon Sep 17 00:00:00 2001 From: Lunny Xiao Date: Thu, 24 Feb 2022 14:13:59 +0800 Subject: [PATCH 4/4] Fix ldap user sync missed email in email_address table (#18786) * Fix ldap user sync missed email in email_address table * Fix test --- models/user/user.go | 30 ++++++++++++++++++++---- services/auth/source/ldap/source_sync.go | 3 ++- 2 files changed, 27 insertions(+), 6 deletions(-) diff --git a/models/user/user.go b/models/user/user.go index b61ffd707248e..d0f1d9d747779 100644 --- a/models/user/user.go +++ b/models/user/user.go @@ -827,8 +827,9 @@ func validateUser(u *User) error { return ValidateEmail(u.Email) } -func updateUser(ctx context.Context, u *User, changePrimaryEmail bool) error { - if err := validateUser(u); err != nil { +func updateUser(ctx context.Context, u *User, changePrimaryEmail bool, cols ...string) error { + err := validateUser(u) + if err != nil { return err } @@ -860,15 +861,34 @@ func updateUser(ctx context.Context, u *User, changePrimaryEmail bool) error { }); err != nil { return err } + } else { // check if primary email in email_address table + primaryEmailExist, err := e.Where("uid=? AND is_primary=?", u.ID, true).Exist(&EmailAddress{}) + if err != nil { + return err + } + + if !primaryEmailExist { + _, err = e.Insert(&EmailAddress{ + Email: u.Email, + UID: u.ID, + IsActivated: true, + IsPrimary: true, + }) + return err + } } - _, err := e.ID(u.ID).AllCols().Update(u) + if len(cols) == 0 { + _, err = e.ID(u.ID).AllCols().Update(u) + } else { + _, err = e.ID(u.ID).Cols(cols...).Update(u) + } return err } // UpdateUser updates user's information. -func UpdateUser(u *User, emailChanged bool) error { - return updateUser(db.DefaultContext, u, emailChanged) +func UpdateUser(u *User, emailChanged bool, cols ...string) error { + return updateUser(db.DefaultContext, u, emailChanged, cols...) } // UpdateUserCols update user according special columns diff --git a/services/auth/source/ldap/source_sync.go b/services/auth/source/ldap/source_sync.go index 74a62ce4e72dc..0d4d94a3ad565 100644 --- a/services/auth/source/ldap/source_sync.go +++ b/services/auth/source/ldap/source_sync.go @@ -146,6 +146,7 @@ func (source *Source) Sync(ctx context.Context, updateExisting bool) error { log.Trace("SyncExternalUsers[%s]: Updating user %s", source.authSource.Name, usr.Name) usr.FullName = fullName + emailChanged := usr.Email != su.Mail usr.Email = su.Mail // Change existing admin flag only if AdminFilter option is set if len(source.AdminFilter) > 0 { @@ -157,7 +158,7 @@ func (source *Source) Sync(ctx context.Context, updateExisting bool) error { } usr.IsActive = true - err = user_model.UpdateUserCols(db.DefaultContext, usr, "full_name", "email", "is_admin", "is_restricted", "is_active") + err = user_model.UpdateUser(usr, emailChanged, "full_name", "email", "is_admin", "is_restricted", "is_active") if err != nil { log.Error("SyncExternalUsers[%s]: Error updating user %s: %v", source.authSource.Name, usr.Name, err) }