mirror of
https://github.com/iflytek/skillhub.git
synced 2026-08-27 11:14:59 +00:00
fix(auth): enable local bootstrap admin by default (#141)
* feat(profile): add field policy config and GET response Add per-field edit policy configuration (editable, requiresReview) to application.yml and expose it in the GET /api/v1/user/profile response via a new fieldPolicies map, enabling the frontend to dynamically render fields based on backend-driven policies. * feat(profile): implement mixed submission in PATCH Split profile update changes by per-field policy: fields without requiresReview apply immediately, fields with requiresReview enter the pending queue. Return PARTIALLY_APPLIED status with appliedFields and pendingFields maps when both paths trigger in a single request. * feat(web): rewrite profile page with dynamic fields Render profile fields dynamically from backend fieldPolicies, with whole-page read/edit mode toggle. Handle APPLIED, PENDING_REVIEW, and PARTIALLY_APPLIED responses. Add i18n keys for review hints and partial-apply toasts in both en and zh. * merge: resolve deepwiki.yml conflict with package-lock.json fix * api schema * fix(profile): align moderation defaults and tests * ci(deepwiki): run crawler on release publish * fix(auth): enable local bootstrap admin by default
This commit is contained in:
parent
611d67f845
commit
b9b8ca22f1
10 changed files with 131 additions and 7 deletions
16
README.md
16
README.md
|
|
@ -99,18 +99,26 @@ Then open:
|
|||
- Web UI: `http://localhost:3000`
|
||||
- Backend API: `http://localhost:8080`
|
||||
|
||||
Local profile seeds two mock-auth users automatically:
|
||||
By default, `make dev-all` starts the backend with the `local` profile.
|
||||
In that mode, local development keeps the mock-auth users below and also
|
||||
creates a password-based bootstrap admin account by default:
|
||||
|
||||
- `local-user` for normal publishing and namespace operations
|
||||
- `local-admin` with `SUPER_ADMIN` for review and admin flows
|
||||
|
||||
Use them with the `X-Mock-User-Id` header in local development.
|
||||
|
||||
The backend can bootstrap a local-login super admin for first-time access
|
||||
when you explicitly set `BOOTSTRAP_ADMIN_ENABLED=true`:
|
||||
The local bootstrap admin is enabled by default in `application-local.yml`:
|
||||
|
||||
- username: `BOOTSTRAP_ADMIN_USERNAME` (`admin` by default)
|
||||
- password: `BOOTSTRAP_ADMIN_PASSWORD` (`ChangeMe!2026` by default)
|
||||
- password: `BOOTSTRAP_ADMIN_PASSWORD`
|
||||
In local app-level fallback it is `ChangeMe!2026`.
|
||||
- For local source startup, set the environment variable
|
||||
`BOOTSTRAP_ADMIN_ENABLED=false` before starting the backend.
|
||||
- For container or release environments, configure the same value in
|
||||
`.env.release` or the Compose environment.
|
||||
- The shipped release template still uses `replace-this-admin-password` and
|
||||
must be changed before first login.
|
||||
|
||||
Stop everything with:
|
||||
|
||||
|
|
|
|||
12
README_zh.md
12
README_zh.md
|
|
@ -67,12 +67,22 @@ curl -fsSL https://imageless.oss-cn-beijing.aliyuncs.com/runtime.sh | sh -s -- u
|
|||
|
||||
### 默认账户
|
||||
|
||||
本地开发环境提供两个模拟用户:
|
||||
默认执行 `make dev-all` 时,后端以 `local` profile 启动。
|
||||
在这个模式下,本地开发会保留下面两个模拟用户,同时默认创建一个可账号密码登录的 bootstrap 管理员:
|
||||
|
||||
- `local-user` — 普通用户,用于发布和命名空间操作
|
||||
- `local-admin` — 超级管理员,用于审核和管理流程
|
||||
|
||||
在本地开发中使用 `X-Mock-User-Id` 请求头切换用户。
|
||||
本地 bootstrap 管理员默认已在 `application-local.yml` 中开启,本地登录账号来自以下配置:
|
||||
|
||||
- 用户名:`BOOTSTRAP_ADMIN_USERNAME`,默认是 `admin`
|
||||
- 密码:`BOOTSTRAP_ADMIN_PASSWORD`
|
||||
- 本地应用默认回退值是 `ChangeMe!2026`
|
||||
- 本地源码启动如需关闭自动创建,请在启动后端前设置环境变量
|
||||
`BOOTSTRAP_ADMIN_ENABLED=false`
|
||||
- 容器或发布环境则在 `.env.release` 或 Compose 环境变量中配置该值
|
||||
- 发布模板 `.env.release.example` 里的占位值仍然是 `replace-this-admin-password`
|
||||
|
||||
### 停止服务
|
||||
|
||||
|
|
|
|||
|
|
@ -60,6 +60,7 @@
|
|||
- `BOOTSTRAP_ADMIN_ENABLED=true`
|
||||
- `BOOTSTRAP_ADMIN_USERNAME`
|
||||
- `BOOTSTRAP_ADMIN_PASSWORD`
|
||||
- 从 `.env.release.example` 复制时,初始占位值是 `replace-this-admin-password`
|
||||
|
||||
建议:
|
||||
|
||||
|
|
@ -210,6 +211,7 @@ docker compose --env-file .env.release -f compose.release.yml up -d
|
|||
- 按云厂商 OSS / S3 兼容参数填写 `SKILLHUB_STORAGE_S3_*`
|
||||
- 设置非默认的 `POSTGRES_PASSWORD`
|
||||
- 如果要启用首登管理员,再额外设置 `BOOTSTRAP_ADMIN_ENABLED=true` 与非默认的 `BOOTSTRAP_ADMIN_PASSWORD`
|
||||
- 不要直接保留模板里的 `replace-this-admin-password`
|
||||
3. 启动前校验
|
||||
- 运行 `make validate-release-config`
|
||||
- 确认没有 `replace-me`、`change-this-*`、`ChangeMe!2026` 之类的占位值
|
||||
|
|
|
|||
|
|
@ -49,6 +49,15 @@ Two mock users are available in local mode (no password needed):
|
|||
| `local-user` | Regular user | `X-Mock-User-Id: local-user` |
|
||||
| `local-admin` | Super admin | `X-Mock-User-Id: local-admin` |
|
||||
|
||||
Local development also creates a password-based bootstrap admin by default.
|
||||
Use `BOOTSTRAP_ADMIN_USERNAME` / `BOOTSTRAP_ADMIN_PASSWORD` to log in through
|
||||
the normal local account form. The default local fallback credentials are
|
||||
`admin` / `ChangeMe!2026`.
|
||||
To disable it for local source startup, set the environment variable
|
||||
`BOOTSTRAP_ADMIN_ENABLED=false` before starting the backend.
|
||||
For container or release environments, set the same value in `.env.release`
|
||||
or the Compose environment.
|
||||
|
||||
### Useful commands
|
||||
|
||||
| Command | Description |
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@ make dev-all
|
|||
|
||||
## 开发用户
|
||||
|
||||
本地开发环境预置了两个测试用户:
|
||||
默认本地开发环境预置了两个模拟测试用户:
|
||||
|
||||
| 用户 | 角色 | 说明 |
|
||||
|------|------|------|
|
||||
|
|
@ -42,6 +42,14 @@ make dev-all
|
|||
| `local-admin` | 超级管理员 | 拥有所有权限,包括审核和用户管理 |
|
||||
|
||||
使用 `X-Mock-User-Id` 请求头在本地开发中模拟用户登录。
|
||||
本地开发环境还会默认创建可密码登录的 bootstrap 管理员账号:
|
||||
|
||||
- 用户名:`admin`
|
||||
- 密码:`ChangeMe!2026`
|
||||
|
||||
本地源码启动如需覆盖或关闭,请在启动后端前设置 `BOOTSTRAP_ADMIN_*`
|
||||
环境变量。
|
||||
容器或发布环境则通过 `.env.release` 或 Compose 环境变量配置。
|
||||
|
||||
## 常用命令
|
||||
|
||||
|
|
|
|||
|
|
@ -55,6 +55,7 @@ curl -i http://127.0.0.1:8080/actuator/health
|
|||
## 首登配置
|
||||
|
||||
1. 使用 `BOOTSTRAP_ADMIN_USERNAME` 和 `BOOTSTRAP_ADMIN_PASSWORD` 登录
|
||||
从 `.env.release.example` 复制配置时,默认占位值是 `replace-this-admin-password`,需要先改掉
|
||||
2. 立即修改管理员密码
|
||||
3. 配置企业 SSO(可选)
|
||||
4. 创建团队命名空间
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@ After successful startup, you can access through the following addresses:
|
|||
|
||||
## Development Users
|
||||
|
||||
The local development environment comes with two test users:
|
||||
By default, the local development environment comes with two mock test users:
|
||||
|
||||
| User | Role | Description |
|
||||
|------|------|-------------|
|
||||
|
|
@ -42,6 +42,16 @@ The local development environment comes with two test users:
|
|||
| `local-admin` | Super admin | Has all permissions including review and user management |
|
||||
|
||||
Use the `X-Mock-User-Id` request header to simulate user login in local development.
|
||||
The local development environment also creates a password-based bootstrap
|
||||
admin by default:
|
||||
|
||||
- username: `admin`
|
||||
- password: `ChangeMe!2026`
|
||||
|
||||
For local source startup, override or disable it with `BOOTSTRAP_ADMIN_*`
|
||||
environment variables before starting the backend.
|
||||
For container or release environments, configure the same values in
|
||||
`.env.release` or the Compose environment.
|
||||
|
||||
## Common Commands
|
||||
|
||||
|
|
|
|||
|
|
@ -55,6 +55,7 @@ curl -i http://127.0.0.1:8080/actuator/health
|
|||
## First Login Configuration
|
||||
|
||||
1. Login with `BOOTSTRAP_ADMIN_USERNAME` and `BOOTSTRAP_ADMIN_PASSWORD`
|
||||
When copied from `.env.release.example`, the shipped placeholder is `replace-this-admin-password`, so change it before first login
|
||||
2. Change admin password immediately
|
||||
3. Configure enterprise SSO (optional)
|
||||
4. Create team namespaces
|
||||
|
|
|
|||
|
|
@ -27,6 +27,9 @@ skillhub:
|
|||
auth:
|
||||
mock:
|
||||
enabled: true
|
||||
bootstrap:
|
||||
admin:
|
||||
enabled: ${BOOTSTRAP_ADMIN_ENABLED:true}
|
||||
profile:
|
||||
moderation:
|
||||
machine-review: ${SKILLHUB_PROFILE_MACHINE_REVIEW_ENABLED:true}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,72 @@
|
|||
package com.iflytek.skillhub.config;
|
||||
|
||||
import com.iflytek.skillhub.bootstrap.BootstrapAdminProperties;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.boot.context.properties.bind.Binder;
|
||||
import org.springframework.boot.context.properties.source.ConfigurationPropertySources;
|
||||
import org.springframework.boot.env.YamlPropertySourceLoader;
|
||||
import org.springframework.core.env.ConfigurableEnvironment;
|
||||
import org.springframework.core.env.StandardEnvironment;
|
||||
import org.springframework.core.env.SystemEnvironmentPropertySource;
|
||||
import org.springframework.core.io.ClassPathResource;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
class BootstrapAdminPropertiesBindingTest {
|
||||
|
||||
@Test
|
||||
void defaultConfig_keepsBootstrapAdminDisabled() throws IOException {
|
||||
BootstrapAdminProperties properties = bindProperties(
|
||||
List.of("application.yml"),
|
||||
Map.of()
|
||||
);
|
||||
|
||||
assertFalse(properties.isEnabled());
|
||||
}
|
||||
|
||||
@Test
|
||||
void localProfile_enablesBootstrapAdminByDefault() throws IOException {
|
||||
BootstrapAdminProperties properties = bindProperties(
|
||||
List.of("application-local.yml", "application.yml"),
|
||||
Map.of()
|
||||
);
|
||||
|
||||
assertTrue(properties.isEnabled());
|
||||
}
|
||||
|
||||
@Test
|
||||
void localProfile_allowsEnvironmentVariablesToDisableBootstrapAdmin() throws IOException {
|
||||
BootstrapAdminProperties properties = bindProperties(
|
||||
List.of("application-local.yml", "application.yml"),
|
||||
Map.of("BOOTSTRAP_ADMIN_ENABLED", "false")
|
||||
);
|
||||
|
||||
assertFalse(properties.isEnabled());
|
||||
}
|
||||
|
||||
private BootstrapAdminProperties bindProperties(List<String> resourceNames,
|
||||
Map<String, Object> envVars) throws IOException {
|
||||
ConfigurableEnvironment environment = new StandardEnvironment();
|
||||
environment.getPropertySources().addFirst(new SystemEnvironmentPropertySource("test-env", envVars));
|
||||
|
||||
YamlPropertySourceLoader loader = new YamlPropertySourceLoader();
|
||||
for (String resourceName : resourceNames) {
|
||||
List<org.springframework.core.env.PropertySource<?>> propertySources = loader.load(
|
||||
resourceName,
|
||||
new ClassPathResource(resourceName)
|
||||
);
|
||||
for (org.springframework.core.env.PropertySource<?> propertySource : propertySources) {
|
||||
environment.getPropertySources().addLast(propertySource);
|
||||
}
|
||||
}
|
||||
ConfigurationPropertySources.attach(environment);
|
||||
|
||||
return Binder.get(environment)
|
||||
.bind("skillhub.bootstrap.admin", BootstrapAdminProperties.class)
|
||||
.orElseThrow(() -> new IllegalStateException("Failed to bind bootstrap admin properties"));
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Reference in a new issue