summaryrefslogtreecommitdiff
path: root/lib/tasks/init.rake
diff options
context:
space:
mode:
Diffstat (limited to 'lib/tasks/init.rake')
-rw-r--r--lib/tasks/init.rake75
1 files changed, 75 insertions, 0 deletions
diff --git a/lib/tasks/init.rake b/lib/tasks/init.rake
new file mode 100644
index 00000000..7e3d8dcc
--- /dev/null
+++ b/lib/tasks/init.rake
@@ -0,0 +1,75 @@
1namespace :cccms do
2 desc "Bootstrap a fresh installation: the node skeleton and one admin " \
3 "account. Idempotent -- every step finds before it creates, so " \
4 "re-running after a new step is added is safe. " \
5 "Requires ADMIN_PASS. ADMIN_LOGIN and ADMIN_EMAIL are optional. " \
6 "The admin is created without the role and promoted with " \
7 "update_column, because admin_needs_second_factor refuses a NEW " \
8 "admin without an enrolled factor -- it exempts retention, not " \
9 "creation. The account therefore cannot do user management until " \
10 "it enrols a second factor and signs in again; see INSTALL.md."
11 task :init => :environment do
12 password = ENV["ADMIN_PASS"].to_s
13 abort "usage: ADMIN_PASS=secret bundle exec rake cccms:init" if password.empty?
14 abort "ADMIN_PASS must be at least 6 characters" if password.length < 6
15
16 login = ENV.fetch("ADMIN_LOGIN", "admin")
17 email = ENV.fetch("ADMIN_EMAIL", "admin@example.org")
18
19 # publish_draft! is called with no user, which guard_live_change! treats
20 # as a trusted system context -- the documented nil-user path, and the
21 # reason a rake task can publish into /updates and /disclosure at all.
22 ensure_node = lambda do |parent, slug, title, body|
23 existing = parent ? parent.children.find_by(:slug => slug) : Node.root
24 if existing
25 puts format(" %-14s exists (%d)", slug || "root", existing.id)
26 next existing
27 end
28
29 node = parent ? parent.children.create!(:slug => slug) : Node.create!
30 Globalize.with_locale(I18n.default_locale) do
31 node.draft.update!(:title => title, :body => body.to_s)
32 end
33 node.publish_draft!
34 puts format(" %-14s created (%d)", slug || "root", node.id)
35 node
36 end
37
38 puts "Node skeleton:"
39 root = ensure_node.(nil, nil, "CCC", "")
40
41 # Referencing it is enough: Node.trash self-creates on first call.
42 puts format(" %-14s ready (%d)", "trash", Node.trash.id)
43
44 ensure_node.(root, "home", "Startseite", "")
45
46 ensure_node.(root, "updates", "Updates",
47 '[aggregate tags="update" limit="30" order_by="published_at" order_direction="DESC"]')
48
49 ensure_node.(root, "disclosure", "Disclosure", "")
50
51 club = ensure_node.(root, "club", "Chaos Computer Club", "")
52 ensure_node.(club, "erfas", "Erfa-Kreise",
53 '[aggregate children="direct" order_by="slug" partial="chapter"]')
54 ensure_node.(club, "chaostreffs", "Chaostreffs",
55 '[aggregate children="direct" order_by="slug" partial="chapter"]')
56
57 puts
58 if User.any?
59 puts "Accounts exist already; skipping admin creation."
60 else
61 user = User.create!(:login => login, :email => email,
62 :password => password,
63 :password_confirmation => password)
64 user.update_column(:roles, %w[admin redaktion])
65 puts "Created #{user.login} <#{user.email}> as admin + redaktion."
66 puts
67 puts "This account has no second factor, so it cannot yet create"
68 puts "users, reset factors or deactivate accounts. To finish:"
69 puts " 1. sign in as #{user.login}"
70 puts " 2. Mein Konto -> enable second factor, scan the QR, confirm"
71 puts " 3. sign out and sign in again, entering the code"
72 puts "Elevation is granted at that login and user management unlocks."
73 end
74 end
75end