/* * 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 }