/
account.rb
96 lines (77 loc) · 3.16 KB
/
account.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
module Spina
class Account < ApplicationRecord
include AttrJson::Record
include AttrJson::NestedAttributes
include Partable
include TranslatedContent
serialize :preferences, coder: Psych
after_save :bootstrap_website
validates :name, presence: true
def to_s
name
end
# Spina previously stored account preferences with symbols as keys.
# Because of CVE-2022-32224 we're changing that to strings instead.
# This fallback ensures backwards compatibility, but in the long run this
# should be refactored to use a simple JSONB-column with Postgres.
def self.serialized_attr_accessor(*args)
args.each do |method_name|
define_method method_name do
if preferences.try(:[], method_name.to_sym).present?
ActiveSupport::Deprecation.warn("#{method_name} is stored as a symbol. Please set and save it again using #{method_name}= on your Spina::Account model to store it as a string. You can do this from the UI by saving your account preferences.")
end
preferences.try(:[], method_name.to_s) ||
preferences.try(:[], method_name.to_sym)
end
define_method "#{method_name}=" do |value|
self.preferences ||= {}
self.preferences.except!(method_name.to_sym)
self.preferences[method_name.to_s] = value
end
end
end
serialized_attr_accessor :google_analytics, :google_site_verification, :facebook, :twitter, :instagram, :youtube, :linkedin, :google_plus, :theme
private
def bootstrap_website
theme_config = ::Spina::Theme.find_by_name(theme)
if theme_config
bootstrap_navigations(theme_config)
bootstrap_pages(theme_config)
bootstrap_resources(theme_config)
end
end
def bootstrap_navigations(theme)
theme.navigations.each_with_index do |navigation, index|
Navigation.where(name: navigation[:name]).first_or_create.update(navigation.merge(position: index))
end
end
def bootstrap_pages(theme)
find_or_create_custom_pages(theme)
deactivate_unused_view_templates(theme)
activate_used_view_templates(theme)
end
def bootstrap_resources(theme)
theme.resources.each do |resource|
Resource.where(name: resource[:name]).first_or_create.update(resource)
end
end
def find_or_create_custom_pages(theme)
theme.custom_pages.each do |page|
ancestry = nil
if page[:parent].present?
parent_page = Page.find_by(name: page[:parent])
ancestry = [parent_page&.ancestry, parent_page&.id].compact.join("/")
end
Page.where(name: page[:name])
.first_or_create(title: page[:title])
.update(view_template: page[:view_template], deletable: page[:deletable], ancestry: ancestry)
end
end
def deactivate_unused_view_templates(theme)
Page.active.where.not(view_template: theme.view_templates.map { |h| h[:name] }).update_all(active: false)
end
def activate_used_view_templates(theme)
Page.where(active: false, view_template: theme.view_templates.map { |h| h[:name] }).update_all(active: true)
end
end
end