discourse_dev 0.0.7 → 0.2.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (36) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +2 -0
  3. data/README.md +40 -4
  4. data/auth/app/views/fake_discourse_connect/form.html.erb +120 -0
  5. data/auth/plugin.rb +219 -0
  6. data/avatars/03F55412-DE8A-4F83-AAA6-D67EE5CE48DA-200w.jpeg +0 -0
  7. data/avatars/1C4EEDC2-FE9C-40B3-A2C9-A038873EE692-200w.jpeg +0 -0
  8. data/avatars/26CFEFB3-21C8-49FC-8C19-8E6A62B6D2E0-200w.jpeg +0 -0
  9. data/avatars/282A12CA-E0D7-4011-8BDD-1FAFAAB035F7-200w.jpeg +0 -0
  10. data/avatars/2DDDE973-40EC-4004-ABC0-73FD4CD6D042-200w.jpeg +0 -0
  11. data/avatars/344CFC24-61FB-426C-B3D1-CAD5BCBD3209-200w.jpeg +0 -0
  12. data/avatars/852EC6E1-347C-4187-9D42-DF264CCF17BF-200w.jpeg +0 -0
  13. data/avatars/A7299C8E-CEFC-47D9-939A-3C8CA0EA4D13-200w.jpeg +0 -0
  14. data/avatars/AEF44435-B547-4B84-A2AE-887DFAEE6DDF-200w.jpeg +0 -0
  15. data/avatars/B3CF5288-34B0-4A5E-9877-5965522529D6-200w.jpeg +0 -0
  16. data/avatars/BA0CB1F2-8C79-4376-B13B-DD5FB8772537-200w.jpeg +0 -0
  17. data/avatars/E0B4CAB3-F491-4322-BEF2-208B46748D4A-200w.jpeg +0 -0
  18. data/avatars/FBEBF655-4886-455A-A4A4-D62B77DD419B-200w.jpeg +0 -0
  19. data/config/dev.yml +38 -0
  20. data/config/locales/client.en.yml +6 -0
  21. data/{lib/faker/locales/en.yml → config/locales/faker.en.yml} +0 -0
  22. data/discourse_dev.gemspec +1 -0
  23. data/lib/discourse_dev.rb +49 -4
  24. data/lib/discourse_dev/category.rb +3 -3
  25. data/lib/discourse_dev/config.rb +101 -29
  26. data/lib/discourse_dev/group.rb +4 -5
  27. data/lib/discourse_dev/post.rb +35 -16
  28. data/lib/discourse_dev/record.rb +13 -11
  29. data/lib/discourse_dev/tag.rb +14 -2
  30. data/lib/discourse_dev/tasks/dev.rake +6 -2
  31. data/lib/discourse_dev/topic.rb +48 -11
  32. data/lib/discourse_dev/user.rb +58 -7
  33. data/lib/discourse_dev/version.rb +1 -1
  34. data/lib/faker/discourse_markdown.rb +96 -0
  35. metadata +36 -4
  36. data/lib/discourse_dev/config.yml +0 -4
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e7cf21a4b27818d1c6c02ce68b6f3fec67fec0b5c7ce070203c4db6bec1e1e72
4
- data.tar.gz: 7bcd79d041f43cf6ed4843c2a3fe9f20bba915682516586064a0356acb5246df
3
+ metadata.gz: b05da63d2ddcf5a7a100cfb9ab95e241a1273aa44f0eb8f0c0ea616793814470
4
+ data.tar.gz: d32bc205ef1072ee5d163cfe9626ffe7592a336286ecc9cd5fbe13f146a85f2b
5
5
  SHA512:
6
- metadata.gz: f964c9b509c0e219aff2161e49fc7d468861fefc85e6ce0a68250fbdfd2ca6d06d32ee7bf0b153ae99eb1dc9be0a1c4694752ec60ee7b0c71143d0283ebd5c15
7
- data.tar.gz: 207d473198144df8997a72eb9ab6f9070b24b924c6600be546d6bef2aeb26076c633b781caba9fb69590a2c99807004b0c19a49026f588d2cc7ae0470fa391b5
6
+ metadata.gz: 61a3aaa9e1cfa08499428e2369b456a466f3c51a7ea722917a3365a9a226f7067073ae6883ee1bd5e618f0f31a63f6e0cb4e74a04ab8478c3fb00f1c51ef7fde
7
+ data.tar.gz: 490c9ad8617b46d09d62b1772c829aa86cda11a5d898be73df6a4671e599c0eeba19f907e653db95f8f8f6d549cc90fd57b68f81dcfac5c5413461cb05dc60cc
data/.rubocop.yml ADDED
@@ -0,0 +1,2 @@
1
+ inherit_gem:
2
+ rubocop-discourse: default.yml
data/README.md CHANGED
@@ -2,14 +2,50 @@
2
2
 
3
3
  ![Gem](https://img.shields.io/gem/v/discourse_dev)
4
4
 
5
- Rake helper tasks for Discourse developers.
5
+ Rake helper tasks for Discourse developers. These tasks can be used to populate random data like topics, groups, users, categories, and tags in your local `discourse_development` database.
6
6
 
7
7
  ## Available Rake Tasks
8
8
 
9
- * `dev:reset`
10
- * `dev:config`
11
- * `dev:populate`
9
+ #### `dev:reset`
10
+
11
+ * db:migrate:reset
12
+ * db:drop
13
+ * db:create
14
+ * db:migrate
15
+ * dev:config
16
+ * admin:create
17
+ * dev:populate
18
+ * groups:populate
19
+ * users:populate
20
+ * categories:populate
21
+ * topics:populate
22
+ * tags:populate
23
+
24
+ The `rake dev:reset` command will just invoke other rake tasks in the above order. So it will completely recreate your development environment.
25
+
26
+ #### `dev:config`
27
+
28
+ Reloads the site settings from the dev.yml file.
29
+
30
+ #### `dev:populate`
31
+
32
+ Runs all of the sub-populate tasks.
33
+
34
+ #### `*:populate`
35
+
36
+ Populates the specified groups of records based on settings in dev.yml.
37
+
12
38
  * `groups:populate`
13
39
  * `users:populate`
14
40
  * `categories:populate`
41
+ * `tags:populate`
15
42
  * `topics:populate`
43
+ * `replies:populate`
44
+
45
+ ## Configuration
46
+
47
+ In your local Discourse repository, this gem is included as a dependency. When you run the gem for the first time it will look for a `config/dev.yml` file and if it does not find one it will generate one from the default included with the gem. Here you can specify site settings which will override default site setting values, as well as configuration for how the local data is generated with this gem.
48
+
49
+ For category, group, post, tag, topic, and user you can specify the `count`, which is the maximum number of records that will be generated by the associated task.
50
+
51
+ For more in-depth information about configuration, consul the comments in the default `dev.yml` in the source code.
@@ -0,0 +1,120 @@
1
+ <%# Layout/CSS borrowed from Omniauth's Form system %>
2
+ <!DOCTYPE html>
3
+ <html>
4
+ <head>
5
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
6
+ <title>Fake DiscourseConnect Provider</title>
7
+ <style type='text/css'>
8
+ body {
9
+ background: #ccc;
10
+ font-family: "Lucida Grande", "Lucida Sans", Helvetica, Arial, sans-serif;
11
+ }
12
+
13
+ h1 {
14
+ text-align: center;
15
+ margin: 30px auto 0px;
16
+ font-size: 18px;
17
+ padding: 10px 10px 15px;
18
+ background: #555;
19
+ color: white;
20
+ width: 320px;
21
+ border: 10px solid #444;
22
+ border-bottom: 0;
23
+ -moz-border-radius-topleft: 10px;
24
+ -moz-border-radius-topright: 10px;
25
+ -webkit-border-top-left-radius: 10px;
26
+ -webkit-border-top-right-radius: 10px;
27
+ border-top-left-radius: 10px;
28
+ border-top-right-radius: 10px;
29
+ }
30
+
31
+ h1,
32
+ form {
33
+ -moz-box-shadow: 2px 2px 7px rgba(0, 0, 0, 0.3);
34
+ -webkit-box-shadow: 2px 2px 7px rgba(0, 0, 0, 0.3);
35
+ }
36
+
37
+ form {
38
+ background: white;
39
+ border: 10px solid #eee;
40
+ border-top: 0;
41
+ padding: 20px;
42
+ margin: 0px auto 40px;
43
+ width: 300px;
44
+ -moz-border-radius-bottomleft: 10px;
45
+ -moz-border-radius-bottomright: 10px;
46
+ -webkit-border-bottom-left-radius: 10px;
47
+ -webkit-border-bottom-right-radius: 10px;
48
+ border-bottom-left-radius: 10px;
49
+ border-bottom-right-radius: 10px;
50
+ }
51
+
52
+ label {
53
+ display: block;
54
+ font-weight: bold;
55
+ margin-bottom: 5px;
56
+ }
57
+
58
+ input, select {
59
+ font-size: 18px;
60
+ padding: 4px 8px;
61
+ display: block;
62
+ margin-bottom: 10px;
63
+ width: 280px;
64
+ }
65
+
66
+ select {
67
+ width: calc(280px + 20px);
68
+ }
69
+
70
+ button {
71
+ font-size: 22px;
72
+ padding: 4px 8px;
73
+ display: block;
74
+ margin: 20px auto 0;
75
+ }
76
+
77
+ fieldset {
78
+ border: 1px solid #ccc;
79
+ border-left: 0;
80
+ border-right: 0;
81
+ padding: 10px 0;
82
+ }
83
+
84
+ fieldset input {
85
+ width: 260px;
86
+ font-size: 16px;
87
+ }
88
+
89
+ details summary {
90
+ cursor: pointer;
91
+ margin-bottom: 10px;
92
+ }
93
+ </style>
94
+ </head>
95
+ <body>
96
+ <h1>Fake DiscourseConnect Provider</h1>
97
+ <form method='post' noValidate='noValidate'>
98
+ <input type='hidden' name='sso_payload' value='<%= @payload %>'/>
99
+ <% @simple_fields.each do |f| %>
100
+ <label for='<%= f %>'><%= f %>:</label><input type='text' id='<%= f %>' name='<%= f %>' value='<%= @defaults[f] %>'/>
101
+ <% end %>
102
+ <details>
103
+ <summary>Advanced</summary>
104
+ <% @advanced_fields.each do |f| %>
105
+ <% if @bools.include? f %>
106
+ <label for='<%= f %>'><%= f %>:</label>
107
+ <select name="<%= f %>" id="<%= f %>">
108
+ <% ["", "true", "false"].each do |opt| %>
109
+ <option <%= "selected" if @defaults[f] == opt %> value="<%= opt %>"><%= opt %></option>
110
+ <% end %>
111
+ </select>
112
+ <% else %>
113
+ <label for='<%= f %>'><%= f %>:</label><input type='text' id='<%= f %>' name='<%= f %>' value='<%= @defaults[f] %>'/>
114
+ <% end %>
115
+ <% end %>
116
+ </details>
117
+ <button type='submit'>Go</button>
118
+ </form>
119
+ </body>
120
+ </html>
data/auth/plugin.rb ADDED
@@ -0,0 +1,219 @@
1
+ # frozen_string_literal: true
2
+
3
+ # name: discourse-development-auth
4
+ # about: A fake authentication provider for development puposes only
5
+ # version: 1.0
6
+ # authors: David Taylor
7
+ # url: https://github.com/discourse/discourse-development-auth
8
+
9
+ raise "discourse-development-auth is highly insecure and should not be installed in production" if Rails.env.production?
10
+
11
+ PLUGIN_NAME = "discourse-development-auth"
12
+
13
+ module ::OmniAuth
14
+ module Strategies
15
+ class Development
16
+ include ::OmniAuth::Strategy
17
+
18
+ FIELDS = %w{
19
+ uid
20
+ name
21
+ email
22
+ email_verified
23
+ nickname
24
+ first_name
25
+ last_name
26
+ location
27
+ description
28
+ image
29
+ }
30
+
31
+ COOKIE = "development-auth-defaults"
32
+
33
+ def request_phase
34
+ return unless is_allowed?
35
+ if (env['REQUEST_METHOD'] == 'POST') && (request.params['uid'])
36
+ data = request.params.slice(*FIELDS)
37
+
38
+ r = Rack::Response.new
39
+ r.set_cookie(COOKIE, { value: data.to_json, path: "/", expires: 1.month.from_now })
40
+
41
+ uri = URI.parse(callback_path)
42
+ uri.query = URI.encode_www_form(data)
43
+ r.redirect(uri)
44
+
45
+ return r.finish
46
+ end
47
+
48
+ build_form.to_response
49
+ end
50
+
51
+ def build_form
52
+ token = begin
53
+ verifier = CSRFTokenVerifier.new
54
+ verifier.call(env)
55
+ verifier.form_authenticity_token
56
+ end
57
+
58
+ request = Rack::Request.new(env)
59
+ raw_defaults = request.cookies[COOKIE] || "{}"
60
+ defaults = JSON.parse(raw_defaults) rescue {}
61
+ defaults["uid"] = SecureRandom.hex(8) unless defaults["uid"].present?
62
+ defaults["email_verified"] = "true" unless defaults["email_verified"].present?
63
+
64
+ OmniAuth::Form.build(title: "Fake Authentication Provider") do
65
+ html "\n<input type='hidden' name='authenticity_token' value='#{token}'/>"
66
+
67
+ FIELDS.each do |f|
68
+ label_field(f, f)
69
+ if f == "email_verified"
70
+ html "<input type='checkbox' id='#{f}' name='#{f}' value='true' #{"checked" if defaults[f] == "true"}/>"
71
+ else
72
+ html "<input type='text' id='#{f}' name='#{f}' value='#{defaults[f]}'/>"
73
+ end
74
+ end
75
+ end
76
+ end
77
+
78
+ def callback_phase
79
+ return unless is_allowed?
80
+ super
81
+ end
82
+
83
+ def auth_hash
84
+ info = request.params.slice(*FIELDS)
85
+ uid = info.delete("uid")
86
+ email_verified = (info.delete("email_verified") == "true")
87
+ OmniAuth::Utils.deep_merge(super, {
88
+ 'uid' => uid,
89
+ 'info' => info,
90
+ 'extra' => { "raw_info" => { "email_verified" => email_verified } }
91
+ })
92
+ end
93
+
94
+ def is_allowed?
95
+ return true if DiscourseDev.config.allow_anonymous_to_impersonate
96
+ fail!("Enable `allow_anonymous_to_impersonate` setting in `config/dev.yml` file.")
97
+ false
98
+ end
99
+ end
100
+ end
101
+ end
102
+
103
+ class DevelopmentAuthenticator < Auth::ManagedAuthenticator
104
+ def name
105
+ 'developmentauth'
106
+ end
107
+
108
+ def can_revoke?
109
+ true
110
+ end
111
+
112
+ def can_connect_existing_user?
113
+ true
114
+ end
115
+
116
+ def enabled?
117
+ DiscourseDev.auth_plugin_enabled?
118
+ end
119
+
120
+ def register_middleware(omniauth)
121
+ omniauth.provider :development, name: :developmentauth
122
+ end
123
+
124
+ def primary_email_verified?(auth)
125
+ auth['extra']['raw_info']['email_verified']
126
+ end
127
+ end
128
+
129
+ auth_provider authenticator: DevelopmentAuthenticator.new
130
+
131
+ ### DiscourseConnect
132
+ after_initialize do
133
+ module ::DevelopmentAuth
134
+ class Engine < ::Rails::Engine
135
+ engine_name PLUGIN_NAME
136
+ isolate_namespace ::DevelopmentAuth
137
+ end
138
+ end
139
+
140
+ class ::DevelopmentAuth::FakeDiscourseConnectController < ::ApplicationController
141
+ requires_plugin "discourse-development-auth"
142
+
143
+ skip_before_action :check_xhr, :preload_json, :redirect_to_login_if_required, :verify_authenticity_token
144
+
145
+ SIMPLE_FIELDS = %w{
146
+ external_id
147
+ email
148
+ username
149
+ name
150
+ }
151
+ ADVANCED_FIELDS = SingleSignOn::ACCESSORS.map(&:to_s) - SIMPLE_FIELDS
152
+ FIELDS = SIMPLE_FIELDS + ADVANCED_FIELDS
153
+
154
+ BOOLS = SingleSignOn::BOOLS.map(&:to_s)
155
+
156
+ COOKIE = "development-auth-discourseconnect-defaults"
157
+
158
+ def auth
159
+ return unless is_allowed?
160
+
161
+ params.require(:sso)
162
+ @payload = request.query_string
163
+ sso = SingleSignOn.parse(@payload, SiteSetting.discourse_connect_secret)
164
+
165
+ if request.method == "POST" && params[:external_id]
166
+ data = {}
167
+ FIELDS.each do |f|
168
+ sso.send(:"#{f}=", params[f])
169
+ data[f] = params[f]
170
+ cookies[COOKIE] = { value: data.to_json, path: "/", expires: 1.month.from_now }
171
+ end
172
+
173
+ return redirect_to sso.to_url(sso.return_sso_url)
174
+ end
175
+
176
+ raw_defaults = cookies[COOKIE] || "{}"
177
+ @defaults = JSON.parse(raw_defaults) rescue {}
178
+ @defaults["return_sso_url"] = sso.return_sso_url
179
+ @defaults["nonce"] = sso.nonce
180
+ @defaults["external_id"] = SecureRandom.hex(8) unless @defaults["external_id"].present?
181
+ render_form
182
+ end
183
+
184
+ private
185
+
186
+ def render_form
187
+ @simple_fields = SIMPLE_FIELDS
188
+ @advanced_fields = ADVANCED_FIELDS
189
+ @bools = BOOLS
190
+ append_view_path(File.expand_path("../app/views", __FILE__))
191
+ render template: "fake_discourse_connect/form", layout: false
192
+ end
193
+ end
194
+
195
+ DevelopmentAuth::Engine.routes.draw do
196
+ get "/fake-discourse-connect" => "fake_discourse_connect#auth"
197
+ post "/fake-discourse-connect" => "fake_discourse_connect#auth"
198
+ end
199
+
200
+ Discourse::Application.routes.append do
201
+ mount ::DevelopmentAuth::Engine, at: "/development-auth"
202
+ end
203
+
204
+ DiscourseSingleSignOn.singleton_class.prepend(Module.new do
205
+ def sso_url
206
+ if DiscourseDev.auth_plugin_enabled?
207
+ return "#{Discourse.base_path}/development-auth/fake-discourse-connect"
208
+ end
209
+ super
210
+ end
211
+ end)
212
+
213
+ EnableSsoValidator.prepend(Module.new do
214
+ def valid_value?(val)
215
+ return true if DiscourseDev.auth_plugin_enabled?
216
+ super
217
+ end
218
+ end)
219
+ end
data/config/dev.yml ADDED
@@ -0,0 +1,38 @@
1
+ site_settings:
2
+ tagging_enabled: true
3
+ verbose_discourse_connect_logging: true
4
+
5
+ seed: 1
6
+ start_date: 2020-01-01
7
+ auth_plugin_enabled: true
8
+ allow_anonymous_to_impersonate: false
9
+
10
+ category:
11
+ count: 30
12
+ group:
13
+ count: 15
14
+ post:
15
+ include_images: false
16
+ max_likes_count: 10
17
+ tag:
18
+ count: 30
19
+ topic:
20
+ count: 30
21
+ replies:
22
+ # number of replies per topic between min and max
23
+ min: 0
24
+ max: 12
25
+ overrides:
26
+ # topic titles can be found in config/locales/faker.en.yml
27
+ - title: "Coolest thing you have seen today"
28
+ count: 99
29
+ tags:
30
+ # number of tags per topic between min and max
31
+ min: 0
32
+ max: 3
33
+ user:
34
+ count: 30
35
+
36
+ new_user:
37
+ username: new_user
38
+ email: new_user@example.com