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
|
namespace :cccms do
desc "Bootstrap a fresh installation: the node skeleton and one admin " \
"account. Idempotent -- every step finds before it creates, so " \
"re-running after a new step is added is safe. " \
"Requires ADMIN_PASS. ADMIN_LOGIN and ADMIN_EMAIL are optional. " \
"The admin is created without the role and promoted with " \
"update_column, because admin_needs_second_factor refuses a NEW " \
"admin without an enrolled factor -- it exempts retention, not " \
"creation. The account therefore cannot do user management until " \
"it enrols a second factor and signs in again; see INSTALL.md."
task :init => :environment do
password = ENV["ADMIN_PASS"].to_s
abort "usage: ADMIN_PASS=secret bundle exec rake cccms:init" if password.empty?
abort "ADMIN_PASS must be at least 6 characters" if password.length < 6
login = ENV.fetch("ADMIN_LOGIN", "admin")
email = ENV.fetch("ADMIN_EMAIL", "admin@example.org")
# publish_draft! is called with no user, which guard_live_change! treats
# as a trusted system context -- the documented nil-user path, and the
# reason a rake task can publish into /updates and /disclosure at all.
ensure_node = lambda do |parent, slug, title, body|
existing = parent ? parent.children.find_by(:slug => slug) : Node.root
if existing
puts format(" %-14s exists (%d)", slug || "root", existing.id)
next existing
end
node = parent ? parent.children.create!(:slug => slug) : Node.create!
if parent.nil?
node.reload
node.update_column(:draft_id, node.pages.first.id) if node.draft_id.nil?
end
Globalize.with_locale(I18n.default_locale) do
node.draft.update!(:title => title, :body => body.to_s)
end
node.publish_draft! if parent
puts format(" %-14s created (%d)", slug || "root", node.id)
node
end
puts "Node skeleton:"
root = ensure_node.(nil, nil, "CCC", "")
# Referencing it is enough: Node.trash self-creates on first call.
puts format(" %-14s ready (%d)", "trash", Node.trash.id)
ensure_node.(root, "home", "Startseite", "")
ensure_node.(root, "updates", "Updates",
'[aggregate tags="update" limit="30" order_by="published_at" order_direction="DESC"]')
ensure_node.(root, "disclosure", "Disclosure", "")
club = ensure_node.(root, "club", "Chaos Computer Club", "")
ensure_node.(club, "erfas", "Erfa-Kreise",
'[aggregate children="direct" order_by="slug" partial="chapter"]')
ensure_node.(club, "chaostreffs", "Chaostreffs",
'[aggregate children="direct" order_by="slug" partial="chapter"]')
puts
if User.any?
puts "Accounts exist already; skipping admin creation."
else
user = User.create!(:login => login, :email => email,
:password => password,
:password_confirmation => password)
user.update_column(:roles, %w[admin redaktion])
puts "Created #{user.login} <#{user.email}> as admin + redaktion."
puts
puts "This account has no second factor, so it cannot yet create"
puts "users, reset factors or deactivate accounts. To finish:"
puts " 1. sign in as #{user.login}"
puts " 2. Mein Konto -> enable second factor, scan the QR, confirm"
puts " 3. sign out and sign in again, entering the code"
puts "Elevation is granted at that login and user management unlocks."
end
end
end
Rake::Task["db:schema:load"].enhance do
Page.ensure_search_vector_trigger!
end
|