@@ -19,6 +19,7 @@ package model
1919import (
2020 "bytes"
2121 "crypto/sha1"
22+ "encoding/json"
2223 "fmt"
2324 "os"
2425 "path/filepath"
@@ -38,6 +39,7 @@ import (
3839 "github.com/siyuan-note/filelock"
3940 "github.com/siyuan-note/logging"
4041 "github.com/siyuan-note/siyuan/kernel/conf"
42+ "github.com/siyuan-note/siyuan/kernel/model/oidc"
4143 "github.com/siyuan-note/siyuan/kernel/sql"
4244 "github.com/siyuan-note/siyuan/kernel/task"
4345 "github.com/siyuan-note/siyuan/kernel/treenode"
@@ -50,40 +52,41 @@ var Conf *AppConf
5052
5153// AppConf 维护应用元数据,保存在 ~/.siyuan/conf.json。
5254type AppConf struct {
53- LogLevel string `json:"logLevel"` // 日志级别:off, trace, debug, info, warn, error, fatal
54- Appearance * conf.Appearance `json:"appearance"` // 外观
55- Langs []* conf.Lang `json:"langs"` // 界面语言列表
56- Lang string `json:"lang"` // 选择的界面语言,同 Appearance.Lang
57- FileTree * conf.FileTree `json:"fileTree"` // 文档面板
58- Tag * conf.Tag `json:"tag"` // 标签面板
59- Editor * conf.Editor `json:"editor"` // 编辑器配置
60- Export * conf.Export `json:"export"` // 导出配置
61- Graph * conf.Graph `json:"graph"` // 关系图配置
62- UILayout * conf.UILayout `json:"uiLayout"` // 界面布局。不要直接使用,使用 GetUILayout() 和 SetUILayout() 方法
63- UserData string `json:"userData"` // 社区用户信息,对 User 加密存储
64- User * conf.User `json:"-"` // 社区用户内存结构,不持久化。不要直接使用,使用 GetUser() 和 SetUser() 方法
65- Account * conf.Account `json:"account"` // 帐号配置
66- ReadOnly bool `json:"readonly"` // 是否是以只读模式运行
67- LocalIPs []string `json:"localIPs"` // 本地 IP 列表
68- AccessAuthCode string `json:"accessAuthCode"` // 访问授权码
69- OIDC * conf.OIDC `json:"oidc"` // OIDC 登录配置
70- System * conf.System `json:"system"` // 系统配置
71- Keymap * conf.Keymap `json:"keymap"` // 快捷键配置
72- Sync * conf.Sync `json:"sync"` // 同步配置
73- Search * conf.Search `json:"search"` // 搜索配置
74- Flashcard * conf.Flashcard `json:"flashcard"` // 闪卡配置
75- AI * conf.AI `json:"ai"` // 人工智能配置
76- Bazaar * conf.Bazaar `json:"bazaar"` // 集市配置
77- Stat * conf.Stat `json:"stat"` // 统计
78- Api * conf.API `json:"api"` // API
79- Repo * conf.Repo `json:"repo"` // 数据仓库
80- Publish * conf.Publish `json:"publish"` // 发布服务
81- OpenHelp bool `json:"openHelp"` // 启动后是否需要打开用户指南
82- ShowChangelog bool `json:"showChangelog"` // 是否显示版本更新日志
83- CloudRegion int `json:"cloudRegion"` // 云端区域,0:中国大陆,1:北美
84- Snippet * conf.Snpt `json:"snippet"` // 代码片段
85- DataIndexState int `json:"dataIndexState"` // 数据索引状态,0:已索引,1:未索引
86- CookieKey string `json:"cookieKey"` // 用于加密 Cookie 的密钥
55+ LogLevel string `json:"logLevel"` // 日志级别:off, trace, debug, info, warn, error, fatal
56+ Appearance * conf.Appearance `json:"appearance"` // 外观
57+ Langs []* conf.Lang `json:"langs"` // 界面语言列表
58+ Lang string `json:"lang"` // 选择的界面语言,同 Appearance.Lang
59+ FileTree * conf.FileTree `json:"fileTree"` // 文档面板
60+ Tag * conf.Tag `json:"tag"` // 标签面板
61+ Editor * conf.Editor `json:"editor"` // 编辑器配置
62+ Export * conf.Export `json:"export"` // 导出配置
63+ Graph * conf.Graph `json:"graph"` // 关系图配置
64+ UILayout * conf.UILayout `json:"uiLayout"` // 界面布局。不要直接使用,使用 GetUILayout() 和 SetUILayout() 方法
65+ UserData string `json:"userData"` // 社区用户信息,对 User 加密存储
66+ User * conf.User `json:"-"` // 社区用户内存结构,不持久化。不要直接使用,使用 GetUser() 和 SetUser() 方法
67+ Account * conf.Account `json:"account"` // 帐号配置
68+ ReadOnly bool `json:"readonly"` // 是否是以只读模式运行
69+ LocalIPs []string `json:"localIPs"` // 本地 IP 列表
70+ AccessAuthBypass bool `json:"accessAuthBypass"` // 跳过一切访问认证和安全检查
71+ AccessAuthCode string `json:"accessAuthCode"` // 访问授权码
72+ OIDC * conf.OIDC `json:"oidc"` // OIDC 登录配置
73+ System * conf.System `json:"system"` // 系统配置
74+ Keymap * conf.Keymap `json:"keymap"` // 快捷键配置
75+ Sync * conf.Sync `json:"sync"` // 同步配置
76+ Search * conf.Search `json:"search"` // 搜索配置
77+ Flashcard * conf.Flashcard `json:"flashcard"` // 闪卡配置
78+ AI * conf.AI `json:"ai"` // 人工智能配置
79+ Bazaar * conf.Bazaar `json:"bazaar"` // 集市配置
80+ Stat * conf.Stat `json:"stat"` // 统计
81+ Api * conf.API `json:"api"` // API
82+ Repo * conf.Repo `json:"repo"` // 数据仓库
83+ Publish * conf.Publish `json:"publish"` // 发布服务
84+ OpenHelp bool `json:"openHelp"` // 启动后是否需要打开用户指南
85+ ShowChangelog bool `json:"showChangelog"` // 是否显示版本更新日志
86+ CloudRegion int `json:"cloudRegion"` // 云端区域,0:中国大陆,1:北美
87+ Snippet * conf.Snpt `json:"snippet"` // 代码片段
88+ DataIndexState int `json:"dataIndexState"` // 数据索引状态,0:已索引,1:未索引
89+ CookieKey string `json:"cookieKey"` // 用于加密 Cookie 的密钥
8790
8891 m * sync.RWMutex // 配置数据锁
8992 userLock * sync.RWMutex // 用户数据独立锁,避免与配置保存操作竞争
@@ -138,6 +141,59 @@ func InitConf() {
138141 }
139142 }
140143
144+ // 合并命令行和环境变量提供的认证配置项。 CLI 优先级高于 配置文件。
145+ // CLI 只存在于桌面端/容器化构建版本,移动平台不会设置这些全局变量。
146+ if util .AuthCLI .AccessCodeSet {
147+ Conf .AccessAuthCode = util .RemoveInvalid (strings .TrimSpace (util .AuthCLI .AccessCode ))
148+ } else {
149+ Conf .AccessAuthCode = util .RemoveInvalid (strings .TrimSpace (Conf .AccessAuthCode ))
150+ }
151+
152+ if util .AuthCLI .AccessAuthBypassSet {
153+ Conf .AccessAuthBypass = util .AuthCLI .AccessAuthBypass
154+ }
155+
156+ if nil == Conf .OIDC {
157+ Conf .OIDC = conf .NewOIDC ()
158+ }
159+
160+ if util .AuthCLI .OIDCProviderSet {
161+ Conf .OIDC .Provider = util .AuthCLI .OIDCProvider
162+ }
163+
164+ if util .AuthCLI .OIDCProvidersSet && "" != util .AuthCLI .OIDCProviders {
165+ if "" != util .AuthCLI .OIDCProviders {
166+ Conf .OIDC .Providers = map [string ]* conf.OIDCProviderConf {}
167+ } else {
168+ providers := map [string ]* conf.OIDCProviderConf {}
169+ if err := json .Unmarshal ([]byte (util .AuthCLI .OIDCProviders ), & providers ); err != nil {
170+ logging .LogErrorf ("parse oidc providers from cli failed: %s" , err )
171+ } else {
172+ Conf .OIDC .Providers = providers
173+ }
174+ }
175+ }
176+
177+ if util .AuthCLI .OIDCFiltersSet {
178+ if "" == util .AuthCLI .OIDCFilters {
179+ Conf .OIDC .Filters = map [string ][]string {}
180+ } else {
181+ filters := map [string ][]string {}
182+ if err := json .Unmarshal ([]byte (util .AuthCLI .OIDCFilters ), & filters ); err != nil {
183+ logging .LogErrorf ("parse oidc filters from cli failed: %s" , err )
184+ } else {
185+ Conf .OIDC .Filters = filters
186+ }
187+ }
188+ }
189+
190+ if util .ContainerDocker == util .Container && ! Conf .AccessAuthBypass {
191+ if "" == Conf .AccessAuthCode && ! oidc .IsEnabled (Conf .OIDC ) {
192+ fmt .Println ("in Docker mode, you must set (or set --accessAuthBypass [not recommended]) at least one auth method: accessAuthCode or OIDC" )
193+ os .Exit (logging .ExitCodeSecurityRisk )
194+ }
195+ }
196+
141197 if "" != util .Lang {
142198 initialized := false
143199 if util .ContainerAndroid == util .Container || util .ContainerIOS == util .Container || util .ContainerHarmony == util .Container {
@@ -383,9 +439,6 @@ func InitConf() {
383439 if nil == Conf .Account {
384440 Conf .Account = conf .NewAccount ()
385441 }
386- if nil == Conf .OIDC {
387- Conf .OIDC = conf .NewOIDC ()
388- }
389442
390443 if nil == Conf .Sync {
391444 Conf .Sync = conf .NewSync ()
@@ -569,12 +622,6 @@ func InitConf() {
569622
570623 Conf .ReadOnly = util .ReadOnly
571624
572- if "" != util .AccessAuthCode {
573- Conf .AccessAuthCode = util .AccessAuthCode
574- }
575- Conf .AccessAuthCode = strings .TrimSpace (Conf .AccessAuthCode )
576- Conf .AccessAuthCode = util .RemoveInvalid (Conf .AccessAuthCode )
577-
578625 Conf .LocalIPs = util .GetLocalIPs ()
579626
580627 if 1 == Conf .DataIndexState {
0 commit comments