398 lines
12 KiB
Go
398 lines
12 KiB
Go
/*
|
|
* Licensed to the Apache Software Foundation (ASF) under one
|
|
* or more contributor license agreements. See the NOTICE file
|
|
* distributed with this work for additional information
|
|
* regarding copyright ownership. The ASF licenses this file
|
|
* to you under the Apache License, Version 2.0 (the
|
|
* "License"); you may not use this file except in compliance
|
|
* with the License. You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing,
|
|
* software distributed under the License is distributed on an
|
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
|
* KIND, either express or implied. See the License for the
|
|
* specific language governing permissions and limitations
|
|
* under the License.
|
|
*/
|
|
|
|
package migrations
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
|
|
"github.com/apache/answer/internal/base/constant"
|
|
"github.com/apache/answer/internal/base/reason"
|
|
"github.com/apache/answer/internal/entity"
|
|
"github.com/apache/answer/internal/schema"
|
|
"github.com/segmentfault/pacman/errors"
|
|
"xorm.io/builder"
|
|
"xorm.io/xorm"
|
|
)
|
|
|
|
func updateAdminMenuSettings(ctx context.Context, x *xorm.Engine) (err error) {
|
|
err = splitWriteMenu(ctx, x)
|
|
if err != nil {
|
|
return
|
|
}
|
|
|
|
err = splitInterfaceMenu(ctx, x)
|
|
if err != nil {
|
|
return
|
|
}
|
|
|
|
err = splitLegalMenu(ctx, x)
|
|
if err != nil {
|
|
return
|
|
}
|
|
return
|
|
}
|
|
|
|
// splitWriteMenu splits the site write settings into advanced, questions, and tags settings
|
|
func splitWriteMenu(ctx context.Context, x *xorm.Engine) error {
|
|
var (
|
|
siteInfo = &entity.SiteInfo{}
|
|
siteInfoAdvanced = &entity.SiteInfo{}
|
|
siteInfoQuestions = &entity.SiteInfo{}
|
|
siteInfoTags = &entity.SiteInfo{}
|
|
)
|
|
exist, err := x.Context(ctx).Where(builder.Eq{"type": constant.SiteTypeWrite}).Get(siteInfo)
|
|
if err != nil {
|
|
err = errors.InternalServer(reason.DatabaseError).WithError(err).WithStack()
|
|
return err
|
|
}
|
|
if !exist {
|
|
return nil
|
|
}
|
|
siteWrite := &schema.SiteWriteResp{}
|
|
if err := json.Unmarshal([]byte(siteInfo.Content), siteWrite); err != nil {
|
|
return err
|
|
}
|
|
// site advanced settings
|
|
siteAdvanced := &schema.SiteAdvancedResp{
|
|
MaxImageSize: siteWrite.MaxImageSize,
|
|
MaxAttachmentSize: siteWrite.MaxAttachmentSize,
|
|
MaxImageMegapixel: siteWrite.MaxImageMegapixel,
|
|
AuthorizedImageExtensions: siteWrite.AuthorizedImageExtensions,
|
|
AuthorizedAttachmentExtensions: siteWrite.AuthorizedAttachmentExtensions,
|
|
}
|
|
// site questions settings
|
|
siteQuestions := &schema.SiteQuestionsResp{
|
|
MinimumTags: siteWrite.MinimumTags,
|
|
MinimumContent: siteWrite.MinimumContent,
|
|
RestrictAnswer: siteWrite.RestrictAnswer,
|
|
}
|
|
// site tags settings
|
|
siteTags := &schema.SiteTagsResp{
|
|
ReservedTags: siteWrite.ReservedTags,
|
|
RecommendTags: siteWrite.RecommendTags,
|
|
RequiredTag: siteWrite.RequiredTag,
|
|
}
|
|
|
|
// save site settings
|
|
// save advanced settings
|
|
existsAdvanced, err := x.Context(ctx).Where(builder.Eq{"type": constant.SiteTypeWrite}).Get(siteInfoAdvanced)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
advancedContent, err := json.Marshal(siteAdvanced)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if !existsAdvanced {
|
|
_, err = x.Context(ctx).Insert(&entity.SiteInfo{
|
|
Type: constant.SiteTypeAdvanced,
|
|
Content: string(advancedContent),
|
|
Status: 1,
|
|
})
|
|
if err != nil {
|
|
return err
|
|
}
|
|
}
|
|
|
|
// save questions settings
|
|
existsQuestions, err := x.Context(ctx).Where(builder.Eq{"type": constant.SiteTypeQuestions}).Get(siteInfoQuestions)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
questionsContent, err := json.Marshal(siteQuestions)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if !existsQuestions {
|
|
_, err = x.Context(ctx).Insert(&entity.SiteInfo{
|
|
Type: constant.SiteTypeQuestions,
|
|
Content: string(questionsContent),
|
|
Status: 1,
|
|
})
|
|
if err != nil {
|
|
return err
|
|
}
|
|
}
|
|
|
|
// save tags settings
|
|
existsTags, err := x.Context(ctx).Where(builder.Eq{"type": constant.SiteTypeTags}).Get(siteInfoTags)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
tagsContent, err := json.Marshal(siteTags)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if !existsTags {
|
|
_, err = x.Context(ctx).Insert(&entity.SiteInfo{
|
|
Type: constant.SiteTypeTags,
|
|
Content: string(tagsContent),
|
|
Status: 1,
|
|
})
|
|
if err != nil {
|
|
return err
|
|
}
|
|
}
|
|
|
|
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{}
|
|
siteInfoInterface = &entity.SiteInfo{}
|
|
siteInfoUsers = &entity.SiteInfo{}
|
|
)
|
|
type SiteInterface struct {
|
|
Language string `validate:"required,gt=1,lte=128" form:"language" json:"language"`
|
|
TimeZone string `validate:"required,gt=1,lte=128" form:"time_zone" json:"time_zone"`
|
|
DefaultAvatar string `validate:"required,oneof=system gravatar" json:"default_avatar"`
|
|
GravatarBaseURL string `validate:"omitempty" json:"gravatar_base_url"`
|
|
}
|
|
|
|
exist, err := x.Context(ctx).Where(builder.Eq{"type": constant.SiteTypeInterface}).Get(siteInfo)
|
|
if err != nil {
|
|
err = errors.InternalServer(reason.DatabaseError).WithError(err).WithStack()
|
|
return err
|
|
}
|
|
if !exist {
|
|
return nil
|
|
}
|
|
oldSiteInterface := &SiteInterface{}
|
|
if err := json.Unmarshal([]byte(siteInfo.Content), oldSiteInterface); err != nil {
|
|
return err
|
|
}
|
|
siteUser := &schema.SiteUsersSettingsResp{
|
|
DefaultAvatar: oldSiteInterface.DefaultAvatar,
|
|
GravatarBaseURL: oldSiteInterface.GravatarBaseURL,
|
|
}
|
|
siteInterface := &schema.SiteInterfaceResp{
|
|
Language: oldSiteInterface.Language,
|
|
TimeZone: oldSiteInterface.TimeZone,
|
|
}
|
|
|
|
// save settings
|
|
// save user settings
|
|
existsUsers, err := x.Context(ctx).Where(builder.Eq{"type": constant.SiteTypeUsersSettings}).Get(siteInfoUsers)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
userContent, err := json.Marshal(siteUser)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if !existsUsers {
|
|
_, err = x.Context(ctx).Insert(&entity.SiteInfo{
|
|
Type: constant.SiteTypeUsersSettings,
|
|
Content: string(userContent),
|
|
Status: 1,
|
|
})
|
|
if err != nil {
|
|
return err
|
|
}
|
|
}
|
|
|
|
// save interface settings
|
|
existsInterface, err := x.Context(ctx).Where(builder.Eq{"type": constant.SiteTypeInterfaceSettings}).Get(siteInfoInterface)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
interfaceContent, err := json.Marshal(siteInterface)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if !existsInterface {
|
|
_, err = x.Context(ctx).Insert(&entity.SiteInfo{
|
|
Type: constant.SiteTypeInterfaceSettings,
|
|
Content: string(interfaceContent),
|
|
Status: 1,
|
|
})
|
|
if err != nil {
|
|
return err
|
|
}
|
|
}
|
|
|
|
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(siteInfoGeneral.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,
|
|
RequireEmailVerification: true,
|
|
}
|
|
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.SiteTypeSecurity,
|
|
Content: string(securityContent),
|
|
Status: 1,
|
|
})
|
|
if err != nil {
|
|
return err
|
|
}
|
|
}
|
|
|
|
// save login settings
|
|
if existsLogin {
|
|
loginContent, _ := json.Marshal(siteLogin)
|
|
_, err = x.Context(ctx).ID(siteInfoLogin.ID).Update(&entity.SiteInfo{
|
|
Type: constant.SiteTypeLogin,
|
|
Content: string(loginContent),
|
|
Status: 1,
|
|
})
|
|
if err != nil {
|
|
return err
|
|
}
|
|
}
|
|
|
|
// save general settings
|
|
if existGeneral {
|
|
generalContent, _ := 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
|
|
}
|