refactor: Migrate OIDC configuration to system settings

This commit is contained in:
1808837298@qq.com
2025-03-11 22:00:31 +08:00
parent c433af284c
commit 66682584a5
7 changed files with 85 additions and 81 deletions

View File

@@ -43,7 +43,6 @@ var PasswordLoginEnabled = true
var PasswordRegisterEnabled = true var PasswordRegisterEnabled = true
var EmailVerificationEnabled = false var EmailVerificationEnabled = false
var GitHubOAuthEnabled = false var GitHubOAuthEnabled = false
var OIDCEnabled = false
var LinuxDOOAuthEnabled = false var LinuxDOOAuthEnabled = false
var WeChatAuthEnabled = false var WeChatAuthEnabled = false
var TelegramOAuthEnabled = false var TelegramOAuthEnabled = false
@@ -78,14 +77,6 @@ var SMTPToken = ""
var GitHubClientId = "" var GitHubClientId = ""
var GitHubClientSecret = "" var GitHubClientSecret = ""
var OIDCClientId = ""
var OIDCClientSecret = ""
var OIDCWellKnown = ""
var OIDCAuthorizationEndpoint = ""
var OIDCTokenEndpoint = ""
var OIDCUserInfoEndpoint = ""
var LinuxDOClientId = "" var LinuxDOClientId = ""
var LinuxDOClientSecret = "" var LinuxDOClientSecret = ""

View File

@@ -8,6 +8,7 @@ import (
"one-api/model" "one-api/model"
"one-api/setting" "one-api/setting"
"one-api/setting/operation_setting" "one-api/setting/operation_setting"
"one-api/setting/system_setting"
"strings" "strings"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
@@ -68,9 +69,9 @@ func GetStatus(c *gin.Context) {
"chats": setting.Chats, "chats": setting.Chats,
"demo_site_enabled": operation_setting.DemoSiteEnabled, "demo_site_enabled": operation_setting.DemoSiteEnabled,
"self_use_mode_enabled": operation_setting.SelfUseModeEnabled, "self_use_mode_enabled": operation_setting.SelfUseModeEnabled,
"oidc": common.OIDCEnabled, "oidc_enabled": system_setting.GetOIDCSettings().Enabled,
"oidc_client_id": common.OIDCClientId, "oidc_client_id": system_setting.GetOIDCSettings().ClientId,
"oidc_authorization_endpoint": common.OIDCAuthorizationEndpoint, "oidc_authorization_endpoint": system_setting.GetOIDCSettings().AuthorizationEndpoint,
}, },
}) })
return return

View File

@@ -9,6 +9,7 @@ import (
"one-api/common" "one-api/common"
"one-api/model" "one-api/model"
"one-api/setting" "one-api/setting"
"one-api/setting/system_setting"
"strconv" "strconv"
"strings" "strings"
"time" "time"
@@ -40,13 +41,13 @@ func getOidcUserInfoByCode(code string) (*OidcUser, error) {
} }
values := url.Values{} values := url.Values{}
values.Set("client_id", common.OIDCClientId) values.Set("client_id", system_setting.GetOIDCSettings().ClientId)
values.Set("client_secret", common.OIDCClientSecret) values.Set("client_secret", system_setting.GetOIDCSettings().ClientSecret)
values.Set("code", code) values.Set("code", code)
values.Set("grant_type", "authorization_code") values.Set("grant_type", "authorization_code")
values.Set("redirect_uri", fmt.Sprintf("%s/oauth/oidc", setting.ServerAddress)) values.Set("redirect_uri", fmt.Sprintf("%s/oauth/oidc", setting.ServerAddress))
formData := values.Encode() formData := values.Encode()
req, err := http.NewRequest("POST", common.OIDCTokenEndpoint, strings.NewReader(formData)) req, err := http.NewRequest("POST", system_setting.GetOIDCSettings().TokenEndpoint, strings.NewReader(formData))
if err != nil { if err != nil {
return nil, err return nil, err
} }
@@ -72,7 +73,7 @@ func getOidcUserInfoByCode(code string) (*OidcUser, error) {
return nil, errors.New("OIDC 获取 Token 失败,请检查设置!") return nil, errors.New("OIDC 获取 Token 失败,请检查设置!")
} }
req, err = http.NewRequest("GET", common.OIDCUserInfoEndpoint, nil) req, err = http.NewRequest("GET", system_setting.GetOIDCSettings().UserInfoEndpoint, nil)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@@ -115,7 +116,7 @@ func OidcAuth(c *gin.Context) {
OidcBind(c) OidcBind(c)
return return
} }
if !common.OIDCEnabled { if !system_setting.GetOIDCSettings().Enabled {
c.JSON(http.StatusOK, gin.H{ c.JSON(http.StatusOK, gin.H{
"success": false, "success": false,
"message": "管理员未开启通过 OIDC 登录以及注册", "message": "管理员未开启通过 OIDC 登录以及注册",
@@ -184,7 +185,7 @@ func OidcAuth(c *gin.Context) {
} }
func OidcBind(c *gin.Context) { func OidcBind(c *gin.Context) {
if !common.OIDCEnabled { if !system_setting.GetOIDCSettings().Enabled {
c.JSON(http.StatusOK, gin.H{ c.JSON(http.StatusOK, gin.H{
"success": false, "success": false,
"message": "管理员未开启通过 OIDC 登录以及注册", "message": "管理员未开启通过 OIDC 登录以及注册",

View File

@@ -6,6 +6,7 @@ import (
"one-api/common" "one-api/common"
"one-api/model" "one-api/model"
"one-api/setting" "one-api/setting"
"one-api/setting/system_setting"
"strings" "strings"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
@@ -51,8 +52,8 @@ func UpdateOption(c *gin.Context) {
}) })
return return
} }
case "OIDCEnabled": case "oidc.enabled":
if option.Value == "true" && common.OIDCClientId == "" { if option.Value == "true" && system_setting.GetOIDCSettings().Enabled {
c.JSON(http.StatusOK, gin.H{ c.JSON(http.StatusOK, gin.H{
"success": false, "success": false,
"message": "无法启用 OIDC 登录,请先填入 OIDC Client Id 以及 OIDC Client Secret", "message": "无法启用 OIDC 登录,请先填入 OIDC Client Id 以及 OIDC Client Secret",

View File

@@ -35,7 +35,6 @@ func InitOptionMap() {
common.OptionMap["PasswordRegisterEnabled"] = strconv.FormatBool(common.PasswordRegisterEnabled) common.OptionMap["PasswordRegisterEnabled"] = strconv.FormatBool(common.PasswordRegisterEnabled)
common.OptionMap["EmailVerificationEnabled"] = strconv.FormatBool(common.EmailVerificationEnabled) common.OptionMap["EmailVerificationEnabled"] = strconv.FormatBool(common.EmailVerificationEnabled)
common.OptionMap["GitHubOAuthEnabled"] = strconv.FormatBool(common.GitHubOAuthEnabled) common.OptionMap["GitHubOAuthEnabled"] = strconv.FormatBool(common.GitHubOAuthEnabled)
common.OptionMap["OIDCEnabled"] = strconv.FormatBool(common.OIDCEnabled)
common.OptionMap["LinuxDOOAuthEnabled"] = strconv.FormatBool(common.LinuxDOOAuthEnabled) common.OptionMap["LinuxDOOAuthEnabled"] = strconv.FormatBool(common.LinuxDOOAuthEnabled)
common.OptionMap["TelegramOAuthEnabled"] = strconv.FormatBool(common.TelegramOAuthEnabled) common.OptionMap["TelegramOAuthEnabled"] = strconv.FormatBool(common.TelegramOAuthEnabled)
common.OptionMap["WeChatAuthEnabled"] = strconv.FormatBool(common.WeChatAuthEnabled) common.OptionMap["WeChatAuthEnabled"] = strconv.FormatBool(common.WeChatAuthEnabled)
@@ -207,8 +206,6 @@ func updateOptionMap(key string, value string) (err error) {
common.EmailVerificationEnabled = boolValue common.EmailVerificationEnabled = boolValue
case "GitHubOAuthEnabled": case "GitHubOAuthEnabled":
common.GitHubOAuthEnabled = boolValue common.GitHubOAuthEnabled = boolValue
case "OIDCEnabled":
common.OIDCEnabled = boolValue
case "LinuxDOOAuthEnabled": case "LinuxDOOAuthEnabled":
common.LinuxDOOAuthEnabled = boolValue common.LinuxDOOAuthEnabled = boolValue
case "WeChatAuthEnabled": case "WeChatAuthEnabled":
@@ -307,18 +304,6 @@ func updateOptionMap(key string, value string) (err error) {
common.GitHubClientId = value common.GitHubClientId = value
case "GitHubClientSecret": case "GitHubClientSecret":
common.GitHubClientSecret = value common.GitHubClientSecret = value
case "OIDCClientId":
common.OIDCClientId = value
case "OIDCClientSecret":
common.OIDCClientSecret = value
case "OIDCWellKnown":
common.OIDCWellKnown = value
case "OIDCAuthorizationEndpoint":
common.OIDCAuthorizationEndpoint = value
case "OIDCTokenEndpoint":
common.OIDCTokenEndpoint = value
case "OIDCUserInfoEndpoint":
common.OIDCUserInfoEndpoint = value
case "LinuxDOClientId": case "LinuxDOClientId":
common.LinuxDOClientId = value common.LinuxDOClientId = value
case "LinuxDOClientSecret": case "LinuxDOClientSecret":

View File

@@ -0,0 +1,25 @@
package system_setting
import "one-api/setting/config"
type OIDCSettings struct {
Enabled bool `json:"enabled"`
ClientId string `json:"client_id"`
ClientSecret string `json:"client_secret"`
WellKnown string `json:"well_known"`
AuthorizationEndpoint string `json:"authorization_endpoint"`
TokenEndpoint string `json:"token_endpoint"`
UserInfoEndpoint string `json:"user_info_endpoint"`
}
// 默认配置
var defaultOIDCSettings = OIDCSettings{}
func init() {
// 注册到全局配置管理器
config.GlobalConfig.Register("oidc", &defaultOIDCSettings)
}
func GetOIDCSettings() *OIDCSettings {
return &defaultOIDCSettings
}

View File

@@ -20,13 +20,13 @@ const SystemSetting = () => {
GitHubOAuthEnabled: '', GitHubOAuthEnabled: '',
GitHubClientId: '', GitHubClientId: '',
GitHubClientSecret: '', GitHubClientSecret: '',
OIDCEnabled: '', 'oidc.enabled': '',
OIDCClientId: '', 'oidc.client_id': '',
OIDCClientSecret: '', 'oidc.client_secret': '',
OIDCWellKnown: '', 'oidc.well_known': '',
OIDCAuthorizationEndpoint: '', 'oidc.authorization_endpoint': '',
OIDCTokenEndpoint: '', 'oidc.token_endpoint': '',
OIDCUserInfoEndpoint: '', 'oidc.user_info_endpoint': '',
Notice: '', Notice: '',
SMTPServer: '', SMTPServer: '',
SMTPPort: '', SMTPPort: '',
@@ -113,7 +113,7 @@ const SystemSetting = () => {
case 'PasswordRegisterEnabled': case 'PasswordRegisterEnabled':
case 'EmailVerificationEnabled': case 'EmailVerificationEnabled':
case 'GitHubOAuthEnabled': case 'GitHubOAuthEnabled':
case 'OIDCEnabled': case 'oidc.enabled':
case 'LinuxDOOAuthEnabled': case 'LinuxDOOAuthEnabled':
case 'WeChatAuthEnabled': case 'WeChatAuthEnabled':
case 'TelegramOAuthEnabled': case 'TelegramOAuthEnabled':
@@ -167,12 +167,12 @@ const SystemSetting = () => {
name === 'PayAddress' || name === 'PayAddress' ||
name === 'GitHubClientId' || name === 'GitHubClientId' ||
name === 'GitHubClientSecret' || name === 'GitHubClientSecret' ||
name === 'OIDCWellKnown' || name === 'oidc.well_known' ||
name === 'OIDCClientId' || name === 'oidc.client_id' ||
name === 'OIDCClientSecret' || name === 'oidc.client_secret' ||
name === 'OIDCAuthorizationEndpoint' || name === 'oidc.authorization_endpoint' ||
name === 'OIDCTokenEndpoint' || name === 'oidc.token_endpoint' ||
name === 'OIDCUserInfoEndpoint' || name === 'oidc.user_info_endpoint' ||
name === 'WeChatServerAddress' || name === 'WeChatServerAddress' ||
name === 'WeChatServerToken' || name === 'WeChatServerToken' ||
name === 'WeChatAccountQRCodeImageURL' || name === 'WeChatAccountQRCodeImageURL' ||
@@ -301,39 +301,39 @@ const SystemSetting = () => {
}; };
const submitOIDCSettings = async () => { const submitOIDCSettings = async () => {
if (inputs.OIDCWellKnown !== '') { if (inputs['oidc.well_known'] !== '') {
if (!inputs.OIDCWellKnown.startsWith('http://') && !inputs.OIDCWellKnown.startsWith('https://')) { if (!inputs['oidc.well_known'].startsWith('http://') && !inputs['oidc.well_known'].startsWith('https://')) {
showError('Well-Known URL 必须以 http:// 或 https:// 开头'); showError('Well-Known URL 必须以 http:// 或 https:// 开头');
return; return;
} }
try { try {
const res = await API.get(inputs.OIDCWellKnown); const res = await API.get(inputs['oidc.well_known']);
inputs.OIDCAuthorizationEndpoint = res.data['authorization_endpoint']; inputs['oidc.authorization_endpoint'] = res.data['authorization_endpoint'];
inputs.OIDCTokenEndpoint = res.data['token_endpoint']; inputs['oidc.token_endpoint'] = res.data['token_endpoint'];
inputs.OIDCUserInfoEndpoint = res.data['userinfo_endpoint']; inputs['oidc.user_info_endpoint'] = res.data['userinfo_endpoint'];
showSuccess('获取 OIDC 配置成功!'); showSuccess('获取 OIDC 配置成功!');
} catch (err) { } catch (err) {
showError("获取 OIDC 配置失败,请检查网络状况和 Well-Known URL 是否正确"); showError("获取 OIDC 配置失败,请检查网络状况和 Well-Known URL 是否正确");
} }
} }
if (originInputs['OIDCWellKnown'] !== inputs.OIDCWellKnown) { if (originInputs['oidc.well_known'] !== inputs['oidc.well_known']) {
await updateOption('OIDCWellKnown', inputs.OIDCWellKnown); await updateOption('oidc.well_known', inputs['oidc.well_known']);
} }
if (originInputs['OIDCClientId'] !== inputs.OIDCClientId) { if (originInputs['oidc.client_id'] !== inputs['oidc.client_id']) {
await updateOption('OIDCClientId', inputs.OIDCClientId); await updateOption('oidc.client_id', inputs['oidc.client_id']);
} }
if (originInputs['OIDCClientSecret'] !== inputs.OIDCClientSecret && inputs.OIDCClientSecret !== '') { if (originInputs['oidc.client_secret'] !== inputs['oidc.client_secret'] && inputs['oidc.client_secret'] !== '') {
await updateOption('OIDCClientSecret', inputs.OIDCClientSecret); await updateOption('oidc.client_secret', inputs['oidc.client_secret']);
} }
if (originInputs['OIDCAuthorizationEndpoint'] !== inputs.OIDCAuthorizationEndpoint) { if (originInputs['oidc.authorization_endpoint'] !== inputs['oidc.authorization_endpoint']) {
await updateOption('OIDCAuthorizationEndpoint', inputs.OIDCAuthorizationEndpoint); await updateOption('oidc.authorization_endpoint', inputs['oidc.authorization_endpoint']);
} }
if (originInputs['OIDCTokenEndpoint'] !== inputs.OIDCTokenEndpoint) { if (originInputs['oidc.token_endpoint'] !== inputs['oidc.token_endpoint']) {
await updateOption('OIDCTokenEndpoint', inputs.OIDCTokenEndpoint); await updateOption('oidc.token_endpoint', inputs['oidc.token_endpoint']);
} }
if (originInputs['OIDCUserInfoEndpoint'] !== inputs.OIDCUserInfoEndpoint) { if (originInputs['oidc.user_info_endpoint'] !== inputs['oidc.user_info_endpoint']) {
await updateOption('OIDCUserInfoEndpoint', inputs.OIDCUserInfoEndpoint); await updateOption('oidc.user_info_endpoint', inputs['oidc.user_info_endpoint']);
} }
} }
@@ -570,9 +570,9 @@ const SystemSetting = () => {
onChange={handleInputChange} onChange={handleInputChange}
/> />
<Form.Checkbox <Form.Checkbox
checked={inputs.OIDCEnabled === 'true'} checked={inputs['oidc.enabled'] === 'true'}
label='允许通过 OIDC 登录 & 注册' label='允许通过 OIDC 登录 & 注册'
name='OIDCEnabled' name='oidc.enabled'
onChange={handleInputChange} onChange={handleInputChange}
/> />
<Form.Checkbox <Form.Checkbox
@@ -938,45 +938,45 @@ const SystemSetting = () => {
<Form.Group widths={3}> <Form.Group widths={3}>
<Form.Input <Form.Input
label='Client ID' label='Client ID'
name='OIDCClientId' name='oidc.client_id'
onChange={handleInputChange} onChange={handleInputChange}
value={inputs.OIDCClientId} value={inputs['oidc.client_id']}
placeholder='输入 OIDC 的 Client ID' placeholder='输入 OIDC 的 Client ID'
/> />
<Form.Input <Form.Input
label='Client Secret' label='Client Secret'
name='OIDCClientSecret' name='oidc.client_secret'
onChange={handleInputChange} onChange={handleInputChange}
type='password' type='password'
value={inputs.OIDCClientSecret} value={inputs['oidc.client_secret']}
placeholder='敏感信息不会发送到前端显示' placeholder='敏感信息不会发送到前端显示'
/> />
<Form.Input <Form.Input
label='Well-Known URL' label='Well-Known URL'
name='OIDCWellKnown' name='oidc.well_known'
onChange={handleInputChange} onChange={handleInputChange}
value={inputs.OIDCWellKnown} value={inputs['oidc.well_known']}
placeholder='请输入 OIDC 的 Well-Known URL' placeholder='请输入 OIDC 的 Well-Known URL'
/> />
<Form.Input <Form.Input
label='Authorization Endpoint' label='Authorization Endpoint'
name='OIDCAuthorizationEndpoint' name='oidc.authorization_endpoint'
onChange={handleInputChange} onChange={handleInputChange}
value={inputs.OIDCAuthorizationEndpoint} value={inputs['oidc.authorization_endpoint']}
placeholder='输入 OIDC 的 Authorization Endpoint' placeholder='输入 OIDC 的 Authorization Endpoint'
/> />
<Form.Input <Form.Input
label='Token Endpoint' label='Token Endpoint'
name='OIDCTokenEndpoint' name='oidc.token_endpoint'
onChange={handleInputChange} onChange={handleInputChange}
value={inputs.OIDCTokenEndpoint} value={inputs['oidc.token_endpoint']}
placeholder='输入 OIDC 的 Token Endpoint' placeholder='输入 OIDC 的 Token Endpoint'
/> />
<Form.Input <Form.Input
label='Userinfo Endpoint' label='Userinfo Endpoint'
name='OIDCUserInfoEndpoint' name='oidc.user_info_endpoint'
onChange={handleInputChange} onChange={handleInputChange}
value={inputs.OIDCUserInfoEndpoint} value={inputs['oidc.user_info_endpoint']}
placeholder='输入 OIDC 的 Userinfo Endpoint' placeholder='输入 OIDC 的 Userinfo Endpoint'
/> />
</Form.Group> </Form.Group>