diff --git a/custom/conf/app.example.ini b/custom/conf/app.example.ini index dc5aa691ee3c5..17d6cd3a35e02 100644 --- a/custom/conf/app.example.ini +++ b/custom/conf/app.example.ini @@ -1480,8 +1480,9 @@ LEVEL = Info ;; ;; Default configuration for email notifications for users (user configurable). Options: enabled, onmention, disabled ;DEFAULT_EMAIL_NOTIFICATIONS = enabled -;; Disabled features for users, could be "deletion","manage_gpg_keys" more features can be disabled in future +;; Disabled features for users, could be "deletion", "manage_ssh_keys","manage_gpg_keys" more features can be disabled in future ;; - deletion: a user cannot delete their own account +;; - manage_ssh_keys: a user cannot configure ssh keys ;; - manage_gpg_keys: a user cannot configure gpg keys ;USER_DISABLED_FEATURES = diff --git a/docs/content/administration/config-cheat-sheet.en-us.md b/docs/content/administration/config-cheat-sheet.en-us.md index ea6e1eb1a4dd4..8a01711949a30 100644 --- a/docs/content/administration/config-cheat-sheet.en-us.md +++ b/docs/content/administration/config-cheat-sheet.en-us.md @@ -518,9 +518,10 @@ And the following unique queues: - `DEFAULT_EMAIL_NOTIFICATIONS`: **enabled**: Default configuration for email notifications for users (user configurable). Options: enabled, onmention, disabled - `DISABLE_REGULAR_ORG_CREATION`: **false**: Disallow regular (non-admin) users from creating organizations. -- `USER_DISABLED_FEATURES`: **_empty_** Disabled features for users, could be `deletion`, `manage_gpg_keys` and more features can be added in future. +- `USER_DISABLED_FEATURES`: **_empty_** Disabled features for users, could be `deletion`, `manage_ssh_keys`, `manage_gpg_keys` and more features can be added in future. - `deletion`: User cannot delete their own account. - - `manage_gpg_keys`: User cannot configure gpg keys + - `manage_ssh_keys`: User cannot configure ssh keys. + - `manage_gpg_keys`: User cannot configure gpg keys. ## Security (`security`) diff --git a/docs/content/administration/config-cheat-sheet.zh-cn.md b/docs/content/administration/config-cheat-sheet.zh-cn.md index 5cc5734359065..7b102eda8e12d 100644 --- a/docs/content/administration/config-cheat-sheet.zh-cn.md +++ b/docs/content/administration/config-cheat-sheet.zh-cn.md @@ -497,9 +497,10 @@ Gitea 创建以下非唯一队列: - `DEFAULT_EMAIL_NOTIFICATIONS`: **enabled**:用户电子邮件通知的默认配置(用户可配置)。选项:enabled、onmention、disabled - `DISABLE_REGULAR_ORG_CREATION`: **false**:禁止普通(非管理员)用户创建组织。 -- `USER_DISABLED_FEATURES`:**_empty_** 禁用的用户特性,当前允许为空或者 `deletion`,`manage_gpg_keys` 未来可以增加更多设置。 +- `USER_DISABLED_FEATURES`:**_empty_** 禁用的用户特性,当前允许为空或者 `deletion`,`manage_ssh_keys`, `manage_gpg_keys` 未来可以增加更多设置。 - `deletion`: 用户不能通过界面或者API删除他自己。 - - `manage_gpg_keys`: 用户不能配置 GPG 密钥 + - `manage_ssh_keys`: 用户不能通过界面或者API配置SSH Keys。 + - `manage_gpg_keys`: 用户不能配置 GPG 密钥。 ## 安全性 (`security`) diff --git a/modules/setting/admin.go b/modules/setting/admin.go index 29bb947bc4780..be214a58ce408 100644 --- a/modules/setting/admin.go +++ b/modules/setting/admin.go @@ -21,5 +21,6 @@ func loadAdminFrom(rootCfg ConfigProvider) { const ( UserFeatureDeletion = "deletion" + UserFeatureManageSSHKeys = "manage_ssh_keys" UserFeatureManageGPGKeys = "manage_gpg_keys" ) diff --git a/package-lock.json b/package-lock.json index fbd0153e118c0..0c8a53a8ef053 100644 --- a/package-lock.json +++ b/package-lock.json @@ -24,7 +24,6 @@ "chartjs-plugin-zoom": "2.0.1", "clippie": "4.0.7", "css-loader": "6.10.0", - "css-variables-parser": "1.0.1", "dayjs": "1.11.10", "dropzone": "6.0.0-beta.2", "easymde": "2.18.0", @@ -4032,35 +4031,6 @@ "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0" } }, - "node_modules/css-variables-parser": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/css-variables-parser/-/css-variables-parser-1.0.1.tgz", - "integrity": "sha512-GWaqrwGtAWVr/yjjE17iyvbcy+W3voe0vko1/xLCwFeYd3kTLstzUdVH+g5TTXejrtlsb1FS4L9rP6PmeTa8wQ==", - "dependencies": { - "postcss": "^7.0.36" - } - }, - "node_modules/css-variables-parser/node_modules/picocolors": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz", - "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==" - }, - "node_modules/css-variables-parser/node_modules/postcss": { - "version": "7.0.39", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz", - "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==", - "dependencies": { - "picocolors": "^0.2.1", - "source-map": "^0.6.1" - }, - "engines": { - "node": ">=6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - } - }, "node_modules/css-what": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.1.0.tgz", diff --git a/package.json b/package.json index 1152bfef72a55..d5e8170228c8b 100644 --- a/package.json +++ b/package.json @@ -23,7 +23,6 @@ "chartjs-plugin-zoom": "2.0.1", "clippie": "4.0.7", "css-loader": "6.10.0", - "css-variables-parser": "1.0.1", "dayjs": "1.11.10", "dropzone": "6.0.0-beta.2", "easymde": "2.18.0", diff --git a/routers/api/v1/user/key.go b/routers/api/v1/user/key.go index ada6759f8e6c5..bcbfd93bd3ede 100644 --- a/routers/api/v1/user/key.go +++ b/routers/api/v1/user/key.go @@ -5,6 +5,7 @@ package user import ( std_ctx "context" + "fmt" "net/http" asymkey_model "code.gitea.io/gitea/models/asymkey" @@ -198,6 +199,11 @@ func GetPublicKey(ctx *context.APIContext) { // CreateUserPublicKey creates new public key to given user by ID. func CreateUserPublicKey(ctx *context.APIContext, form api.CreateKeyOption, uid int64) { + if setting.Admin.UserDisabledFeatures.Contains(setting.UserFeatureManageSSHKeys) { + ctx.NotFound("Not Found", fmt.Errorf("ssh keys setting is not allowed to be visited")) + return + } + content, err := asymkey_model.CheckPublicKeyString(form.Key) if err != nil { repo.HandleCheckKeyStringError(ctx, err) @@ -263,6 +269,11 @@ func DeletePublicKey(ctx *context.APIContext) { // "404": // "$ref": "#/responses/notFound" + if setting.Admin.UserDisabledFeatures.Contains(setting.UserFeatureManageSSHKeys) { + ctx.NotFound("Not Found", fmt.Errorf("ssh keys setting is not allowed to be visited")) + return + } + id := ctx.ParamsInt64(":id") externallyManaged, err := asymkey_model.PublicKeyIsExternallyManaged(ctx, id) if err != nil { diff --git a/routers/web/user/setting/keys.go b/routers/web/user/setting/keys.go index cb01913bdafb2..d2b60fc809e31 100644 --- a/routers/web/user/setting/keys.go +++ b/routers/web/user/setting/keys.go @@ -159,6 +159,11 @@ func KeysPost(ctx *context.Context) { ctx.Flash.Success(ctx.Tr("settings.verify_gpg_key_success", keyID)) ctx.Redirect(setting.AppSubURL + "/user/settings/keys") case "ssh": + if setting.Admin.UserDisabledFeatures.Contains(setting.UserFeatureManageSSHKeys) { + ctx.NotFound("Not Found", fmt.Errorf("ssh keys setting is not allowed to be visited")) + return + } + content, err := asymkey_model.CheckPublicKeyString(form.Content) if err != nil { if db.IsErrSSHDisabled(err) { @@ -198,6 +203,11 @@ func KeysPost(ctx *context.Context) { ctx.Flash.Success(ctx.Tr("settings.add_key_success", form.Title)) ctx.Redirect(setting.AppSubURL + "/user/settings/keys") case "verify_ssh": + if setting.Admin.UserDisabledFeatures.Contains(setting.UserFeatureManageSSHKeys) { + ctx.NotFound("Not Found", fmt.Errorf("ssh keys setting is not allowed to be visited")) + return + } + token := asymkey_model.VerificationToken(ctx.Doer, 1) lastToken := asymkey_model.VerificationToken(ctx.Doer, 0) @@ -240,6 +250,11 @@ func DeleteKey(ctx *context.Context) { ctx.Flash.Success(ctx.Tr("settings.gpg_key_deletion_success")) } case "ssh": + if setting.Admin.UserDisabledFeatures.Contains(setting.UserFeatureManageSSHKeys) { + ctx.NotFound("Not Found", fmt.Errorf("ssh keys setting is not allowed to be visited")) + return + } + keyID := ctx.FormInt64("id") external, err := asymkey_model.PublicKeyIsExternallyManaged(ctx, keyID) if err != nil { @@ -318,4 +333,5 @@ func loadKeysData(ctx *context.Context) { ctx.Data["VerifyingID"] = ctx.FormString("verify_gpg") ctx.Data["VerifyingFingerprint"] = ctx.FormString("verify_ssh") + ctx.Data["UserDisabledFeatures"] = &setting.Admin.UserDisabledFeatures } diff --git a/tailwind.config.js b/tailwind.config.js index 7f36822001b66..fb17980568cb2 100644 --- a/tailwind.config.js +++ b/tailwind.config.js @@ -1,9 +1,28 @@ import {readFileSync} from 'node:fs'; import {env} from 'node:process'; -import {parse} from 'css-variables-parser'; +import {parse} from 'postcss'; const isProduction = env.NODE_ENV !== 'development'; +function extractRootVars(css) { + const root = parse(css); + const vars = new Set(); + root.walkRules((rule) => { + if (rule.selector !== ':root') return; + rule.each((decl) => { + if (decl.value && decl.prop.startsWith('--')) { + vars.add(decl.prop.substring(2)); + } + }); + }); + return Array.from(vars); +} + +const vars = extractRootVars([ + readFileSync(new URL('web_src/css/themes/theme-gitea-light.css', import.meta.url), 'utf8'), + readFileSync(new URL('web_src/css/themes/theme-gitea-dark.css', import.meta.url), 'utf8'), +].join('\n')); + export default { prefix: 'tw-', important: true, // the frameworks are mixed together, so tailwind needs to override other framework's styles @@ -23,15 +42,10 @@ export default { theme: { colors: { // make `tw-bg-red` etc work with our CSS variables - ...Object.fromEntries( - Object.keys(parse([ - readFileSync(new URL('web_src/css/themes/theme-gitea-light.css', import.meta.url), 'utf8'), - readFileSync(new URL('web_src/css/themes/theme-gitea-dark.css', import.meta.url), 'utf8'), - ].join('\n'), {})).filter((prop) => prop.startsWith('color-')).map((prop) => { - const color = prop.substring(6); - return [color, `var(--color-${color})`]; - }) - ), + ...Object.fromEntries(vars.filter((prop) => prop.startsWith('color-')).map((prop) => { + const color = prop.substring(6); + return [color, `var(--color-${color})`]; + })), inherit: 'inherit', current: 'currentcolor', transparent: 'transparent', diff --git a/templates/user/settings/keys.tmpl b/templates/user/settings/keys.tmpl index a44bf5004827a..e0f5e426ae45a 100644 --- a/templates/user/settings/keys.tmpl +++ b/templates/user/settings/keys.tmpl @@ -1,6 +1,8 @@ {{template "user/settings/layout_head" (dict "ctxData" . "pageClass" "user settings sshkeys")}}