This is an automated email from the ASF dual-hosted git repository.
kumfo pushed a commit to branch feat/1.8.0/menu
in repository https://gitbox.apache.org/repos/asf/answer.git
The following commit(s) were added to refs/heads/feat/1.8.0/menu by this push:
new f0636d43 feat(siteinfo): refactor site legal and security settings to
use new policies and security endpoints
f0636d43 is described below
commit f0636d43693897de38d61d221a972c7d03f187a6
Author: kumfo <[email protected]>
AuthorDate: Wed Jan 21 16:06:17 2026 +0800
feat(siteinfo): refactor site legal and security settings to use new
policies and security endpoints
---
docs/docs.go | 250 ++++++++++++++-------
docs/swagger.json | 250 ++++++++++++++-------
docs/swagger.yaml | 171 +++++++++-----
internal/base/constant/site_type.go | 6 +-
internal/base/middleware/auth.go | 4 +-
internal/base/middleware/visit_img_auth.go | 4 +-
internal/controller/siteinfo_controller.go | 4 +-
internal/controller/template_controller.go | 2 +-
internal/controller_admin/siteinfo_controller.go | 61 +++--
internal/migrations/init.go | 85 +++++--
internal/migrations/v30.go | 217 ++++++++++++++----
internal/router/answer_api_router.go | 7 +-
internal/schema/siteinfo_schema.go | 21 +-
internal/service/dashboard/dashboard_service.go | 17 +-
internal/service/mock/siteinfo_repo_mock.go | 62 +++--
internal/service/siteinfo/siteinfo_service.go | 34 ++-
.../service/siteinfo_common/siteinfo_service.go | 22 +-
17 files changed, 855 insertions(+), 362 deletions(-)
diff --git a/docs/docs.go b/docs/docs.go
index b030c3d3..a70cdab0 100644
--- a/docs/docs.go
+++ b/docs/docs.go
@@ -1211,21 +1211,21 @@ const docTemplate = `{
}
}
},
- "/answer/admin/api/siteinfo/legal": {
+ "/answer/admin/api/siteinfo/login": {
"get": {
"security": [
{
"ApiKeyAuth": []
}
],
- "description": "Set the legal information for the site",
+ "description": "get site info login config",
"produces": [
"application/json"
],
"tags": [
"admin"
],
- "summary": "Set the legal information for the site",
+ "summary": "get site info login config",
"responses": {
"200": {
"description": "OK",
@@ -1238,7 +1238,7 @@ const docTemplate = `{
"type": "object",
"properties": {
"data": {
- "$ref":
"#/definitions/schema.SiteLegalResp"
+ "$ref":
"#/definitions/schema.SiteLoginResp"
}
}
}
@@ -1253,22 +1253,22 @@ const docTemplate = `{
"ApiKeyAuth": []
}
],
- "description": "update site legal info",
+ "description": "update site login",
"produces": [
"application/json"
],
"tags": [
"admin"
],
- "summary": "update site legal info",
+ "summary": "update site login",
"parameters": [
{
- "description": "write info",
+ "description": "login info",
"name": "data",
"in": "body",
"required": true,
"schema": {
- "$ref": "#/definitions/schema.SiteLegalReq"
+ "$ref": "#/definitions/schema.SiteLoginReq"
}
}
],
@@ -1282,21 +1282,21 @@ const docTemplate = `{
}
}
},
- "/answer/admin/api/siteinfo/login": {
+ "/answer/admin/api/siteinfo/polices": {
"get": {
"security": [
{
"ApiKeyAuth": []
}
],
- "description": "get site info login config",
+ "description": "Get the policies information for the site",
"produces": [
"application/json"
],
"tags": [
"admin"
],
- "summary": "get site info login config",
+ "summary": "Get the policies information for the site",
"responses": {
"200": {
"description": "OK",
@@ -1309,7 +1309,7 @@ const docTemplate = `{
"type": "object",
"properties": {
"data": {
- "$ref":
"#/definitions/schema.SiteLoginResp"
+ "$ref":
"#/definitions/schema.SitePoliciesResp"
}
}
}
@@ -1324,22 +1324,22 @@ const docTemplate = `{
"ApiKeyAuth": []
}
],
- "description": "update site login",
+ "description": "update site policies configuration",
"produces": [
"application/json"
],
"tags": [
"admin"
],
- "summary": "update site login",
+ "summary": "update site policies configuration",
"parameters": [
{
- "description": "login info",
+ "description": "write info",
"name": "data",
"in": "body",
"required": true,
"schema": {
- "$ref": "#/definitions/schema.SiteLoginReq"
+ "$ref": "#/definitions/schema.SitePoliciesReq"
}
}
],
@@ -1424,6 +1424,77 @@ const docTemplate = `{
}
}
},
+ "/answer/admin/api/siteinfo/security": {
+ "get": {
+ "security": [
+ {
+ "ApiKeyAuth": []
+ }
+ ],
+ "description": "Get the security information for the site",
+ "produces": [
+ "application/json"
+ ],
+ "tags": [
+ "admin"
+ ],
+ "summary": "Get the security information for the site",
+ "responses": {
+ "200": {
+ "description": "OK",
+ "schema": {
+ "allOf": [
+ {
+ "$ref": "#/definitions/handler.RespBody"
+ },
+ {
+ "type": "object",
+ "properties": {
+ "data": {
+ "$ref":
"#/definitions/schema.SiteSecurityResp"
+ }
+ }
+ }
+ ]
+ }
+ }
+ }
+ },
+ "put": {
+ "security": [
+ {
+ "ApiKeyAuth": []
+ }
+ ],
+ "description": "update site security configuration",
+ "produces": [
+ "application/json"
+ ],
+ "tags": [
+ "admin"
+ ],
+ "summary": "update site security configuration",
+ "parameters": [
+ {
+ "description": "write info",
+ "name": "data",
+ "in": "body",
+ "required": true,
+ "schema": {
+ "$ref": "#/definitions/schema.SiteSecurityReq"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "OK",
+ "schema": {
+ "$ref": "#/definitions/handler.RespBody"
+ }
+ }
+ }
+ }
+ },
"/answer/admin/api/siteinfo/seo": {
"get": {
"security": [
@@ -10843,9 +10914,6 @@ const docTemplate = `{
"site_url"
],
"properties": {
- "check_update": {
- "type": "boolean"
- },
"contact_email": {
"type": "string",
"maxLength": 512
@@ -10876,9 +10944,6 @@ const docTemplate = `{
"site_url"
],
"properties": {
- "check_update": {
- "type": "boolean"
- },
"contact_email": {
"type": "string",
"maxLength": 512
@@ -10917,7 +10982,12 @@ const docTemplate = `{
"$ref": "#/definitions/schema.SiteInterfaceSettingsResp"
},
"login": {
- "$ref": "#/definitions/schema.SiteLoginResp"
+ "description": "todo",
+ "allOf": [
+ {
+ "$ref": "#/definitions/schema.SiteLoginResp"
+ }
+ ]
},
"revision": {
"type": "string"
@@ -10996,60 +11066,6 @@ const docTemplate = `{
}
}
},
- "schema.SiteLegalReq": {
- "type": "object",
- "required": [
- "external_content_display"
- ],
- "properties": {
- "external_content_display": {
- "type": "string",
- "enum": [
- "always_display",
- "ask_before_display"
- ]
- },
- "privacy_policy_original_text": {
- "type": "string"
- },
- "privacy_policy_parsed_text": {
- "type": "string"
- },
- "terms_of_service_original_text": {
- "type": "string"
- },
- "terms_of_service_parsed_text": {
- "type": "string"
- }
- }
- },
- "schema.SiteLegalResp": {
- "type": "object",
- "required": [
- "external_content_display"
- ],
- "properties": {
- "external_content_display": {
- "type": "string",
- "enum": [
- "always_display",
- "ask_before_display"
- ]
- },
- "privacy_policy_original_text": {
- "type": "string"
- },
- "privacy_policy_parsed_text": {
- "type": "string"
- },
- "terms_of_service_original_text": {
- "type": "string"
- },
- "terms_of_service_parsed_text": {
- "type": "string"
- }
- }
- },
"schema.SiteLegalSimpleResp": {
"type": "object",
"required": [
@@ -11082,9 +11098,6 @@ const docTemplate = `{
},
"allow_password_login": {
"type": "boolean"
- },
- "login_required": {
- "type": "boolean"
}
}
},
@@ -11105,9 +11118,40 @@ const docTemplate = `{
},
"allow_password_login": {
"type": "boolean"
+ }
+ }
+ },
+ "schema.SitePoliciesReq": {
+ "type": "object",
+ "properties": {
+ "privacy_policy_original_text": {
+ "type": "string"
},
- "login_required": {
- "type": "boolean"
+ "privacy_policy_parsed_text": {
+ "type": "string"
+ },
+ "terms_of_service_original_text": {
+ "type": "string"
+ },
+ "terms_of_service_parsed_text": {
+ "type": "string"
+ }
+ }
+ },
+ "schema.SitePoliciesResp": {
+ "type": "object",
+ "properties": {
+ "privacy_policy_original_text": {
+ "type": "string"
+ },
+ "privacy_policy_parsed_text": {
+ "type": "string"
+ },
+ "terms_of_service_original_text": {
+ "type": "string"
+ },
+ "terms_of_service_parsed_text": {
+ "type": "string"
}
}
},
@@ -11137,6 +11181,48 @@ const docTemplate = `{
}
}
},
+ "schema.SiteSecurityReq": {
+ "type": "object",
+ "required": [
+ "external_content_display"
+ ],
+ "properties": {
+ "check_update": {
+ "type": "boolean"
+ },
+ "external_content_display": {
+ "type": "string",
+ "enum": [
+ "always_display",
+ "ask_before_display"
+ ]
+ },
+ "login_required": {
+ "type": "boolean"
+ }
+ }
+ },
+ "schema.SiteSecurityResp": {
+ "type": "object",
+ "required": [
+ "external_content_display"
+ ],
+ "properties": {
+ "check_update": {
+ "type": "boolean"
+ },
+ "external_content_display": {
+ "type": "string",
+ "enum": [
+ "always_display",
+ "ask_before_display"
+ ]
+ },
+ "login_required": {
+ "type": "boolean"
+ }
+ }
+ },
"schema.SiteSeoReq": {
"type": "object",
"required": [
diff --git a/docs/swagger.json b/docs/swagger.json
index 879302fa..05e3302c 100644
--- a/docs/swagger.json
+++ b/docs/swagger.json
@@ -1203,21 +1203,21 @@
}
}
},
- "/answer/admin/api/siteinfo/legal": {
+ "/answer/admin/api/siteinfo/login": {
"get": {
"security": [
{
"ApiKeyAuth": []
}
],
- "description": "Set the legal information for the site",
+ "description": "get site info login config",
"produces": [
"application/json"
],
"tags": [
"admin"
],
- "summary": "Set the legal information for the site",
+ "summary": "get site info login config",
"responses": {
"200": {
"description": "OK",
@@ -1230,7 +1230,7 @@
"type": "object",
"properties": {
"data": {
- "$ref":
"#/definitions/schema.SiteLegalResp"
+ "$ref":
"#/definitions/schema.SiteLoginResp"
}
}
}
@@ -1245,22 +1245,22 @@
"ApiKeyAuth": []
}
],
- "description": "update site legal info",
+ "description": "update site login",
"produces": [
"application/json"
],
"tags": [
"admin"
],
- "summary": "update site legal info",
+ "summary": "update site login",
"parameters": [
{
- "description": "write info",
+ "description": "login info",
"name": "data",
"in": "body",
"required": true,
"schema": {
- "$ref": "#/definitions/schema.SiteLegalReq"
+ "$ref": "#/definitions/schema.SiteLoginReq"
}
}
],
@@ -1274,21 +1274,21 @@
}
}
},
- "/answer/admin/api/siteinfo/login": {
+ "/answer/admin/api/siteinfo/polices": {
"get": {
"security": [
{
"ApiKeyAuth": []
}
],
- "description": "get site info login config",
+ "description": "Get the policies information for the site",
"produces": [
"application/json"
],
"tags": [
"admin"
],
- "summary": "get site info login config",
+ "summary": "Get the policies information for the site",
"responses": {
"200": {
"description": "OK",
@@ -1301,7 +1301,7 @@
"type": "object",
"properties": {
"data": {
- "$ref":
"#/definitions/schema.SiteLoginResp"
+ "$ref":
"#/definitions/schema.SitePoliciesResp"
}
}
}
@@ -1316,22 +1316,22 @@
"ApiKeyAuth": []
}
],
- "description": "update site login",
+ "description": "update site policies configuration",
"produces": [
"application/json"
],
"tags": [
"admin"
],
- "summary": "update site login",
+ "summary": "update site policies configuration",
"parameters": [
{
- "description": "login info",
+ "description": "write info",
"name": "data",
"in": "body",
"required": true,
"schema": {
- "$ref": "#/definitions/schema.SiteLoginReq"
+ "$ref": "#/definitions/schema.SitePoliciesReq"
}
}
],
@@ -1416,6 +1416,77 @@
}
}
},
+ "/answer/admin/api/siteinfo/security": {
+ "get": {
+ "security": [
+ {
+ "ApiKeyAuth": []
+ }
+ ],
+ "description": "Get the security information for the site",
+ "produces": [
+ "application/json"
+ ],
+ "tags": [
+ "admin"
+ ],
+ "summary": "Get the security information for the site",
+ "responses": {
+ "200": {
+ "description": "OK",
+ "schema": {
+ "allOf": [
+ {
+ "$ref": "#/definitions/handler.RespBody"
+ },
+ {
+ "type": "object",
+ "properties": {
+ "data": {
+ "$ref":
"#/definitions/schema.SiteSecurityResp"
+ }
+ }
+ }
+ ]
+ }
+ }
+ }
+ },
+ "put": {
+ "security": [
+ {
+ "ApiKeyAuth": []
+ }
+ ],
+ "description": "update site security configuration",
+ "produces": [
+ "application/json"
+ ],
+ "tags": [
+ "admin"
+ ],
+ "summary": "update site security configuration",
+ "parameters": [
+ {
+ "description": "write info",
+ "name": "data",
+ "in": "body",
+ "required": true,
+ "schema": {
+ "$ref": "#/definitions/schema.SiteSecurityReq"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "OK",
+ "schema": {
+ "$ref": "#/definitions/handler.RespBody"
+ }
+ }
+ }
+ }
+ },
"/answer/admin/api/siteinfo/seo": {
"get": {
"security": [
@@ -10835,9 +10906,6 @@
"site_url"
],
"properties": {
- "check_update": {
- "type": "boolean"
- },
"contact_email": {
"type": "string",
"maxLength": 512
@@ -10868,9 +10936,6 @@
"site_url"
],
"properties": {
- "check_update": {
- "type": "boolean"
- },
"contact_email": {
"type": "string",
"maxLength": 512
@@ -10909,7 +10974,12 @@
"$ref": "#/definitions/schema.SiteInterfaceSettingsResp"
},
"login": {
- "$ref": "#/definitions/schema.SiteLoginResp"
+ "description": "todo",
+ "allOf": [
+ {
+ "$ref": "#/definitions/schema.SiteLoginResp"
+ }
+ ]
},
"revision": {
"type": "string"
@@ -10988,60 +11058,6 @@
}
}
},
- "schema.SiteLegalReq": {
- "type": "object",
- "required": [
- "external_content_display"
- ],
- "properties": {
- "external_content_display": {
- "type": "string",
- "enum": [
- "always_display",
- "ask_before_display"
- ]
- },
- "privacy_policy_original_text": {
- "type": "string"
- },
- "privacy_policy_parsed_text": {
- "type": "string"
- },
- "terms_of_service_original_text": {
- "type": "string"
- },
- "terms_of_service_parsed_text": {
- "type": "string"
- }
- }
- },
- "schema.SiteLegalResp": {
- "type": "object",
- "required": [
- "external_content_display"
- ],
- "properties": {
- "external_content_display": {
- "type": "string",
- "enum": [
- "always_display",
- "ask_before_display"
- ]
- },
- "privacy_policy_original_text": {
- "type": "string"
- },
- "privacy_policy_parsed_text": {
- "type": "string"
- },
- "terms_of_service_original_text": {
- "type": "string"
- },
- "terms_of_service_parsed_text": {
- "type": "string"
- }
- }
- },
"schema.SiteLegalSimpleResp": {
"type": "object",
"required": [
@@ -11074,9 +11090,6 @@
},
"allow_password_login": {
"type": "boolean"
- },
- "login_required": {
- "type": "boolean"
}
}
},
@@ -11097,9 +11110,40 @@
},
"allow_password_login": {
"type": "boolean"
+ }
+ }
+ },
+ "schema.SitePoliciesReq": {
+ "type": "object",
+ "properties": {
+ "privacy_policy_original_text": {
+ "type": "string"
},
- "login_required": {
- "type": "boolean"
+ "privacy_policy_parsed_text": {
+ "type": "string"
+ },
+ "terms_of_service_original_text": {
+ "type": "string"
+ },
+ "terms_of_service_parsed_text": {
+ "type": "string"
+ }
+ }
+ },
+ "schema.SitePoliciesResp": {
+ "type": "object",
+ "properties": {
+ "privacy_policy_original_text": {
+ "type": "string"
+ },
+ "privacy_policy_parsed_text": {
+ "type": "string"
+ },
+ "terms_of_service_original_text": {
+ "type": "string"
+ },
+ "terms_of_service_parsed_text": {
+ "type": "string"
}
}
},
@@ -11129,6 +11173,48 @@
}
}
},
+ "schema.SiteSecurityReq": {
+ "type": "object",
+ "required": [
+ "external_content_display"
+ ],
+ "properties": {
+ "check_update": {
+ "type": "boolean"
+ },
+ "external_content_display": {
+ "type": "string",
+ "enum": [
+ "always_display",
+ "ask_before_display"
+ ]
+ },
+ "login_required": {
+ "type": "boolean"
+ }
+ }
+ },
+ "schema.SiteSecurityResp": {
+ "type": "object",
+ "required": [
+ "external_content_display"
+ ],
+ "properties": {
+ "check_update": {
+ "type": "boolean"
+ },
+ "external_content_display": {
+ "type": "string",
+ "enum": [
+ "always_display",
+ "ask_before_display"
+ ]
+ },
+ "login_required": {
+ "type": "boolean"
+ }
+ }
+ },
"schema.SiteSeoReq": {
"type": "object",
"required": [
diff --git a/docs/swagger.yaml b/docs/swagger.yaml
index ce16da75..85a05baf 100644
--- a/docs/swagger.yaml
+++ b/docs/swagger.yaml
@@ -2157,8 +2157,6 @@ definitions:
type: object
schema.SiteGeneralReq:
properties:
- check_update:
- type: boolean
contact_email:
maxLength: 512
type: string
@@ -2181,8 +2179,6 @@ definitions:
type: object
schema.SiteGeneralResp:
properties:
- check_update:
- type: boolean
contact_email:
maxLength: 512
type: string
@@ -2214,7 +2210,9 @@ definitions:
interface:
$ref: '#/definitions/schema.SiteInterfaceSettingsResp'
login:
- $ref: '#/definitions/schema.SiteLoginResp'
+ allOf:
+ - $ref: '#/definitions/schema.SiteLoginResp'
+ description: todo
revision:
type: string
site_advanced:
@@ -2268,42 +2266,6 @@ definitions:
- language
- time_zone
type: object
- schema.SiteLegalReq:
- properties:
- external_content_display:
- enum:
- - always_display
- - ask_before_display
- type: string
- privacy_policy_original_text:
- type: string
- privacy_policy_parsed_text:
- type: string
- terms_of_service_original_text:
- type: string
- terms_of_service_parsed_text:
- type: string
- required:
- - external_content_display
- type: object
- schema.SiteLegalResp:
- properties:
- external_content_display:
- enum:
- - always_display
- - ask_before_display
- type: string
- privacy_policy_original_text:
- type: string
- privacy_policy_parsed_text:
- type: string
- terms_of_service_original_text:
- type: string
- terms_of_service_parsed_text:
- type: string
- required:
- - external_content_display
- type: object
schema.SiteLegalSimpleResp:
properties:
external_content_display:
@@ -2326,8 +2288,6 @@ definitions:
type: boolean
allow_password_login:
type: boolean
- login_required:
- type: boolean
type: object
schema.SiteLoginResp:
properties:
@@ -2341,8 +2301,28 @@ definitions:
type: boolean
allow_password_login:
type: boolean
- login_required:
- type: boolean
+ type: object
+ schema.SitePoliciesReq:
+ properties:
+ privacy_policy_original_text:
+ type: string
+ privacy_policy_parsed_text:
+ type: string
+ terms_of_service_original_text:
+ type: string
+ terms_of_service_parsed_text:
+ type: string
+ type: object
+ schema.SitePoliciesResp:
+ properties:
+ privacy_policy_original_text:
+ type: string
+ privacy_policy_parsed_text:
+ type: string
+ terms_of_service_original_text:
+ type: string
+ terms_of_service_parsed_text:
+ type: string
type: object
schema.SiteQuestionsReq:
properties:
@@ -2362,6 +2342,34 @@ definitions:
restrict_answer:
type: boolean
type: object
+ schema.SiteSecurityReq:
+ properties:
+ check_update:
+ type: boolean
+ external_content_display:
+ enum:
+ - always_display
+ - ask_before_display
+ type: string
+ login_required:
+ type: boolean
+ required:
+ - external_content_display
+ type: object
+ schema.SiteSecurityResp:
+ properties:
+ check_update:
+ type: boolean
+ external_content_display:
+ enum:
+ - always_display
+ - ask_before_display
+ type: string
+ login_required:
+ type: boolean
+ required:
+ - external_content_display
+ type: object
schema.SiteSeoReq:
properties:
permalink:
@@ -3924,9 +3932,9 @@ paths:
summary: update site info interface
tags:
- admin
- /answer/admin/api/siteinfo/legal:
+ /answer/admin/api/siteinfo/login:
get:
- description: Set the legal information for the site
+ description: get site info login config
produces:
- application/json
responses:
@@ -3937,22 +3945,22 @@ paths:
- $ref: '#/definitions/handler.RespBody'
- properties:
data:
- $ref: '#/definitions/schema.SiteLegalResp'
+ $ref: '#/definitions/schema.SiteLoginResp'
type: object
security:
- ApiKeyAuth: []
- summary: Set the legal information for the site
+ summary: get site info login config
tags:
- admin
put:
- description: update site legal info
+ description: update site login
parameters:
- - description: write info
+ - description: login info
in: body
name: data
required: true
schema:
- $ref: '#/definitions/schema.SiteLegalReq'
+ $ref: '#/definitions/schema.SiteLoginReq'
produces:
- application/json
responses:
@@ -3962,12 +3970,12 @@ paths:
$ref: '#/definitions/handler.RespBody'
security:
- ApiKeyAuth: []
- summary: update site legal info
+ summary: update site login
tags:
- admin
- /answer/admin/api/siteinfo/login:
+ /answer/admin/api/siteinfo/polices:
get:
- description: get site info login config
+ description: Get the policies information for the site
produces:
- application/json
responses:
@@ -3978,22 +3986,22 @@ paths:
- $ref: '#/definitions/handler.RespBody'
- properties:
data:
- $ref: '#/definitions/schema.SiteLoginResp'
+ $ref: '#/definitions/schema.SitePoliciesResp'
type: object
security:
- ApiKeyAuth: []
- summary: get site info login config
+ summary: Get the policies information for the site
tags:
- admin
put:
- description: update site login
+ description: update site policies configuration
parameters:
- - description: login info
+ - description: write info
in: body
name: data
required: true
schema:
- $ref: '#/definitions/schema.SiteLoginReq'
+ $ref: '#/definitions/schema.SitePoliciesReq'
produces:
- application/json
responses:
@@ -4003,7 +4011,7 @@ paths:
$ref: '#/definitions/handler.RespBody'
security:
- ApiKeyAuth: []
- summary: update site login
+ summary: update site policies configuration
tags:
- admin
/answer/admin/api/siteinfo/question:
@@ -4047,6 +4055,47 @@ paths:
summary: update site question settings
tags:
- admin
+ /answer/admin/api/siteinfo/security:
+ get:
+ description: Get the security information for the site
+ produces:
+ - application/json
+ responses:
+ "200":
+ description: OK
+ schema:
+ allOf:
+ - $ref: '#/definitions/handler.RespBody'
+ - properties:
+ data:
+ $ref: '#/definitions/schema.SiteSecurityResp'
+ type: object
+ security:
+ - ApiKeyAuth: []
+ summary: Get the security information for the site
+ tags:
+ - admin
+ put:
+ description: update site security configuration
+ parameters:
+ - description: write info
+ in: body
+ name: data
+ required: true
+ schema:
+ $ref: '#/definitions/schema.SiteSecurityReq'
+ produces:
+ - application/json
+ responses:
+ "200":
+ description: OK
+ schema:
+ $ref: '#/definitions/handler.RespBody'
+ security:
+ - ApiKeyAuth: []
+ summary: update site security configuration
+ tags:
+ - admin
/answer/admin/api/siteinfo/seo:
get:
description: get site seo information
diff --git a/internal/base/constant/site_type.go
b/internal/base/constant/site_type.go
index 9bb4e10a..44cd0abd 100644
--- a/internal/base/constant/site_type.go
+++ b/internal/base/constant/site_type.go
@@ -25,7 +25,8 @@ const (
SiteTypeInterface = "interface"
SiteTypeBranding = "branding"
// Deprecated: use SiteTypeAdvanced, SiteTypeQuestions, and
SiteTypeTags instead
- SiteTypeWrite = "write"
+ SiteTypeWrite = "write"
+ // Deprecated: use SiteTypePolicies and SiteTypeSecurity instead
SiteTypeLegal = "legal"
SiteTypeSeo = "seo"
SiteTypeLogin = "login"
@@ -40,4 +41,7 @@ const (
SiteTypeUsersSettings = "users_settings"
SiteTypeInterfaceSettings = "interface_settings"
+
+ SiteTypePolicies = "policies"
+ SiteTypeSecurity = "security"
)
diff --git a/internal/base/middleware/auth.go b/internal/base/middleware/auth.go
index f21837b6..57bbaae2 100644
--- a/internal/base/middleware/auth.go
+++ b/internal/base/middleware/auth.go
@@ -80,7 +80,7 @@ func (am *AuthUserMiddleware) Auth() gin.HandlerFunc {
func (am *AuthUserMiddleware) EjectUserBySiteInfo() gin.HandlerFunc {
return func(ctx *gin.Context) {
mustLogin := false
- siteInfo, _ := am.siteInfoCommonService.GetSiteLogin(ctx)
+ siteInfo, _ := am.siteInfoCommonService.GetSiteSecurity(ctx)
if siteInfo != nil {
mustLogin = siteInfo.LoginRequired
}
@@ -197,7 +197,7 @@ func (am *AuthUserMiddleware) AdminAuth() gin.HandlerFunc {
func (am *AuthUserMiddleware) CheckPrivateMode() gin.HandlerFunc {
return func(ctx *gin.Context) {
- resp, err := am.siteInfoCommonService.GetSiteLogin(ctx)
+ resp, err := am.siteInfoCommonService.GetSiteSecurity(ctx)
if err != nil {
ShowIndexPage(ctx)
ctx.Abort()
diff --git a/internal/base/middleware/visit_img_auth.go
b/internal/base/middleware/visit_img_auth.go
index 33b62172..bfd157a9 100644
--- a/internal/base/middleware/visit_img_auth.go
+++ b/internal/base/middleware/visit_img_auth.go
@@ -41,11 +41,11 @@ func (am *AuthUserMiddleware) VisitAuth() gin.HandlerFunc {
return
}
- siteLogin, err := am.siteInfoCommonService.GetSiteLogin(ctx)
+ siteSecurity, err :=
am.siteInfoCommonService.GetSiteSecurity(ctx)
if err != nil {
return
}
- if !siteLogin.LoginRequired {
+ if !siteSecurity.LoginRequired {
ctx.Next()
return
}
diff --git a/internal/controller/siteinfo_controller.go
b/internal/controller/siteinfo_controller.go
index 503bfeb6..64aa02ce 100644
--- a/internal/controller/siteinfo_controller.go
+++ b/internal/controller/siteinfo_controller.go
@@ -104,7 +104,7 @@ func (sc *SiteInfoController) GetSiteInfo(ctx *gin.Context)
{
if err != nil {
log.Error(err)
}
- if legal, err := sc.siteInfoService.GetSiteLegal(ctx); err == nil {
+ if legal, err := sc.siteInfoService.GetSiteSecurity(ctx); err == nil {
resp.Legal =
&schema.SiteLegalSimpleResp{ExternalContentDisplay:
legal.ExternalContentDisplay}
}
@@ -124,7 +124,7 @@ func (sc *SiteInfoController) GetSiteLegalInfo(ctx
*gin.Context) {
if handler.BindAndCheck(ctx, req) {
return
}
- siteLegal, err := sc.siteInfoService.GetSiteLegal(ctx)
+ siteLegal, err := sc.siteInfoService.GetSitePolicies(ctx)
if err != nil {
handler.HandleResponse(ctx, err, nil)
return
diff --git a/internal/controller/template_controller.go
b/internal/controller/template_controller.go
index e6b94f4f..31cc5152 100644
--- a/internal/controller/template_controller.go
+++ b/internal/controller/template_controller.go
@@ -656,7 +656,7 @@ func (tc *TemplateController) SitemapPage(ctx *gin.Context)
{
}
func (tc *TemplateController) checkPrivateMode(ctx *gin.Context) bool {
- resp, err := tc.siteInfoService.GetSiteLogin(ctx)
+ resp, err := tc.siteInfoService.GetSiteSecurity(ctx)
if err != nil {
log.Error(err)
return false
diff --git a/internal/controller_admin/siteinfo_controller.go
b/internal/controller_admin/siteinfo_controller.go
index 056b01ae..339d2caa 100644
--- a/internal/controller_admin/siteinfo_controller.go
+++ b/internal/controller_admin/siteinfo_controller.go
@@ -134,16 +134,29 @@ func (sc *SiteInfoController) GetSiteAdvanced(ctx
*gin.Context) {
handler.HandleResponse(ctx, err, resp)
}
-// GetSiteLegal Set the legal information for the site
-// @Summary Set the legal information for the site
-// @Description Set the legal information for the site
+// GetSitePolicies Get the policies information for the site
+// @Summary Get the policies information for the site
+// @Description Get the policies information for the site
// @Security ApiKeyAuth
// @Tags admin
// @Produce json
-// @Success 200 {object} handler.RespBody{data=schema.SiteLegalResp}
-// @Router /answer/admin/api/siteinfo/legal [get]
-func (sc *SiteInfoController) GetSiteLegal(ctx *gin.Context) {
- resp, err := sc.siteInfoService.GetSiteLegal(ctx)
+// @Success 200 {object} handler.RespBody{data=schema.SitePoliciesResp}
+// @Router /answer/admin/api/siteinfo/polices [get]
+func (sc *SiteInfoController) GetSitePolicies(ctx *gin.Context) {
+ resp, err := sc.siteInfoService.GetSitePolicies(ctx)
+ handler.HandleResponse(ctx, err, resp)
+}
+
+// GetSiteSecurity Get the security information for the site
+// @Summary Get the security information for the site
+// @Description Get the security information for the site
+// @Security ApiKeyAuth
+// @Tags admin
+// @Produce json
+// @Success 200 {object} handler.RespBody{data=schema.SiteSecurityResp}
+// @Router /answer/admin/api/siteinfo/security [get]
+func (sc *SiteInfoController) GetSiteSecurity(ctx *gin.Context) {
+ resp, err := sc.siteInfoService.GetSiteSecurity(ctx)
handler.HandleResponse(ctx, err, resp)
}
@@ -403,21 +416,39 @@ func (sc *SiteInfoController) UpdateSiteAdvanced(ctx
*gin.Context) {
handler.HandleResponse(ctx, err, resp)
}
-// UpdateSiteLegal update site legal info
-// @Summary update site legal info
-// @Description update site legal info
+// UpdateSitePolices update site policies configuration
+// @Summary update site policies configuration
+// @Description update site policies configuration
+// @Security ApiKeyAuth
+// @Tags admin
+// @Produce json
+// @Param data body schema.SitePoliciesReq true "write info"
+// @Success 200 {object} handler.RespBody{}
+// @Router /answer/admin/api/siteinfo/polices [put]
+func (sc *SiteInfoController) UpdateSitePolices(ctx *gin.Context) {
+ req := &schema.SitePoliciesReq{}
+ if handler.BindAndCheck(ctx, req) {
+ return
+ }
+ err := sc.siteInfoService.SaveSitePolicies(ctx, req)
+ handler.HandleResponse(ctx, err, nil)
+}
+
+// UpdateSiteSecurity update site security configuration
+// @Summary update site security configuration
+// @Description update site security configuration
// @Security ApiKeyAuth
// @Tags admin
// @Produce json
-// @Param data body schema.SiteLegalReq true "write info"
+// @Param data body schema.SiteSecurityReq true "write info"
// @Success 200 {object} handler.RespBody{}
-// @Router /answer/admin/api/siteinfo/legal [put]
-func (sc *SiteInfoController) UpdateSiteLegal(ctx *gin.Context) {
- req := &schema.SiteLegalReq{}
+// @Router /answer/admin/api/siteinfo/security [put]
+func (sc *SiteInfoController) UpdateSiteSecurity(ctx *gin.Context) {
+ req := &schema.SiteSecurityReq{}
if handler.BindAndCheck(ctx, req) {
return
}
- err := sc.siteInfoService.SaveSiteLegal(ctx, req)
+ err := sc.siteInfoService.SaveSiteSecurity(ctx, req)
handler.HandleResponse(ctx, err, nil)
}
diff --git a/internal/migrations/init.go b/internal/migrations/init.go
index 8a72794f..97b32a3c 100644
--- a/internal/migrations/init.go
+++ b/internal/migrations/init.go
@@ -74,14 +74,17 @@ func (m *Mentor) InitDB() error {
m.do("init role power rel", m.initRolePowerRel)
m.do("init admin user role rel", m.initAdminUserRoleRel)
m.do("init site info interface", m.initSiteInfoInterface)
+ m.do("init site info users settings", m.initSiteInfoUsersSettings)
m.do("init site info general config", m.initSiteInfoGeneralData)
m.do("init site info login config", m.initSiteInfoLoginConfig)
m.do("init site info theme config", m.initSiteInfoThemeConfig)
m.do("init site info seo config", m.initSiteInfoSEOConfig)
m.do("init site info user config", m.initSiteInfoUsersConfig)
m.do("init site info privilege rank", m.initSiteInfoPrivilegeRank)
- m.do("init site info write", m.initSiteInfoWrite)
- m.do("init site info legal", m.initSiteInfoLegalConfig)
+ m.do("init site info write", m.initSiteInfoAdvanced)
+ m.do("init site info write", m.initSiteInfoQuestions)
+ m.do("init site info write", m.initSiteInfoTags)
+ m.do("init site info security", m.initSiteInfoSecurityConfig)
m.do("init default content", m.initDefaultContent)
m.do("init default badges", m.initDefaultBadges)
return m.err
@@ -181,19 +184,30 @@ func (m *Mentor) initSiteInfoInterface() {
}
interfaceData := map[string]string{
- "language": m.userData.Language,
- "time_zone": localTimezone,
- "default_avatar": "gravatar",
- "gravatar_base_url": "https://www.gravatar.com/avatar/",
+ "language": m.userData.Language,
+ "time_zone": localTimezone,
}
interfaceDataBytes, _ := json.Marshal(interfaceData)
_, m.err = m.engine.Context(m.ctx).Insert(&entity.SiteInfo{
- Type: "interface",
+ Type: "interface_settings",
Content: string(interfaceDataBytes),
Status: 1,
})
}
+func (m *Mentor) initSiteInfoUsersSettings() {
+ usersSettings := map[string]any{
+ "default_avatar": "gravatar",
+ "gravatar_base_url": "https://www.gravatar.com/avatar/",
+ }
+ usersSettingsDataBytes, _ := json.Marshal(usersSettings)
+ _, m.err = m.engine.Context(m.ctx).Insert(&entity.SiteInfo{
+ Type: "users_settings",
+ Content: string(usersSettingsDataBytes),
+ Status: 1,
+ })
+}
+
func (m *Mentor) initSiteInfoGeneralData() {
generalData := map[string]string{
"name": m.userData.SiteName,
@@ -213,7 +227,6 @@ func (m *Mentor) initSiteInfoLoginConfig() {
"allow_new_registrations": true,
"allow_email_registrations": true,
"allow_password_login": true,
- "login_required": m.userData.LoginRequired,
}
loginConfigDataBytes, _ := json.Marshal(loginConfig)
_, m.err = m.engine.Context(m.ctx).Insert(&entity.SiteInfo{
@@ -223,14 +236,16 @@ func (m *Mentor) initSiteInfoLoginConfig() {
})
}
-func (m *Mentor) initSiteInfoLegalConfig() {
- legalConfig := map[string]any{
+func (m *Mentor) initSiteInfoSecurityConfig() {
+ securityConfig := map[string]any{
+ "login_required": m.userData.LoginRequired,
"external_content_display": m.userData.ExternalContentDisplay,
+ "check_update": true,
}
- legalConfigDataBytes, _ := json.Marshal(legalConfig)
+ securityConfigDataBytes, _ := json.Marshal(securityConfig)
_, m.err = m.engine.Context(m.ctx).Insert(&entity.SiteInfo{
- Type: "legal",
- Content: string(legalConfigDataBytes),
+ Type: "security",
+ Content: string(securityConfigDataBytes),
Status: 1,
})
}
@@ -288,24 +303,46 @@ func (m *Mentor) initSiteInfoPrivilegeRank() {
})
}
-func (m *Mentor) initSiteInfoWrite() {
- writeData := map[string]any{
- "min_content": 6,
- "restrict_answer": true,
- "min_tags": 1,
- "required_tag": false,
- "recommend_tags": []string{},
- "reserved_tags": []string{},
+func (m *Mentor) initSiteInfoAdvanced() {
+ advancedData := map[string]any{
"max_image_size": 4,
"max_attachment_size": 8,
"max_image_megapixel": 40,
"authorized_image_extensions": []string{"jpg", "jpeg",
"png", "gif", "webp"},
"authorized_attachment_extensions": []string{},
}
- writeDataBytes, _ := json.Marshal(writeData)
+ advancedDataBytes, _ := json.Marshal(advancedData)
+ _, m.err = m.engine.Context(m.ctx).Insert(&entity.SiteInfo{
+ Type: "advanced",
+ Content: string(advancedDataBytes),
+ Status: 1,
+ })
+}
+
+func (m *Mentor) initSiteInfoQuestions() {
+ questionsData := map[string]any{
+ "min_tags": 1,
+ "min_content": 6,
+ "restrict_answer": true,
+ }
+ questionsDataBytes, _ := json.Marshal(questionsData)
+ _, m.err = m.engine.Context(m.ctx).Insert(&entity.SiteInfo{
+ Type: "questions",
+ Content: string(questionsDataBytes),
+ Status: 1,
+ })
+}
+
+func (m *Mentor) initSiteInfoTags() {
+ tagsData := map[string]any{
+ "required_tag": false,
+ "recommend_tags": []string{},
+ "reserved_tags": []string{},
+ }
+ tagsDataBytes, _ := json.Marshal(tagsData)
_, m.err = m.engine.Context(m.ctx).Insert(&entity.SiteInfo{
- Type: "write",
- Content: string(writeDataBytes),
+ Type: "tags",
+ Content: string(tagsDataBytes),
Status: 1,
})
}
diff --git a/internal/migrations/v30.go b/internal/migrations/v30.go
index 4d0f1130..c73f501d 100644
--- a/internal/migrations/v30.go
+++ b/internal/migrations/v30.go
@@ -37,6 +37,16 @@ func updateAdminMenuSettings(ctx context.Context, x
*xorm.Engine) (err error) {
if err != nil {
return
}
+
+ err = splitInterfaceMenu(ctx, x)
+ if err != nil {
+ return
+ }
+
+ err = splitLegalMenu(ctx, x)
+ if err != nil {
+ return
+ }
return
}
@@ -91,16 +101,7 @@ func splitWriteMenu(ctx context.Context, x *xorm.Engine)
error {
if err != nil {
return err
}
- if existsAdvanced {
- _, err =
x.Context(ctx).ID(siteInfoAdvanced.ID).Update(&entity.SiteInfo{
- Type: constant.SiteTypeAdvanced,
- Content: string(advancedContent),
- Status: 1,
- })
- if err != nil {
- return err
- }
- } else {
+ if !existsAdvanced {
_, err = x.Context(ctx).Insert(&entity.SiteInfo{
Type: constant.SiteTypeAdvanced,
Content: string(advancedContent),
@@ -120,16 +121,7 @@ func splitWriteMenu(ctx context.Context, x *xorm.Engine)
error {
if err != nil {
return err
}
- if existsQuestions {
- _, err =
x.Context(ctx).ID(siteInfoQuestions.ID).Update(&entity.SiteInfo{
- Type: constant.SiteTypeQuestions,
- Content: string(questionsContent),
- Status: 1,
- })
- if err != nil {
- return err
- }
- } else {
+ if !existsQuestions {
_, err = x.Context(ctx).Insert(&entity.SiteInfo{
Type: constant.SiteTypeQuestions,
Content: string(questionsContent),
@@ -149,16 +141,7 @@ func splitWriteMenu(ctx context.Context, x *xorm.Engine)
error {
if err != nil {
return err
}
- if existsTags {
- _, err =
x.Context(ctx).ID(siteInfoTags.ID).Update(&entity.SiteInfo{
- Type: constant.SiteTypeTags,
- Content: string(tagsContent),
- Status: 1,
- })
- if err != nil {
- return err
- }
- } else {
+ if !existsTags {
_, err = x.Context(ctx).Insert(&entity.SiteInfo{
Type: constant.SiteTypeTags,
Content: string(tagsContent),
@@ -172,6 +155,7 @@ func splitWriteMenu(ctx context.Context, x *xorm.Engine)
error {
return nil
}
+// splitInterfaceMenu splits the site interface settings into interface and
user settings
func splitInterfaceMenu(ctx context.Context, x *xorm.Engine) error {
var (
siteInfo = &entity.SiteInfo{}
@@ -216,16 +200,7 @@ func splitInterfaceMenu(ctx context.Context, x
*xorm.Engine) error {
if err != nil {
return err
}
- if existsUsers {
- _, err =
x.Context(ctx).ID(siteInfoUsers.ID).Update(&entity.SiteInfo{
- Type: constant.SiteTypeUsersSettings,
- Content: string(userContent),
- Status: 1,
- })
- if err != nil {
- return err
- }
- } else {
+ if !existsUsers {
_, err = x.Context(ctx).Insert(&entity.SiteInfo{
Type: constant.SiteTypeUsersSettings,
Content: string(userContent),
@@ -245,8 +220,8 @@ func splitInterfaceMenu(ctx context.Context, x
*xorm.Engine) error {
if err != nil {
return err
}
- if existsInterface {
- _, err =
x.Context(ctx).ID(siteInfoInterface.ID).Update(&entity.SiteInfo{
+ if !existsInterface {
+ _, err = x.Context(ctx).Insert(&entity.SiteInfo{
Type: constant.SiteTypeInterfaceSettings,
Content: string(interfaceContent),
Status: 1,
@@ -254,10 +229,150 @@ func splitInterfaceMenu(ctx context.Context, x
*xorm.Engine) error {
if err != nil {
return err
}
- } else {
+ }
+
+ return nil
+}
+
+// splitLegalMenu splits the site legal settings into policies and security
settings
+func splitLegalMenu(ctx context.Context, x *xorm.Engine) error {
+ var (
+ siteInfo = &entity.SiteInfo{}
+ siteInfoPolices = &entity.SiteInfo{}
+ siteInfoSecurity = &entity.SiteInfo{}
+ siteInfoLogin = &entity.SiteInfo{}
+ siteInfoGeneral = &entity.SiteInfo{}
+ )
+
+ type SiteLogin struct {
+ AllowNewRegistrations bool
`json:"allow_new_registrations"`
+ AllowEmailRegistrations bool
`json:"allow_email_registrations"`
+ AllowPasswordLogin bool `json:"allow_password_login"`
+ LoginRequired bool `json:"login_required"`
+ AllowEmailDomains []string `json:"allow_email_domains"`
+ }
+
+ type SiteGeneral struct {
+ Name string
`validate:"required,sanitizer,gt=1,lte=128" form:"name" json:"name"`
+ ShortDescription string
`validate:"omitempty,sanitizer,gt=3,lte=255" form:"short_description"
json:"short_description"`
+ Description string
`validate:"omitempty,sanitizer,gt=3,lte=2000" form:"description"
json:"description"`
+ SiteUrl string
`validate:"required,sanitizer,gt=1,lte=512,url" form:"site_url" json:"site_url"`
+ ContactEmail string
`validate:"required,sanitizer,gt=1,lte=512,email" form:"contact_email"
json:"contact_email"`
+ CheckUpdate bool `validate:"omitempty,sanitizer"
form:"check_update" json:"check_update"`
+ }
+
+ // find old site legal settings
+ exist, err := x.Context(ctx).Where(builder.Eq{"type":
constant.SiteTypeLegal}).Get(siteInfo)
+ if err != nil {
+ err =
errors.InternalServer(reason.DatabaseError).WithError(err).WithStack()
+ return err
+ }
+ if !exist {
+ return nil
+ }
+ oldSiteLegal := &schema.SiteLegalResp{}
+ if err := json.Unmarshal([]byte(siteInfo.Content), oldSiteLegal); err
!= nil {
+ return err
+ }
+
+ // find old site login settings
+ existsLogin, err := x.Context(ctx).Where(builder.Eq{"type":
constant.SiteTypeLogin}).Get(siteInfoLogin)
+ if err != nil {
+ return err
+ }
+ oldSiteLogin := &SiteLogin{}
+ if err := json.Unmarshal([]byte(siteInfoLogin.Content), oldSiteLogin);
err != nil {
+ return err
+ }
+
+ // find old site general settings
+ existGeneral, err := x.Context(ctx).Where(builder.Eq{"type":
constant.SiteTypeGeneral}).Get(siteInfoGeneral)
+ if err != nil {
+ return err
+ }
+ oldSiteGeneral := &SiteGeneral{}
+ if err := json.Unmarshal([]byte(siteInfoLogin.Content),
oldSiteGeneral); err != nil {
+ return err
+ }
+
+ sitePolicies := &schema.SitePoliciesResp{
+ TermsOfServiceOriginalText:
oldSiteLegal.TermsOfServiceOriginalText,
+ TermsOfServiceParsedText:
oldSiteLegal.TermsOfServiceParsedText,
+ PrivacyPolicyOriginalText:
oldSiteLegal.PrivacyPolicyOriginalText,
+ PrivacyPolicyParsedText:
oldSiteLegal.PrivacyPolicyParsedText,
+ }
+ siteLogin := &schema.SiteLoginResp{
+ AllowNewRegistrations: oldSiteLogin.AllowNewRegistrations,
+ AllowEmailRegistrations: oldSiteLogin.AllowEmailRegistrations,
+ AllowPasswordLogin: oldSiteLogin.AllowPasswordLogin,
+ AllowEmailDomains: oldSiteLogin.AllowEmailDomains,
+ }
+ siteGeneral := &schema.SiteGeneralReq{
+ Name: oldSiteGeneral.Name,
+ ShortDescription: oldSiteGeneral.ShortDescription,
+ Description: oldSiteGeneral.Description,
+ SiteUrl: oldSiteGeneral.SiteUrl,
+ ContactEmail: oldSiteGeneral.ContactEmail,
+ }
+ siteSecurity := &schema.SiteSecurityResp{
+ LoginRequired: oldSiteLogin.LoginRequired,
+ ExternalContentDisplay: oldSiteLegal.ExternalContentDisplay,
+ CheckUpdate: oldSiteGeneral.CheckUpdate,
+ }
+ if !existsLogin {
+ siteSecurity.LoginRequired = false
+ }
+ if !existGeneral {
+ siteSecurity.CheckUpdate = true
+ }
+
+ // save settings
+ // save policies settings
+ existsPolicies, err := x.Context(ctx).Where(builder.Eq{"type":
constant.SiteTypePolicies}).Get(siteInfoPolices)
+ if err != nil {
+ return err
+ }
+ policiesContent, err := json.Marshal(sitePolicies)
+ if err != nil {
+ return err
+ }
+ if !existsPolicies {
+ _, err = x.Context(ctx).Insert(&entity.SiteInfo{
+ Type: constant.SiteTypePolicies,
+ Content: string(policiesContent),
+ Status: 1,
+ })
+ if err != nil {
+ return err
+ }
+ }
+
+ // save security settings
+ existsSecurity, err := x.Context(ctx).Where(builder.Eq{"type":
constant.SiteTypeSecurity}).Get(siteInfoSecurity)
+ if err != nil {
+ return err
+ }
+ securityContent, err := json.Marshal(siteSecurity)
+ if err != nil {
+ return err
+ }
+ if !existsSecurity {
_, err = x.Context(ctx).Insert(&entity.SiteInfo{
- Type: constant.SiteTypeInterfaceSettings,
- Content: string(interfaceContent),
+ Type: constant.SiteTypeSecurity,
+ Content: string(securityContent),
+ Status: 1,
+ })
+ if err != nil {
+ return err
+ }
+ }
+
+ // save login settings
+ if existsLogin {
+ loginContent, err := json.Marshal(siteLogin)
+ _, err =
x.Context(ctx).ID(siteInfoLogin.ID).Update(&entity.SiteInfo{
+ Type: constant.SiteTypeLogin,
+ Content: string(loginContent),
Status: 1,
})
if err != nil {
@@ -265,5 +380,17 @@ func splitInterfaceMenu(ctx context.Context, x
*xorm.Engine) error {
}
}
+ // save general settings
+ if existGeneral {
+ generalContent, err := json.Marshal(siteGeneral)
+ _, err =
x.Context(ctx).ID(siteInfoGeneral.ID).Update(&entity.SiteInfo{
+ Type: constant.SiteTypeGeneral,
+ Content: string(generalContent),
+ Status: 1,
+ })
+ if err != nil {
+ return err
+ }
+ }
return nil
}
diff --git a/internal/router/answer_api_router.go
b/internal/router/answer_api_router.go
index c776b44f..1fe8bdb1 100644
--- a/internal/router/answer_api_router.go
+++ b/internal/router/answer_api_router.go
@@ -359,8 +359,11 @@ func (a *AnswerAPIRouter) RegisterAnswerAdminAPIRouter(r
*gin.RouterGroup) {
r.GET("/siteinfo/advanced", a.adminSiteInfoController.GetSiteAdvanced)
r.PUT("/siteinfo/advanced",
a.adminSiteInfoController.UpdateSiteAdvanced)
- r.GET("/siteinfo/legal", a.adminSiteInfoController.GetSiteLegal)
- r.PUT("/siteinfo/legal", a.adminSiteInfoController.UpdateSiteLegal)
+ r.GET("/siteinfo/polices", a.adminSiteInfoController.GetSitePolicies)
+ r.PUT("/siteinfo/polices", a.adminSiteInfoController.UpdateSitePolices)
+ r.GET("/siteinfo/security", a.adminSiteInfoController.GetSiteSecurity)
+ r.PUT("/siteinfo/security",
a.adminSiteInfoController.UpdateSiteSecurity)
+
r.GET("/siteinfo/seo", a.adminSiteInfoController.GetSeo)
r.PUT("/siteinfo/seo", a.adminSiteInfoController.UpdateSeo)
r.GET("/siteinfo/login", a.adminSiteInfoController.GetSiteLogin)
diff --git a/internal/schema/siteinfo_schema.go
b/internal/schema/siteinfo_schema.go
index a060558a..563b0cc1 100644
--- a/internal/schema/siteinfo_schema.go
+++ b/internal/schema/siteinfo_schema.go
@@ -42,7 +42,6 @@ type SiteGeneralReq struct {
Description string `validate:"omitempty,sanitizer,gt=3,lte=2000"
form:"description" json:"description"`
SiteUrl string `validate:"required,sanitizer,gt=1,lte=512,url"
form:"site_url" json:"site_url"`
ContactEmail string
`validate:"required,sanitizer,gt=1,lte=512,email" form:"contact_email"
json:"contact_email"`
- CheckUpdate bool `validate:"omitempty,sanitizer"
form:"check_update" json:"check_update"`
}
func (r *SiteGeneralReq) FormatSiteUrl() {
@@ -158,6 +157,7 @@ type SiteWriteTag struct {
}
// SiteLegalReq site branding request
+// Deprecated: use SitePoliciesReq and SiteSecurityReq instead
type SiteLegalReq struct {
TermsOfServiceOriginalText string
`json:"terms_of_service_original_text"`
TermsOfServiceParsedText string `json:"terms_of_service_parsed_text"`
@@ -166,6 +166,22 @@ type SiteLegalReq struct {
ExternalContentDisplay string
`validate:"required,oneof=always_display ask_before_display"
json:"external_content_display"`
}
+type SitePoliciesReq struct {
+ TermsOfServiceOriginalText string
`json:"terms_of_service_original_text"`
+ TermsOfServiceParsedText string `json:"terms_of_service_parsed_text"`
+ PrivacyPolicyOriginalText string `json:"privacy_policy_original_text"`
+ PrivacyPolicyParsedText string `json:"privacy_policy_parsed_text"`
+}
+
+type SiteSecurityReq struct {
+ LoginRequired bool `json:"login_required"`
+ ExternalContentDisplay string `validate:"required,oneof=always_display
ask_before_display" json:"external_content_display"`
+ CheckUpdate bool `validate:"omitempty,sanitizer"
form:"check_update" json:"check_update"`
+}
+
+type SitePoliciesResp SitePoliciesReq
+type SiteSecurityResp SiteSecurityReq
+
// GetSiteLegalInfoReq site site legal request
type GetSiteLegalInfoReq struct {
InfoType string `validate:"required,oneof=tos privacy" form:"info_type"`
@@ -204,7 +220,6 @@ type SiteLoginReq struct {
AllowNewRegistrations bool `json:"allow_new_registrations"`
AllowEmailRegistrations bool `json:"allow_email_registrations"`
AllowPasswordLogin bool `json:"allow_password_login"`
- LoginRequired bool `json:"login_required"`
AllowEmailDomains []string `json:"allow_email_domains"`
}
@@ -282,6 +297,7 @@ type SiteAdvancedResp SiteAdvancedReq
type SiteTagsResp SiteTagsReq
// SiteLegalResp site write response
+// Deprecated: use SitePoliciesResp and SiteSecurityResp instead
type SiteLegalResp SiteLegalReq
// SiteLegalSimpleResp site write response
@@ -311,7 +327,6 @@ type SiteInfoResp struct {
Revision string `json:"revision"`
}
-// todo: 检查模板使用
type TemplateSiteInfoResp struct {
General *SiteGeneralResp `json:"general"`
Interface *SiteInterfaceSettingsResp `json:"interface"`
diff --git a/internal/service/dashboard/dashboard_service.go
b/internal/service/dashboard/dashboard_service.go
index 8b08ba02..a6ac76e6 100644
--- a/internal/service/dashboard/dashboard_service.go
+++ b/internal/service/dashboard/dashboard_service.go
@@ -101,6 +101,12 @@ type DashboardService interface {
func (ds *dashboardService) Statistical(ctx context.Context)
(*schema.DashboardInfo, error) {
dashboardInfo := ds.getFromCache(ctx)
+ security, err := ds.siteInfoService.GetSiteSecurity(ctx)
+ if err != nil {
+ log.Errorf("get general site info failed: %s", err)
+ return dashboardInfo, nil
+ }
+
if dashboardInfo == nil {
dashboardInfo = &schema.DashboardInfo{}
dashboardInfo.AnswerCount = ds.answerCount(ctx)
@@ -108,12 +114,7 @@ func (ds *dashboardService) Statistical(ctx
context.Context) (*schema.DashboardI
dashboardInfo.UserCount = ds.userCount(ctx)
dashboardInfo.VoteCount = ds.voteCount(ctx)
dashboardInfo.OccupyingStorageSpace = ds.calculateStorage()
- general, err := ds.siteInfoService.GetSiteGeneral(ctx)
- if err != nil {
- log.Errorf("get general site info failed: %s", err)
- return dashboardInfo, nil
- }
- if general.CheckUpdate {
+ if security.CheckUpdate {
dashboardInfo.VersionInfo.RemoteVersion =
ds.remoteVersion(ctx)
}
dashboardInfo.DatabaseVersion = ds.getDatabaseInfo()
@@ -141,9 +142,7 @@ func (ds *dashboardService) Statistical(ctx
context.Context) (*schema.DashboardI
dashboardInfo.VersionInfo.Version = constant.Version
dashboardInfo.VersionInfo.Revision = constant.Revision
dashboardInfo.GoVersion = constant.GoVersion
- if siteLogin, err := ds.siteInfoService.GetSiteLogin(ctx); err == nil {
- dashboardInfo.LoginRequired = siteLogin.LoginRequired
- }
+ dashboardInfo.LoginRequired = security.LoginRequired
ds.setCache(ctx, dashboardInfo)
return dashboardInfo, nil
diff --git a/internal/service/mock/siteinfo_repo_mock.go
b/internal/service/mock/siteinfo_repo_mock.go
index 5d5429ba..a4d9d97b 100644
--- a/internal/service/mock/siteinfo_repo_mock.go
+++ b/internal/service/mock/siteinfo_repo_mock.go
@@ -231,10 +231,10 @@ func (mr *MockSiteInfoCommonServiceMockRecorder)
GetSiteInfoByType(ctx, siteType
}
// GetSiteInterface mocks base method.
-func (m *MockSiteInfoCommonService) GetSiteInterface(ctx context.Context)
(*schema.SiteInterfaceResp, error) {
+func (m *MockSiteInfoCommonService) GetSiteInterface(ctx context.Context)
(*schema.SiteInterfaceSettingsResp, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "GetSiteInterface", ctx)
- ret0, _ := ret[0].(*schema.SiteInterfaceResp)
+ ret0, _ := ret[0].(*schema.SiteInterfaceSettingsResp)
ret1, _ := ret[1].(error)
return ret0, ret1
}
@@ -245,34 +245,34 @@ func (mr *MockSiteInfoCommonServiceMockRecorder)
GetSiteInterface(ctx interface{
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock,
"GetSiteInterface",
reflect.TypeOf((*MockSiteInfoCommonService)(nil).GetSiteInterface), ctx)
}
-// GetSiteLegal mocks base method.
-func (m *MockSiteInfoCommonService) GetSiteLegal(ctx context.Context)
(*schema.SiteLegalResp, error) {
+// GetSiteLogin mocks base method.
+func (m *MockSiteInfoCommonService) GetSiteLogin(ctx context.Context)
(*schema.SiteLoginResp, error) {
m.ctrl.T.Helper()
- ret := m.ctrl.Call(m, "GetSiteLegal", ctx)
- ret0, _ := ret[0].(*schema.SiteLegalResp)
+ ret := m.ctrl.Call(m, "GetSiteLogin", ctx)
+ ret0, _ := ret[0].(*schema.SiteLoginResp)
ret1, _ := ret[1].(error)
return ret0, ret1
}
-// GetSiteLegal indicates an expected call of GetSiteLegal.
-func (mr *MockSiteInfoCommonServiceMockRecorder) GetSiteLegal(ctx interface{})
*gomock.Call {
+// GetSiteLogin indicates an expected call of GetSiteLogin.
+func (mr *MockSiteInfoCommonServiceMockRecorder) GetSiteLogin(ctx interface{})
*gomock.Call {
mr.mock.ctrl.T.Helper()
- return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetSiteLegal",
reflect.TypeOf((*MockSiteInfoCommonService)(nil).GetSiteLegal), ctx)
+ return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetSiteLogin",
reflect.TypeOf((*MockSiteInfoCommonService)(nil).GetSiteLogin), ctx)
}
-// GetSiteLogin mocks base method.
-func (m *MockSiteInfoCommonService) GetSiteLogin(ctx context.Context)
(*schema.SiteLoginResp, error) {
+// GetSitePolicies mocks base method.
+func (m *MockSiteInfoCommonService) GetSitePolicies(ctx context.Context)
(*schema.SitePoliciesResp, error) {
m.ctrl.T.Helper()
- ret := m.ctrl.Call(m, "GetSiteLogin", ctx)
- ret0, _ := ret[0].(*schema.SiteLoginResp)
+ ret := m.ctrl.Call(m, "GetSitePolicies", ctx)
+ ret0, _ := ret[0].(*schema.SitePoliciesResp)
ret1, _ := ret[1].(error)
return ret0, ret1
}
-// GetSiteLogin indicates an expected call of GetSiteLogin.
-func (mr *MockSiteInfoCommonServiceMockRecorder) GetSiteLogin(ctx interface{})
*gomock.Call {
+// GetSitePolicies indicates an expected call of GetSitePolicies.
+func (mr *MockSiteInfoCommonServiceMockRecorder) GetSitePolicies(ctx
interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
- return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetSiteLogin",
reflect.TypeOf((*MockSiteInfoCommonService)(nil).GetSiteLogin), ctx)
+ return mr.mock.ctrl.RecordCallWithMethodType(mr.mock,
"GetSitePolicies",
reflect.TypeOf((*MockSiteInfoCommonService)(nil).GetSitePolicies), ctx)
}
// GetSiteQuestion mocks base method.
@@ -290,6 +290,21 @@ func (mr *MockSiteInfoCommonServiceMockRecorder)
GetSiteQuestion(ctx interface{}
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock,
"GetSiteQuestion",
reflect.TypeOf((*MockSiteInfoCommonService)(nil).GetSiteQuestion), ctx)
}
+// GetSiteSecurity mocks base method.
+func (m *MockSiteInfoCommonService) GetSiteSecurity(ctx context.Context)
(*schema.SiteSecurityResp, error) {
+ m.ctrl.T.Helper()
+ ret := m.ctrl.Call(m, "GetSiteSecurity", ctx)
+ ret0, _ := ret[0].(*schema.SiteSecurityResp)
+ ret1, _ := ret[1].(error)
+ return ret0, ret1
+}
+
+// GetSiteSecurity indicates an expected call of GetSiteSecurity.
+func (mr *MockSiteInfoCommonServiceMockRecorder) GetSiteSecurity(ctx
interface{}) *gomock.Call {
+ mr.mock.ctrl.T.Helper()
+ return mr.mock.ctrl.RecordCallWithMethodType(mr.mock,
"GetSiteSecurity",
reflect.TypeOf((*MockSiteInfoCommonService)(nil).GetSiteSecurity), ctx)
+}
+
// GetSiteSeo mocks base method.
func (m *MockSiteInfoCommonService) GetSiteSeo(ctx context.Context)
(*schema.SiteSeoResp, error) {
m.ctrl.T.Helper()
@@ -350,6 +365,21 @@ func (mr *MockSiteInfoCommonServiceMockRecorder)
GetSiteUsers(ctx interface{}) *
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetSiteUsers",
reflect.TypeOf((*MockSiteInfoCommonService)(nil).GetSiteUsers), ctx)
}
+// GetSiteUsersSettings mocks base method.
+func (m *MockSiteInfoCommonService) GetSiteUsersSettings(ctx context.Context)
(*schema.SiteUsersSettingsResp, error) {
+ m.ctrl.T.Helper()
+ ret := m.ctrl.Call(m, "GetSiteUsersSettings", ctx)
+ ret0, _ := ret[0].(*schema.SiteUsersSettingsResp)
+ ret1, _ := ret[1].(error)
+ return ret0, ret1
+}
+
+// GetSiteUsersSettings indicates an expected call of GetSiteUsersSettings.
+func (mr *MockSiteInfoCommonServiceMockRecorder) GetSiteUsersSettings(ctx
interface{}) *gomock.Call {
+ mr.mock.ctrl.T.Helper()
+ return mr.mock.ctrl.RecordCallWithMethodType(mr.mock,
"GetSiteUsersSettings",
reflect.TypeOf((*MockSiteInfoCommonService)(nil).GetSiteUsersSettings), ctx)
+}
+
// GetSiteWrite mocks base method.
func (m *MockSiteInfoCommonService) GetSiteWrite(ctx context.Context)
(*schema.SiteWriteResp, error) {
m.ctrl.T.Helper()
diff --git a/internal/service/siteinfo/siteinfo_service.go
b/internal/service/siteinfo/siteinfo_service.go
index 956511ce..d374008c 100644
--- a/internal/service/siteinfo/siteinfo_service.go
+++ b/internal/service/siteinfo/siteinfo_service.go
@@ -138,9 +138,14 @@ func (s *SiteInfoService) GetSiteAdvanced(ctx
context.Context) (resp *schema.Sit
return s.siteInfoCommonService.GetSiteAdvanced(ctx)
}
-// GetSiteLegal get site legal info
-func (s *SiteInfoService) GetSiteLegal(ctx context.Context) (resp
*schema.SiteLegalResp, err error) {
- return s.siteInfoCommonService.GetSiteLegal(ctx)
+// GetSitePolicies get site legal info
+func (s *SiteInfoService) GetSitePolicies(ctx context.Context) (resp
*schema.SitePoliciesResp, err error) {
+ return s.siteInfoCommonService.GetSitePolicies(ctx)
+}
+
+// GetSiteSecurity get site security info
+func (s *SiteInfoService) GetSiteSecurity(ctx context.Context) (resp
*schema.SiteSecurityResp, err error) {
+ return s.siteInfoCommonService.GetSiteSecurity(ctx)
}
// GetSiteLogin get site login info
@@ -261,15 +266,26 @@ func (s *SiteInfoService) SaveSiteTags(ctx
context.Context, req *schema.SiteTags
return nil, s.siteInfoRepo.SaveByType(ctx, constant.SiteTypeTags, data)
}
-// SaveSiteLegal save site legal configuration
-func (s *SiteInfoService) SaveSiteLegal(ctx context.Context, req
*schema.SiteLegalReq) (err error) {
+// SaveSitePolicies save site policies configuration
+func (s *SiteInfoService) SaveSitePolicies(ctx context.Context, req
*schema.SitePoliciesReq) (err error) {
+ content, _ := json.Marshal(req)
+ data := &entity.SiteInfo{
+ Type: constant.SiteTypePolicies,
+ Content: string(content),
+ Status: 1,
+ }
+ return s.siteInfoRepo.SaveByType(ctx, constant.SiteTypePolicies, data)
+}
+
+// SaveSiteSecurity save site security configuration
+func (s *SiteInfoService) SaveSiteSecurity(ctx context.Context, req
*schema.SiteSecurityReq) (err error) {
content, _ := json.Marshal(req)
data := &entity.SiteInfo{
- Type: constant.SiteTypeLegal,
+ Type: constant.SiteTypeSecurity,
Content: string(content),
Status: 1,
}
- return s.siteInfoRepo.SaveByType(ctx, constant.SiteTypeLegal, data)
+ return s.siteInfoRepo.SaveByType(ctx, constant.SiteTypeSecurity, data)
}
// SaveSiteLogin save site legal configuration
@@ -361,13 +377,13 @@ func (s *SiteInfoService) GetSeo(ctx context.Context)
(resp *schema.SiteSeoReq,
if err = s.siteInfoCommonService.GetSiteInfoByType(ctx,
constant.SiteTypeSeo, resp); err != nil {
return resp, err
}
- loginConfig, err := s.GetSiteLogin(ctx)
+ siteSecurity, err := s.GetSiteSecurity(ctx)
if err != nil {
log.Error(err)
return resp, nil
}
// If the site is set to privacy mode, prohibit crawling any page.
- if loginConfig.LoginRequired {
+ if siteSecurity.LoginRequired {
resp.Robots = "User-agent: *\nDisallow: /"
return resp, nil
}
diff --git a/internal/service/siteinfo_common/siteinfo_service.go
b/internal/service/siteinfo_common/siteinfo_service.go
index dde0114b..5ed39913 100644
--- a/internal/service/siteinfo_common/siteinfo_service.go
+++ b/internal/service/siteinfo_common/siteinfo_service.go
@@ -55,7 +55,8 @@ type SiteInfoCommonService interface {
GetSiteAdvanced(ctx context.Context) (resp *schema.SiteAdvancedResp,
err error)
GetSiteQuestion(ctx context.Context) (resp *schema.SiteQuestionsResp,
err error)
GetSiteTag(ctx context.Context) (resp *schema.SiteTagsResp, err error)
- GetSiteLegal(ctx context.Context) (resp *schema.SiteLegalResp, err
error)
+ GetSitePolicies(ctx context.Context) (resp *schema.SitePoliciesResp,
err error)
+ GetSiteSecurity(ctx context.Context) (resp *schema.SiteSecurityResp,
err error)
GetSiteLogin(ctx context.Context) (resp *schema.SiteLoginResp, err
error)
GetSiteCustomCssHTML(ctx context.Context) (resp
*schema.SiteCustomCssHTMLResp, err error)
GetSiteTheme(ctx context.Context) (resp *schema.SiteThemeResp, err
error)
@@ -73,7 +74,7 @@ func NewSiteInfoCommonService(siteInfoRepo SiteInfoRepo)
SiteInfoCommonService {
// GetSiteGeneral get site info general
func (s *siteInfoCommonService) GetSiteGeneral(ctx context.Context) (resp
*schema.SiteGeneralResp, err error) {
- resp = &schema.SiteGeneralResp{CheckUpdate: true}
+ resp = &schema.SiteGeneralResp{}
if err = s.GetSiteInfoByType(ctx, constant.SiteTypeGeneral, resp); err
!= nil {
return nil, err
}
@@ -207,10 +208,19 @@ func (s *siteInfoCommonService) GetSiteTag(ctx
context.Context) (resp *schema.Si
return resp, nil
}
-// GetSiteLegal get site info write
-func (s *siteInfoCommonService) GetSiteLegal(ctx context.Context) (resp
*schema.SiteLegalResp, err error) {
- resp = &schema.SiteLegalResp{}
- if err = s.GetSiteInfoByType(ctx, constant.SiteTypeLegal, resp); err !=
nil {
+// GetSitePolicies get site info policies
+func (s *siteInfoCommonService) GetSitePolicies(ctx context.Context) (resp
*schema.SitePoliciesResp, err error) {
+ resp = &schema.SitePoliciesResp{}
+ if err = s.GetSiteInfoByType(ctx, constant.SiteTypePolicies, resp); err
!= nil {
+ return nil, err
+ }
+ return resp, nil
+}
+
+// GetSiteSecurity get site security config
+func (s *siteInfoCommonService) GetSiteSecurity(ctx context.Context) (resp
*schema.SiteSecurityResp, err error) {
+ resp = &schema.SiteSecurityResp{CheckUpdate: true}
+ if err = s.GetSiteInfoByType(ctx, constant.SiteTypeSecurity, resp); err
!= nil {
return nil, err
}
return resp, nil