fix(deploy): complete DingTalk runtime configuration

Signed-off-by: XiaoSeS <87064762+XiaoSeS@users.noreply.github.com>
This commit is contained in:
XiaoSeS 2026-09-21 15:02:43 +08:00
parent d92e1f8216
commit 1297e87c5a
12 changed files with 86 additions and 4 deletions

View file

@ -146,6 +146,8 @@ OAUTH2_DINGTALK_CLIENT_ID=
OAUTH2_DINGTALK_CLIENT_SECRET=
OAUTH2_DINGTALK_AUTHORIZE_URI=https://login.dingtalk.com
OAUTH2_DINGTALK_BASE_URI=https://api.dingtalk.com
# Optional; defaults to {baseUrl}/login/oauth2/code/dingtalk.
OAUTH2_DINGTALK_REDIRECT_URI=
OAUTH2_DINGTALK_DISPLAY_NAME=钉钉
# Optional: OIDC login (e.g. Keycloak, Okta, Azure AD).

View file

@ -394,6 +394,16 @@ spec:
name: {{ include "skillhub.secretName" . }}
key: oauth2-dingtalk-client-secret
optional: true
- name: OAUTH2_DINGTALK_AUTHORIZE_URI
value: {{ .Values.oauth2.dingtalk.authorizeBaseUri | quote }}
- name: OAUTH2_DINGTALK_BASE_URI
value: {{ .Values.oauth2.dingtalk.apiBaseUri | quote }}
{{- with .Values.oauth2.dingtalk.redirectUri }}
- name: OAUTH2_DINGTALK_REDIRECT_URI
value: {{ . | quote }}
{{- end }}
- name: OAUTH2_DINGTALK_DISPLAY_NAME
value: {{ .Values.oauth2.dingtalk.displayName | quote }}
{{- if .Values.server.javaOpts }}
- name: JAVA_OPTS

View file

@ -42,6 +42,9 @@ grep -A1 -F 'name: SKILLHUB_SUITE_REVIEW_WRITES_ENABLED' "$TMP_DIR/default.yaml"
if grep -Fq 'name: OAUTH2_FEISHU_REDIRECT_URI' "$TMP_DIR/default.yaml"; then
fail "default Helm rendering must omit an empty Feishu redirect URI so Spring can derive baseUrl"
fi
if grep -Fq 'name: OAUTH2_DINGTALK_REDIRECT_URI' "$TMP_DIR/default.yaml"; then
fail "default Helm rendering must omit an empty DingTalk redirect URI so Spring can derive baseUrl"
fi
render feishu-redirect "$CHART_DIR" \
--set-string oauth2.feishu.redirectUri=https://skills.example.com/login/oauth2/code/feishu \
@ -50,6 +53,13 @@ grep -A1 -F 'name: OAUTH2_FEISHU_REDIRECT_URI' "$TMP_DIR/feishu-redirect.yaml" \
| grep -Fq 'value: "https://skills.example.com/login/oauth2/code/feishu"' \
|| fail "Helm must inject an explicitly configured Feishu redirect URI"
render dingtalk-redirect "$CHART_DIR" \
--set-string oauth2.dingtalk.redirectUri=https://skills.example.com/login/oauth2/code/dingtalk \
--show-only templates/server-deployment.yaml >"$TMP_DIR/dingtalk-redirect.yaml"
grep -A1 -F 'name: OAUTH2_DINGTALK_REDIRECT_URI' "$TMP_DIR/dingtalk-redirect.yaml" \
| grep -Fq 'value: "https://skills.example.com/login/oauth2/code/dingtalk"' \
|| fail "Helm must inject an explicitly configured DingTalk redirect URI"
render suite-review-enabled "$CHART_DIR" \
--set server.suiteReviewWritesEnabled=true \
--show-only templates/server-deployment.yaml >"$TMP_DIR/suite-review-enabled.yaml"

View file

@ -37,7 +37,7 @@
"oauth2": {
"type": "object",
"additionalProperties": false,
"required": ["feishu"],
"required": ["feishu", "dingtalk"],
"properties": {
"feishu": {
"type": "object",
@ -50,6 +50,17 @@
"userInfoUri": { "type": "string", "format": "uri" },
"redirectUri": { "type": "string" }
}
},
"dingtalk": {
"type": "object",
"additionalProperties": false,
"required": ["authorizeBaseUri", "apiBaseUri", "redirectUri", "displayName"],
"properties": {
"authorizeBaseUri": { "type": "string", "format": "uri" },
"apiBaseUri": { "type": "string", "format": "uri" },
"redirectUri": { "type": "string" },
"displayName": { "type": "string", "minLength": 1 }
}
}
}
},

View file

@ -29,6 +29,11 @@ oauth2:
tokenUri: https://accounts.feishu.cn/oauth/v3/token
userInfoUri: https://open.feishu.cn/open-apis/authen/v1/user_info
redirectUri: ""
dingtalk:
authorizeBaseUri: https://login.dingtalk.com
apiBaseUri: https://api.dingtalk.com
redirectUri: ""
displayName: 钉钉
builtinSkills:
enabled: true

View file

@ -132,6 +132,7 @@ services:
OAUTH2_DINGTALK_CLIENT_SECRET: ${OAUTH2_DINGTALK_CLIENT_SECRET:-local-placeholder}
OAUTH2_DINGTALK_AUTHORIZE_URI: ${OAUTH2_DINGTALK_AUTHORIZE_URI:-https://login.dingtalk.com}
OAUTH2_DINGTALK_BASE_URI: ${OAUTH2_DINGTALK_BASE_URI:-https://api.dingtalk.com}
OAUTH2_DINGTALK_REDIRECT_URI: ${OAUTH2_DINGTALK_REDIRECT_URI:-${SKILLHUB_PUBLIC_BASE_URL:-http://localhost}/login/oauth2/code/dingtalk}
OAUTH2_DINGTALK_DISPLAY_NAME: ${OAUTH2_DINGTALK_DISPLAY_NAME:-钉钉}
SPRING_MAIL_HOST: ${SPRING_MAIL_HOST:-}
SPRING_MAIL_PORT: ${SPRING_MAIL_PORT:-25}

View file

@ -262,6 +262,12 @@ spec:
name: skillhub-secret
key: oauth2-dingtalk-client-secret
optional: true
- name: OAUTH2_DINGTALK_AUTHORIZE_URI
value: "https://login.dingtalk.com"
- name: OAUTH2_DINGTALK_BASE_URI
value: "https://api.dingtalk.com"
- name: OAUTH2_DINGTALK_DISPLAY_NAME
value: "钉钉"
volumeMounts:
- name: skillhub-storage
mountPath: /var/lib/skillhub/storage

View file

@ -288,7 +288,9 @@ spring:
# 故意不声明 scope钉钉的授权端点要 scope=openid但在这里声明会让
# Spring 把该注册当成 OIDC 客户端并附加 nonce而钉钉不接受 nonce。
# scope 由 DingTalkAuthorizationRequestCustomizer 在请求阶段补上。
client-authentication-method: none
# 钉钉是 confidential client只是由自定义 token client 把 secret 放进 JSON body。
# 不使用 none避免 Spring 自动添加本实现无法应答的 PKCE challenge。
client-authentication-method: client_secret_post
authorization-grant-type: authorization_code
provider:
feishu:

View file

@ -315,7 +315,12 @@ services:
exchange 的 endpoint。`OAUTH2_FEISHU_PROTOCOL_VERSION` 只允许 `v2``v3`
默认 `v3`,不会自动 fallback。
- 钉钉:`OAUTH2_DINGTALK_CLIENT_ID` / `OAUTH2_DINGTALK_CLIENT_SECRET`
(分别填应用的 AppKey 与 AppSecret
(分别填应用的 AppKey 与 AppSecret。在钉钉开发者后台登记
`https://<公网域名>/login/oauth2/code/dingtalk`,并为用户信息接口开通所需权限。
`OAUTH2_DINGTALK_REDIRECT_URI` 可在动态端口或特殊反向代理场景显式覆盖Compose
默认根据 `SKILLHUB_PUBLIC_BASE_URL` 生成回调Helm/K8s 未设置时由 Spring 使用
`{baseUrl}`。国际版或网关场景可覆盖 `OAUTH2_DINGTALK_AUTHORIZE_URI`
`OAUTH2_DINGTALK_BASE_URI`
留空即不展示该入口,无需改配置文件。注意:飞书和钉钉的邮箱都由企业管理员导入、
未经用户确认,因此 `emailVerified` 恒为 false若在 `application.yml` 中把

View file

@ -107,6 +107,27 @@ write_env "$invalid_feishu_redirect_env" "release-download-secret-32-bytes-minim
printf '%s\n' "OAUTH2_FEISHU_REDIRECT_URI=https://skillhub.example.com/login/oauth2/code/feishu?bad=1" >>"$invalid_feishu_redirect_env"
expect_fail "$invalid_feishu_redirect_env" "OAUTH2_FEISHU_REDIRECT_URI must not contain a query"
valid_dingtalk_env="$tmp/valid-dingtalk.env"
write_env "$valid_dingtalk_env" "release-download-secret-32-bytes-minimum"
cat >>"$valid_dingtalk_env" <<'EOF'
OAUTH2_DINGTALK_CLIENT_ID=ding-test
OAUTH2_DINGTALK_CLIENT_SECRET=dingtalk-test-secret
OAUTH2_DINGTALK_AUTHORIZE_URI=https://login.dingtalk.com
OAUTH2_DINGTALK_BASE_URI=https://api.dingtalk.com
OAUTH2_DINGTALK_REDIRECT_URI=https://skillhub.example.com/login/oauth2/code/dingtalk
EOF
"$SCRIPT" "$valid_dingtalk_env" >/dev/null
invalid_dingtalk_base_env="$tmp/invalid-dingtalk-base.env"
write_env "$invalid_dingtalk_base_env" "release-download-secret-32-bytes-minimum"
printf '%s\n' "OAUTH2_DINGTALK_BASE_URI=https://api.dingtalk.com/" >>"$invalid_dingtalk_base_env"
expect_fail "$invalid_dingtalk_base_env" "OAUTH2_DINGTALK_BASE_URI must not have a trailing slash"
invalid_dingtalk_redirect_env="$tmp/invalid-dingtalk-redirect.env"
write_env "$invalid_dingtalk_redirect_env" "release-download-secret-32-bytes-minimum"
printf '%s\n' "OAUTH2_DINGTALK_REDIRECT_URI=https://skillhub.example.com/callback?bad=1" >>"$invalid_dingtalk_redirect_env"
expect_fail "$invalid_dingtalk_redirect_env" "OAUTH2_DINGTALK_REDIRECT_URI must not contain a query"
disabled_builtin_skills_env="$tmp/disabled-builtin-skills.env"
write_env "$disabled_builtin_skills_env" "release-download-secret-32-bytes-minimum"
printf '%s\n' "SKILLHUB_BUILTIN_SKILLS_ENABLED=false" >>"$disabled_builtin_skills_env"

View file

@ -406,6 +406,15 @@ for feishu_endpoint in OAUTH2_FEISHU_AUTHORIZATION_URI OAUTH2_FEISHU_TOKEN_URI O
fi
done
for dingtalk_endpoint in OAUTH2_DINGTALK_AUTHORIZE_URI OAUTH2_DINGTALK_BASE_URI OAUTH2_DINGTALK_REDIRECT_URI; do
eval "dingtalk_endpoint_value=\${$dingtalk_endpoint:-}"
if [ -n "$dingtalk_endpoint_value" ]; then
validate_url "$dingtalk_endpoint"
fi
done
validate_no_trailing_slash OAUTH2_DINGTALK_AUTHORIZE_URI
validate_no_trailing_slash OAUTH2_DINGTALK_BASE_URI
if [ "$errors" -gt 0 ]; then
echo "Release config validation failed: $errors error(s), $warnings warning(s)." >&2
exit 1

View file

@ -58,7 +58,7 @@ spring:
scope:
- read:user
- user:email
redirect-uri: "{baseUrl}/login/oauth2/code/{registrationId}"
redirect-uri: "${OAUTH2_DINGTALK_REDIRECT_URI:{baseUrl}/login/oauth2/code/{registrationId}}"
client-name: GitHub
authorization-grant-type: authorization_code
gitlab: