mirror of
https://codeberg.org/forgejo/forgejo.git
synced 2026-06-07 00:32:07 -04:00
feat: add ability for admins to mark account as bot
This commit is contained in:
parent
26f18a94ee
commit
fc296cdd8d
11 changed files with 41 additions and 14 deletions
|
|
@ -48,7 +48,7 @@ type SearchUserOptions struct {
|
|||
func (opts *SearchUserOptions) toSearchQueryBase(ctx context.Context) *xorm.Session {
|
||||
var cond builder.Cond
|
||||
if opts.Type == UserTypeIndividual {
|
||||
cond = builder.In("type", UserTypeIndividual, UserTypeRemoteUser)
|
||||
cond = builder.In("type", UserTypeIndividual, UserTypeBot, UserTypeRemoteUser)
|
||||
} else {
|
||||
cond = builder.Eq{"type": opts.Type}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -222,6 +222,8 @@
|
|||
"admin.users.list_status_filter.not_prohibit_login": "Allow login",
|
||||
"admin.users.list_status_filter.is_2fa_enabled": "2FA enabled",
|
||||
"admin.users.list_status_filter.not_2fa_enabled": "2FA disabled",
|
||||
"admin.users.is_bot": "Bot account",
|
||||
"admin.users.bot.description": "Mark the account as a bot.",
|
||||
"admin.monitor.queues": "Queues",
|
||||
"admin.monitor.queue": "Queue: %s",
|
||||
"admin.monitor.queue.name": "Name",
|
||||
|
|
|
|||
|
|
@ -455,6 +455,7 @@ func EditUserPost(ctx *context.Context) {
|
|||
Visibility: optional.Some(form.Visibility),
|
||||
Language: optional.Some(form.Language),
|
||||
KeepEmailPrivate: optional.Some(form.HideEmail),
|
||||
IsBot: optional.Some(form.Bot),
|
||||
}
|
||||
|
||||
if err := user_service.UpdateUser(ctx, u, opts); err != nil {
|
||||
|
|
|
|||
|
|
@ -421,7 +421,7 @@ func Action(ctx *context.Context) {
|
|||
}
|
||||
}
|
||||
|
||||
if ctx.ContextUser.IsIndividual() {
|
||||
if ctx.ContextUser.IsUser() {
|
||||
shared_user.PrepareContextForProfileBigAvatar(ctx)
|
||||
ctx.Data["IsHTMX"] = true
|
||||
ctx.HTML(http.StatusOK, tplProfileBigAvatar)
|
||||
|
|
|
|||
|
|
@ -943,9 +943,9 @@ func registerRoutes(m *web.Route) {
|
|||
reqRepoProjectsReader(ctx)
|
||||
}
|
||||
|
||||
individualPermsChecker := func(ctx *context.Context) {
|
||||
// org permissions have been checked in context.OrgAssignment(), but individual permissions haven't been checked.
|
||||
if ctx.ContextUser.IsIndividual() {
|
||||
userPermsChecker := func(ctx *context.Context) {
|
||||
// org permissions have been checked in context.OrgAssignment(), but user permissions haven't been checked.
|
||||
if ctx.ContextUser.IsUser() {
|
||||
switch ctx.ContextUser.Visibility {
|
||||
case structs.VisibleTypePrivate:
|
||||
if ctx.Doer == nil || (ctx.ContextUser.ID != ctx.Doer.ID && !ctx.Doer.IsAdmin) {
|
||||
|
|
@ -1148,11 +1148,11 @@ func registerRoutes(m *web.Route) {
|
|||
return
|
||||
}
|
||||
})
|
||||
}, reqUnitAccess(unit.TypeProjects, perm.AccessModeRead, true), individualPermsChecker)
|
||||
}, reqUnitAccess(unit.TypeProjects, perm.AccessModeRead, true), userPermsChecker)
|
||||
|
||||
m.Group("", func() {
|
||||
m.Get("/code", user.CodeSearch)
|
||||
}, reqUnitAccess(unit.TypeCode, perm.AccessModeRead, false), individualPermsChecker)
|
||||
}, reqUnitAccess(unit.TypeCode, perm.AccessModeRead, false), userPermsChecker)
|
||||
}, ignSignIn, context.UserAssignmentWeb(), context.OrgAssignment()) // for "/{username}/-" (packages, projects, code)
|
||||
|
||||
m.Group("/{username}/{reponame}", func() {
|
||||
|
|
|
|||
|
|
@ -47,6 +47,7 @@ type AdminEditUserForm struct {
|
|||
Active bool
|
||||
Admin bool
|
||||
Restricted bool
|
||||
Bot bool
|
||||
AllowGitHook bool
|
||||
AllowImportLocal bool
|
||||
AllowCreateOrganization bool
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ package user
|
|||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"forgejo.org/models"
|
||||
|
|
@ -41,10 +42,11 @@ type UpdateOptions struct {
|
|||
RepoAdminChangeTeamAccess optional.Option[bool]
|
||||
EnableRepoUnitHints optional.Option[bool]
|
||||
KeepPronounsPrivate optional.Option[bool]
|
||||
IsBot optional.Option[bool]
|
||||
}
|
||||
|
||||
func UpdateUser(ctx context.Context, u *user_model.User, opts *UpdateOptions) error {
|
||||
cols := make([]string, 0, 20)
|
||||
cols := make([]string, 0, 21)
|
||||
|
||||
if has, value := opts.KeepEmailPrivate.Get(); has {
|
||||
u.KeepEmailPrivate = value
|
||||
|
|
@ -144,6 +146,17 @@ func UpdateUser(ctx context.Context, u *user_model.User, opts *UpdateOptions) er
|
|||
u.SetLastLogin()
|
||||
cols = append(cols, "last_login_unix")
|
||||
}
|
||||
if has, value := opts.IsBot.Get(); has {
|
||||
if !u.IsUser() {
|
||||
return errors.New("changing to bot account for non user account is not allowed")
|
||||
}
|
||||
if value {
|
||||
u.Type = user_model.UserTypeBot
|
||||
} else {
|
||||
u.Type = user_model.UserTypeIndividual
|
||||
}
|
||||
cols = append(cols, "type")
|
||||
}
|
||||
|
||||
return user_model.UpdateUserCols(ctx, u, cols...)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -135,6 +135,13 @@
|
|||
</div>
|
||||
<span class="help tw-block">{{ctx.Locale.Tr "admin.users.admin.description"}}</span>
|
||||
</div>
|
||||
<div class="inline field">
|
||||
<div class="ui checkbox">
|
||||
<label>{{ctx.Locale.Tr "admin.users.is_bot"}}</label>
|
||||
<input name="bot" type="checkbox" {{if .User.IsBot}}checked{{end}}>
|
||||
</div>
|
||||
<span class="help tw-block">{{ctx.Locale.Tr "admin.users.bot.description"}}</span>
|
||||
</div>
|
||||
<div class="inline field">
|
||||
<div class="ui checkbox">
|
||||
<label>{{ctx.Locale.Tr "admin.users.is_restricted"}}</label>
|
||||
|
|
|
|||
|
|
@ -9,6 +9,9 @@
|
|||
{{if .User.IsAdmin}}
|
||||
<span class="ui basic label">{{ctx.Locale.Tr "admin.users.admin"}}</span>
|
||||
{{end}}
|
||||
{{if .User.IsBot}}
|
||||
<span class="ui basic label">{{ctx.Locale.Tr "admin.users.bot"}}</span>
|
||||
{{end}}
|
||||
</div>
|
||||
<div class="flex-item-body">
|
||||
<b>{{ctx.Locale.Tr "admin.users.auth_source"}}:</b>
|
||||
|
|
|
|||
|
|
@ -3,5 +3,5 @@
|
|||
data-tooltip-content="{{ctx.Locale.Tr "user.ghost.tooltip"}}">Ghost</a>
|
||||
{{else}}
|
||||
<a class="author text black tw-font-semibold muted"{{if gt .ID 0}} href="{{.HomeLink}}"{{end}}>{{.GetDisplayName}}</a>
|
||||
{{if .IsBot}}<span class="ui basic label tw-p-1 tw-align-baseline">bot</span>{{end}}
|
||||
{{if .IsBot}}<span class="ui basic label tw-p-1 tw-align-baseline">{{ctx.Locale.Tr "admin.users.bot"}}</span>{{end}}
|
||||
{{end}}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
<overflow-menu class="ui secondary pointing tabular borderless menu">
|
||||
<div class="overflow-menu-items">
|
||||
{{if and .HasProfileReadme .ContextUser.IsIndividual}}
|
||||
{{if and .HasProfileReadme .ContextUser.IsUser}}
|
||||
<a class="{{if eq .TabName "overview"}}active {{end}}item" href="{{.ContextUser.HomeLink}}?tab=overview">
|
||||
{{svg "octicon-info"}} {{ctx.Locale.Tr "user.overview"}}
|
||||
</a>
|
||||
|
|
@ -12,7 +12,7 @@
|
|||
{{end}}
|
||||
<span hidden test-name="repository-count">{{.RepoCount}}</span>
|
||||
</a>
|
||||
{{if or .ContextUser.IsIndividual .CanReadProjects}}
|
||||
{{if or .ContextUser.IsUser .CanReadProjects}}
|
||||
<a href="{{.ContextUser.HomeLink}}/-/projects" class="{{if .PageIsViewProjects}}active {{end}}item">
|
||||
{{svg "octicon-project-symlink"}} {{ctx.Locale.Tr "user.projects"}}
|
||||
{{if .ProjectCount}}
|
||||
|
|
@ -21,7 +21,7 @@
|
|||
<span hidden test-name="project-count">{{.ProjectCount}}</span>
|
||||
</a>
|
||||
{{end}}
|
||||
{{if and .IsPackageEnabled (or .ContextUser.IsIndividual .CanReadPackages)}}
|
||||
{{if and .IsPackageEnabled (or .ContextUser.IsUser .CanReadPackages)}}
|
||||
<a href="{{.ContextUser.HomeLink}}/-/packages" class="{{if .IsPackagesPage}}active {{end}}item">
|
||||
{{svg "octicon-package"}} {{ctx.Locale.Tr "packages.title"}}
|
||||
{{if .PackageCount}}
|
||||
|
|
@ -30,12 +30,12 @@
|
|||
<span hidden test-name="package-count">{{.PackageCount}}</span>
|
||||
</a>
|
||||
{{end}}
|
||||
{{if and .IsRepoIndexerEnabled (or .ContextUser.IsIndividual .CanReadCode)}}
|
||||
{{if and .IsRepoIndexerEnabled (or .ContextUser.IsUser .CanReadCode)}}
|
||||
<a href="{{.ContextUser.HomeLink}}/-/code" class="{{if .IsCodePage}}active {{end}}item">
|
||||
{{svg "octicon-code"}} {{ctx.Locale.Tr "user.code"}}
|
||||
</a>
|
||||
{{end}}
|
||||
{{if .ContextUser.IsIndividual}}
|
||||
{{if .ContextUser.IsUser}}
|
||||
{{if or (eq .TabName "activity") .IsAdmin (eq .SignedUserID .ContextUser.ID) (not .ContextUser.KeepActivityPrivate)}}
|
||||
<a class="{{if eq .TabName "activity"}}active {{end}}item" href="{{.ContextUser.HomeLink}}?tab=activity">
|
||||
{{svg "octicon-rss"}} {{ctx.Locale.Tr "user.activity"}}
|
||||
|
|
|
|||
Loading…
Reference in a new issue