yiffspace 0.0.25 → 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +11 -0
- data/lib/yiffspace/configuration.rb +0 -25
- data/lib/yiffspace/{railtie.rb → engine.rb} +9 -7
- data/lib/yiffspace/extensions/active_record/where_chain.rb +5 -5
- data/lib/yiffspace/extensions/arel/visitors/postgresql/cross_join_lateral.rb +1 -1
- data/lib/yiffspace/extensions/arel/visitors/postgresql/left_join_lateral.rb +1 -1
- data/lib/yiffspace/version.rb +1 -1
- data/lib/yiffspace.rb +5 -6
- metadata +2 -49
- data/app/helpers/yiff_space/auth_helper.rb +0 -6
- data/engines/auth/app/controllers/yiff_space/auth/application_controller.rb +0 -11
- data/engines/auth/app/controllers/yiff_space/auth/root_controller.rb +0 -49
- data/engines/auth/app/controllers/yiff_space/auth/webhook_controller.rb +0 -73
- data/engines/auth/app/views/yiff_space/auth/root/permissions.html.erb +0 -14
- data/engines/auth/config/routes.rb +0 -12
- data/lib/tasks/yiffspace_tasks.rake +0 -41
- data/lib/yiffspace/auth/api_user.rb +0 -43
- data/lib/yiffspace/auth/auth_info/anonymous.rb +0 -60
- data/lib/yiffspace/auth/auth_info.rb +0 -78
- data/lib/yiffspace/auth/client.rb +0 -56
- data/lib/yiffspace/auth/discord_info.rb +0 -65
- data/lib/yiffspace/auth/engine.rb +0 -58
- data/lib/yiffspace/auth/helper.rb +0 -174
- data/lib/yiffspace/auth/permissions.rb +0 -87
- data/lib/yiffspace/auth/set_client_name.rb +0 -15
- data/lib/yiffspace/auth/user_info/anonymous.rb +0 -72
- data/lib/yiffspace/auth/user_info.rb +0 -87
- data/lib/yiffspace/auth.rb +0 -44
- data/lib/yiffspace/core_ext/action_dispatch/set_auth_client/scoped.rb +0 -13
- data/lib/yiffspace/core_ext/action_dispatch/set_auth_client.rb +0 -13
- data/lib/yiffspace/core_ext/logto/named_session_storage.rb +0 -7
- data/lib/yiffspace/extensions/action_dispatch/set_auth_client/scoped.rb +0 -15
- data/lib/yiffspace/extensions/action_dispatch/set_auth_client.rb +0 -13
- data/lib/yiffspace/extensions/logto/named_session_storage.rb +0 -22
- data/lib/yiffspace/logto_management_client.rb +0 -136
- data/lib/yiffspace/serializers/anonymous_auth_info_serializer.rb +0 -23
- data/lib/yiffspace/serializers/anonymous_user_info_serializer.rb +0 -23
- data/lib/yiffspace/serializers/auth_info_serializer.rb +0 -23
- data/lib/yiffspace/serializers/discord_info_serializer.rb +0 -23
- data/lib/yiffspace/serializers/permissions_serializer.rb +0 -23
- data/lib/yiffspace/serializers/user_info_serializer.rb +0 -23
- data/lib/yiffspace/utils/user_deduper.rb +0 -66
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 2c5a6f91681f3b27a8a9ae4c3846ce05893cfcfab2ff26387be86ae036a36c3c
|
|
4
|
+
data.tar.gz: 1e2897c5ce9d77e00f914e2e2feb968022f0d7c6e8cc08cc779741c2d3f02065
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 64e931b055288ffd30590af4aa1668684647d915da22c9d9d33cb1f58fabdd452887a7dc96761dfdea8a544334a68966a67821f4a2a7e3726978d2a46ab73695
|
|
7
|
+
data.tar.gz: 1715c43fef12acee13bf66a35db09886caff6ef1c77f23690588b04707fcc2649f1d0adc07288bd2c88c72587e61f9102320f42bc18315bf8e0e87e39937ca8d
|
data/CHANGELOG.md
CHANGED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
## 0.1.0
|
|
2
|
+
|
|
3
|
+
- **Breaking:** extracted the Logto auth engine (`YiffSpace::Auth::*`) into a
|
|
4
|
+
separate gem, [`yiffspace-auth`](https://github.com/YiffSpace/Auth.rb). Apps
|
|
5
|
+
using auth need to add that gem alongside `yiffspace`.
|
|
6
|
+
- `YiffSpace::Configuration#auth`/`#add_auth`/`#add_default_auth` and the
|
|
7
|
+
`logto_api_*`/`discord_bot_token` settings moved to `yiffspace-auth`.
|
|
8
|
+
- Replaced the dead `YiffSpace::Railtie` with a real `YiffSpace::Engine <
|
|
9
|
+
Rails::Engine`, so the shared `app/` directory (ApplicationController,
|
|
10
|
+
layout, error view, CSS, ActiveJob serializers) actually loads into host
|
|
11
|
+
apps again.
|
|
@@ -31,12 +31,6 @@ module YiffSpace
|
|
|
31
31
|
# The `last_ip_addr` attribute of the User model, used by the UserResolvableMethods concern
|
|
32
32
|
attr_accessor(:last_ip_addr_attribute)
|
|
33
33
|
|
|
34
|
-
# Logto Management API credentials (shared across all auth clients).
|
|
35
|
-
attr_accessor(:logto_api_client_id, :logto_api_client_secret, :logto_api_resource)
|
|
36
|
-
|
|
37
|
-
# Discord bot token used to look up Discord users (shared across all auth clients).
|
|
38
|
-
attr_accessor(:discord_bot_token)
|
|
39
|
-
|
|
40
34
|
# The anonymous user's name, can be a proc
|
|
41
35
|
attr_reader(:anonymous_user_name)
|
|
42
36
|
|
|
@@ -58,10 +52,6 @@ module YiffSpace
|
|
|
58
52
|
@default_ip_address = "127.0.0.1"
|
|
59
53
|
@last_ip_addr_attribute = :last_ip_addr
|
|
60
54
|
@anonymous_user_name = -> { "Anonymous" }
|
|
61
|
-
@logto_api_client_id = nil
|
|
62
|
-
@logto_api_client_secret = nil
|
|
63
|
-
@logto_api_resource = nil
|
|
64
|
-
@discord_bot_token = nil
|
|
65
55
|
end
|
|
66
56
|
|
|
67
57
|
def user_class
|
|
@@ -103,21 +93,6 @@ module YiffSpace
|
|
|
103
93
|
@anonymous_user_name = value.is_a?(Proc) ? value : -> { value }
|
|
104
94
|
end
|
|
105
95
|
|
|
106
|
-
def auth(&block)
|
|
107
|
-
client = YiffSpace::Auth.register(Auth::DEFAULT_CLIENT_NAME) unless YiffSpace::Auth.instance_variable_get(:@clients).key?(Auth::DEFAULT_CLIENT_NAME)
|
|
108
|
-
client ||= YiffSpace::Auth[Auth::DEFAULT_CLIENT_NAME]
|
|
109
|
-
block&.call(client)
|
|
110
|
-
client
|
|
111
|
-
end
|
|
112
|
-
|
|
113
|
-
def add_auth(name, &)
|
|
114
|
-
YiffSpace::Auth.register(name, &)
|
|
115
|
-
end
|
|
116
|
-
|
|
117
|
-
def add_default_auth(&)
|
|
118
|
-
add_auth(Auth::DEFAULT_CLIENT_NAME, &)
|
|
119
|
-
end
|
|
120
|
-
|
|
121
96
|
def images
|
|
122
97
|
@images ||= Images.new
|
|
123
98
|
end
|
|
@@ -1,18 +1,20 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
+
require("rails")
|
|
4
|
+
|
|
3
5
|
module YiffSpace
|
|
4
|
-
class
|
|
6
|
+
class Engine < ::Rails::Engine
|
|
7
|
+
config.root = File.expand_path("../..", __dir__)
|
|
8
|
+
|
|
9
|
+
initializer("yiffspace.assets") do |app|
|
|
10
|
+
app.config.assets.precompile += %w[yiffspace/application.css] if app.config.respond_to?(:assets)
|
|
11
|
+
end
|
|
12
|
+
|
|
5
13
|
initializer("yiffspace.serializers") do
|
|
6
14
|
ActiveSupport.on_load(:active_job) do
|
|
7
15
|
ActiveJob::Serializers.add_serializers(
|
|
8
|
-
Serializers::AnonymousAuthInfoSerializer,
|
|
9
|
-
Serializers::AnonymousUserInfoSerializer,
|
|
10
|
-
Serializers::AuthInfoSerializer,
|
|
11
16
|
Serializers::AvatarSerializer,
|
|
12
17
|
Serializers::BannerSerializer,
|
|
13
|
-
Serializers::DiscordInfoSerializer,
|
|
14
|
-
Serializers::PermissionsSerializer,
|
|
15
|
-
Serializers::UserInfoSerializer,
|
|
16
18
|
Serializers::UserResolvableSerializer,
|
|
17
19
|
)
|
|
18
20
|
end
|
|
@@ -23,17 +23,17 @@ module YiffSpace
|
|
|
23
23
|
# https://www.postgresql.org/docs/current/static/functions-matching.html#FUNCTIONS-POSIX-REGEXP
|
|
24
24
|
# "(?e)" means force use of ERE syntax; see sections 9.7.3.1 and 9.7.3.4.
|
|
25
25
|
def regex(conditions = {}, flags: "e", **kwargs)
|
|
26
|
-
conditions.merge!(kwargs) if conditions.is_a?(Hash)
|
|
26
|
+
conditions.merge!(kwargs) if conditions.is_a?(::Hash)
|
|
27
27
|
build(conditions, :regex, flags)
|
|
28
28
|
end
|
|
29
29
|
|
|
30
30
|
def not_regex(conditions = {}, flags: "e", **kwargs)
|
|
31
|
-
conditions.merge!(kwargs) if conditions.is_a?(Hash)
|
|
31
|
+
conditions.merge!(kwargs) if conditions.is_a?(::Hash)
|
|
32
32
|
build(conditions, :not_regex, flags)
|
|
33
33
|
end
|
|
34
34
|
|
|
35
35
|
def tsquery(conditions = {}, ts_config: "english", **kwargs)
|
|
36
|
-
conditions.merge!(kwargs) if conditions.is_a?(Hash)
|
|
36
|
+
conditions.merge!(kwargs) if conditions.is_a?(::Hash)
|
|
37
37
|
build(conditions, :tsquery, ts_config)
|
|
38
38
|
end
|
|
39
39
|
|
|
@@ -84,9 +84,9 @@ module YiffSpace
|
|
|
84
84
|
|
|
85
85
|
conditions.each do |key, value|
|
|
86
86
|
case key
|
|
87
|
-
when String, Symbol
|
|
87
|
+
when ::String, ::Symbol
|
|
88
88
|
key = key.to_s
|
|
89
|
-
if value.is_a?(Hash)
|
|
89
|
+
if value.is_a?(::Hash)
|
|
90
90
|
pairs.concat(normalize_conditions(value, model, key))
|
|
91
91
|
elsif key.include?(".")
|
|
92
92
|
table, col = key.split(".", 2)
|
|
@@ -7,7 +7,7 @@ module YiffSpace
|
|
|
7
7
|
module PostgreSQL
|
|
8
8
|
module CrossJoinLateral
|
|
9
9
|
# noinspection RubyInstanceMethodNamingConvention
|
|
10
|
-
def
|
|
10
|
+
def visit_YiffSpace_Extensions_Arel_Nodes_CrossJoinLateral(o, collector)
|
|
11
11
|
collector << "CROSS JOIN LATERAL "
|
|
12
12
|
visit(o.left, collector)
|
|
13
13
|
end
|
|
@@ -7,7 +7,7 @@ module YiffSpace
|
|
|
7
7
|
module PostgreSQL
|
|
8
8
|
module LeftJoinLateral
|
|
9
9
|
# noinspection RubyInstanceMethodNamingConvention
|
|
10
|
-
def
|
|
10
|
+
def visit_YiffSpace_Extensions_Arel_Nodes_LeftJoinLateral(o, collector)
|
|
11
11
|
collector << "LEFT JOIN LATERAL "
|
|
12
12
|
visit(o.left, collector)
|
|
13
13
|
return unless o.right
|
data/lib/yiffspace/version.rb
CHANGED
data/lib/yiffspace.rb
CHANGED
|
@@ -20,12 +20,11 @@ loader = Zeitwerk::Loader.for_gem
|
|
|
20
20
|
loader.inflector.inflect({ "postgresql" => "PostgreSQL", "yiffspace" => "YiffSpace", "query_dsl" => "QueryDSL" })
|
|
21
21
|
loader.ignore("#{__dir__}/yiffspace/core_ext")
|
|
22
22
|
loader.ignore("#{__dir__}/yiffspace/include")
|
|
23
|
-
loader.ignore("#{__dir__}/yiffspace/
|
|
24
|
-
loader.ignore("#{__dir__}/yiffspace/auth/engine.rb")
|
|
23
|
+
loader.ignore("#{__dir__}/yiffspace/engine.rb")
|
|
25
24
|
loader.setup
|
|
26
25
|
|
|
27
|
-
# Require the
|
|
26
|
+
# Require the engine eagerly so it registers with Rails before the host app's
|
|
28
27
|
# active_support.initialize_per_engine_zeitwerk_loaders initializer runs. Without this,
|
|
29
|
-
# the engine is only loaded
|
|
30
|
-
#
|
|
31
|
-
require_relative("yiffspace/
|
|
28
|
+
# the engine is only loaded lazily (after Zeitwerk setup) and its app/controllers
|
|
29
|
+
# path is never added to the app's autoload roots.
|
|
30
|
+
require_relative("yiffspace/engine") if defined?(Rails)
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: yiffspace
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.1.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Donovan_DMC
|
|
@@ -37,20 +37,6 @@ dependencies:
|
|
|
37
37
|
- - ">="
|
|
38
38
|
- !ruby/object:Gem::Version
|
|
39
39
|
version: '0.24'
|
|
40
|
-
- !ruby/object:Gem::Dependency
|
|
41
|
-
name: logto
|
|
42
|
-
requirement: !ruby/object:Gem::Requirement
|
|
43
|
-
requirements:
|
|
44
|
-
- - ">="
|
|
45
|
-
- !ruby/object:Gem::Version
|
|
46
|
-
version: 0.2.0
|
|
47
|
-
type: :runtime
|
|
48
|
-
prerelease: false
|
|
49
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
50
|
-
requirements:
|
|
51
|
-
- - ">="
|
|
52
|
-
- !ruby/object:Gem::Version
|
|
53
|
-
version: 0.2.0
|
|
54
40
|
- !ruby/object:Gem::Dependency
|
|
55
41
|
name: rails
|
|
56
42
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -108,29 +94,10 @@ files:
|
|
|
108
94
|
- app/assets/stylesheets/yiffspace/application.css
|
|
109
95
|
- app/controllers/yiff_space/application_controller.rb
|
|
110
96
|
- app/helpers/yiff_space/application_helper.rb
|
|
111
|
-
- app/helpers/yiff_space/auth_helper.rb
|
|
112
97
|
- app/models/yiff_space/application_record.rb
|
|
113
98
|
- app/views/layouts/yiff_space/application.html.erb
|
|
114
99
|
- app/views/yiff_space/error.html.erb
|
|
115
|
-
- engines/auth/app/controllers/yiff_space/auth/application_controller.rb
|
|
116
|
-
- engines/auth/app/controllers/yiff_space/auth/root_controller.rb
|
|
117
|
-
- engines/auth/app/controllers/yiff_space/auth/webhook_controller.rb
|
|
118
|
-
- engines/auth/app/views/yiff_space/auth/root/permissions.html.erb
|
|
119
|
-
- engines/auth/config/routes.rb
|
|
120
|
-
- lib/tasks/yiffspace_tasks.rake
|
|
121
100
|
- lib/yiffspace.rb
|
|
122
|
-
- lib/yiffspace/auth.rb
|
|
123
|
-
- lib/yiffspace/auth/api_user.rb
|
|
124
|
-
- lib/yiffspace/auth/auth_info.rb
|
|
125
|
-
- lib/yiffspace/auth/auth_info/anonymous.rb
|
|
126
|
-
- lib/yiffspace/auth/client.rb
|
|
127
|
-
- lib/yiffspace/auth/discord_info.rb
|
|
128
|
-
- lib/yiffspace/auth/engine.rb
|
|
129
|
-
- lib/yiffspace/auth/helper.rb
|
|
130
|
-
- lib/yiffspace/auth/permissions.rb
|
|
131
|
-
- lib/yiffspace/auth/set_client_name.rb
|
|
132
|
-
- lib/yiffspace/auth/user_info.rb
|
|
133
|
-
- lib/yiffspace/auth/user_info/anonymous.rb
|
|
134
101
|
- lib/yiffspace/concerns/active_record_extensions.rb
|
|
135
102
|
- lib/yiffspace/concerns/api_methods.rb
|
|
136
103
|
- lib/yiffspace/concerns/attribute_matchers.rb
|
|
@@ -146,8 +113,6 @@ files:
|
|
|
146
113
|
- lib/yiffspace/config_builder.rb
|
|
147
114
|
- lib/yiffspace/configuration.rb
|
|
148
115
|
- lib/yiffspace/configuration/images.rb
|
|
149
|
-
- lib/yiffspace/core_ext/action_dispatch/set_auth_client.rb
|
|
150
|
-
- lib/yiffspace/core_ext/action_dispatch/set_auth_client/scoped.rb
|
|
151
116
|
- lib/yiffspace/core_ext/active_record/all.rb
|
|
152
117
|
- lib/yiffspace/core_ext/active_record/where_chain.rb
|
|
153
118
|
- lib/yiffspace/core_ext/all.rb
|
|
@@ -158,14 +123,12 @@ files:
|
|
|
158
123
|
- lib/yiffspace/core_ext/enumerable/parallel.rb
|
|
159
124
|
- lib/yiffspace/core_ext/hash/all.rb
|
|
160
125
|
- lib/yiffspace/core_ext/hash/to_open_hash.rb
|
|
161
|
-
- lib/yiffspace/core_ext/logto/named_session_storage.rb
|
|
162
126
|
- lib/yiffspace/core_ext/object/all.rb
|
|
163
127
|
- lib/yiffspace/core_ext/object/to_b.rb
|
|
164
128
|
- lib/yiffspace/core_ext/object/truthy_falsy.rb
|
|
165
129
|
- lib/yiffspace/core_ext/string/all.rb
|
|
166
130
|
- lib/yiffspace/core_ext/string/sql.rb
|
|
167
|
-
- lib/yiffspace/
|
|
168
|
-
- lib/yiffspace/extensions/action_dispatch/set_auth_client/scoped.rb
|
|
131
|
+
- lib/yiffspace/engine.rb
|
|
169
132
|
- lib/yiffspace/extensions/active_record/where_chain.rb
|
|
170
133
|
- lib/yiffspace/extensions/arel/nodes/cross_join_lateral.rb
|
|
171
134
|
- lib/yiffspace/extensions/arel/nodes/left_join_lateral.rb
|
|
@@ -175,7 +138,6 @@ files:
|
|
|
175
138
|
- lib/yiffspace/extensions/arel/visitors/postgresql/left_join_lateral.rb
|
|
176
139
|
- lib/yiffspace/extensions/enumerable/parallel.rb
|
|
177
140
|
- lib/yiffspace/extensions/hash/to_open_hash.rb
|
|
178
|
-
- lib/yiffspace/extensions/logto/named_session_storage.rb
|
|
179
141
|
- lib/yiffspace/extensions/object/to_b.rb
|
|
180
142
|
- lib/yiffspace/extensions/object/truthy_falsy.rb
|
|
181
143
|
- lib/yiffspace/extensions/string/sql.rb
|
|
@@ -217,19 +179,11 @@ files:
|
|
|
217
179
|
- lib/yiffspace/include/user_name_methods.rb
|
|
218
180
|
- lib/yiffspace/include/user_resolvable.rb
|
|
219
181
|
- lib/yiffspace/include/user_resolvable_methods.rb
|
|
220
|
-
- lib/yiffspace/logto_management_client.rb
|
|
221
|
-
- lib/yiffspace/railtie.rb
|
|
222
182
|
- lib/yiffspace/search/query_builder.rb
|
|
223
183
|
- lib/yiffspace/search/query_dsl.rb
|
|
224
184
|
- lib/yiffspace/search/query_helper.rb
|
|
225
|
-
- lib/yiffspace/serializers/anonymous_auth_info_serializer.rb
|
|
226
|
-
- lib/yiffspace/serializers/anonymous_user_info_serializer.rb
|
|
227
|
-
- lib/yiffspace/serializers/auth_info_serializer.rb
|
|
228
185
|
- lib/yiffspace/serializers/avatar_serializer.rb
|
|
229
186
|
- lib/yiffspace/serializers/banner_serializer.rb
|
|
230
|
-
- lib/yiffspace/serializers/discord_info_serializer.rb
|
|
231
|
-
- lib/yiffspace/serializers/permissions_serializer.rb
|
|
232
|
-
- lib/yiffspace/serializers/user_info_serializer.rb
|
|
233
187
|
- lib/yiffspace/serializers/user_resolvable_serializer.rb
|
|
234
188
|
- lib/yiffspace/utils.rb
|
|
235
189
|
- lib/yiffspace/utils/cache.rb
|
|
@@ -244,7 +198,6 @@ files:
|
|
|
244
198
|
- lib/yiffspace/utils/table_builder.rb
|
|
245
199
|
- lib/yiffspace/utils/trace_logger.rb
|
|
246
200
|
- lib/yiffspace/utils/user_attribute.rb
|
|
247
|
-
- lib/yiffspace/utils/user_deduper.rb
|
|
248
201
|
- lib/yiffspace/utils/user_like.rb
|
|
249
202
|
- lib/yiffspace/utils/user_resolvable.rb
|
|
250
203
|
- lib/yiffspace/utils/user_to_id.rb
|
|
@@ -1,49 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module YiffSpace
|
|
4
|
-
module Auth
|
|
5
|
-
class RootController < ApplicationController
|
|
6
|
-
include(Helper)
|
|
7
|
-
|
|
8
|
-
before_action(:sync_auth_if_dirty!)
|
|
9
|
-
|
|
10
|
-
def show
|
|
11
|
-
client.sign_in(redirect_uri: auth_client_config.redirect_uri, post_redirect_uri: params[:path] || "/")
|
|
12
|
-
end
|
|
13
|
-
|
|
14
|
-
def cb
|
|
15
|
-
client.handle_sign_in_callback(url: request.original_url)
|
|
16
|
-
user = client.fetch_user_info
|
|
17
|
-
self.user = UserInfo.new(id: user["identities"]["discord"]["userId"], user: user, discord: user["identities"]["discord"]["details"]["rawData"])
|
|
18
|
-
token = client.access_token_claims(resource: auth_client_config.resource)
|
|
19
|
-
self.auth = AuthInfo.new(id: user["identities"]["discord"]["userId"], token: token, permissions: token["scope"].split, roles: user["roles"], client_id: auth_client_config.client_id)
|
|
20
|
-
end
|
|
21
|
-
|
|
22
|
-
def permissions; end
|
|
23
|
-
|
|
24
|
-
def logout
|
|
25
|
-
client.sign_out(post_logout_redirect_uri: request.base_url)
|
|
26
|
-
full_reset!
|
|
27
|
-
end
|
|
28
|
-
|
|
29
|
-
def debug
|
|
30
|
-
return render("yiffspace/error", locals: { message: "Access Denied" }, status: :forbidden) unless YiffSpace::Auth.enable_debug_action?
|
|
31
|
-
|
|
32
|
-
render(json: {
|
|
33
|
-
env: request.env.select { |env| env.start_with?("yiffspace.") },
|
|
34
|
-
params: params,
|
|
35
|
-
session: session,
|
|
36
|
-
client: auth_client_config.as_json.merge(client_secret: "[REDACTED]"),
|
|
37
|
-
user: client.fetch_user_info,
|
|
38
|
-
token: client.access_token_claims(resource: auth_client_config.resource),
|
|
39
|
-
})
|
|
40
|
-
end
|
|
41
|
-
|
|
42
|
-
private
|
|
43
|
-
|
|
44
|
-
def client
|
|
45
|
-
@client ||= auth_client_config.logto(self)
|
|
46
|
-
end
|
|
47
|
-
end
|
|
48
|
-
end
|
|
49
|
-
end
|
|
@@ -1,73 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
require("openssl")
|
|
4
|
-
require("active_support/security_utils")
|
|
5
|
-
|
|
6
|
-
module YiffSpace
|
|
7
|
-
module Auth
|
|
8
|
-
class WebhookController < ApplicationController
|
|
9
|
-
skip_before_action(:verify_authenticity_token)
|
|
10
|
-
|
|
11
|
-
HANDLED_EVENTS = %w[
|
|
12
|
-
User.Roles.Updated
|
|
13
|
-
User.SuspensionStatus.Updated
|
|
14
|
-
User.Deleted
|
|
15
|
-
Role.Scopes.Updated
|
|
16
|
-
].freeze
|
|
17
|
-
DIRTY_FLAG_TTL = 24.hours
|
|
18
|
-
|
|
19
|
-
def create
|
|
20
|
-
unless verify_signature
|
|
21
|
-
render(plain: "Unauthorized", status: :unauthorized)
|
|
22
|
-
return
|
|
23
|
-
end
|
|
24
|
-
|
|
25
|
-
payload = JSON.parse(request.raw_post)
|
|
26
|
-
event = payload["event"]
|
|
27
|
-
|
|
28
|
-
handle_event(event, payload) if HANDLED_EVENTS.include?(event)
|
|
29
|
-
|
|
30
|
-
head(:ok)
|
|
31
|
-
rescue JSON::ParserError
|
|
32
|
-
render(plain: "Bad Request", status: :bad_request)
|
|
33
|
-
end
|
|
34
|
-
|
|
35
|
-
private
|
|
36
|
-
|
|
37
|
-
def verify_signature
|
|
38
|
-
secret = auth_client_config.logto_webhook_secret
|
|
39
|
-
return true if secret.blank?
|
|
40
|
-
|
|
41
|
-
received = request.headers["logto-signature-sha-256"].to_s
|
|
42
|
-
expected = OpenSSL::HMAC.hexdigest("SHA256", secret, request.raw_post)
|
|
43
|
-
ActiveSupport::SecurityUtils.secure_compare(received, expected)
|
|
44
|
-
end
|
|
45
|
-
|
|
46
|
-
def handle_event(event, payload)
|
|
47
|
-
data = payload["data"] || {}
|
|
48
|
-
|
|
49
|
-
if event == "Role.Scopes.Updated"
|
|
50
|
-
handle_role_scopes_updated(data)
|
|
51
|
-
else
|
|
52
|
-
user_id = data["id"]
|
|
53
|
-
mark_dirty(user_id) if user_id.present?
|
|
54
|
-
end
|
|
55
|
-
end
|
|
56
|
-
|
|
57
|
-
def handle_role_scopes_updated(data)
|
|
58
|
-
role_id = data["id"]
|
|
59
|
-
return if role_id.blank?
|
|
60
|
-
|
|
61
|
-
management = auth_client_config.logto_management
|
|
62
|
-
users = management.get_users_with_role(role_id)
|
|
63
|
-
users.each { |u| mark_dirty(u["id"]) }
|
|
64
|
-
rescue StandardError => e
|
|
65
|
-
Rails.logger.error("[YiffSpace::Auth::WebhookController] Role.Scopes.Updated fan-out failed: #{e.message}")
|
|
66
|
-
end
|
|
67
|
-
|
|
68
|
-
def mark_dirty(user_id)
|
|
69
|
-
Rails.cache.write(format(Helper::DIRTY_FLAG_KEY, user_id), true, expires_in: DIRTY_FLAG_TTL)
|
|
70
|
-
end
|
|
71
|
-
end
|
|
72
|
-
end
|
|
73
|
-
end
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
<h1 class="title">Permissions</h1>
|
|
2
|
-
<% if logged_in? %>
|
|
3
|
-
<% if auth.permissions.any? %>
|
|
4
|
-
<ul class="permissions-list">
|
|
5
|
-
<% auth.permissions.each do |perm| %>
|
|
6
|
-
<li class="permission"><%= perm %></li>
|
|
7
|
-
<% end %>
|
|
8
|
-
</ul>
|
|
9
|
-
<% else %>
|
|
10
|
-
<p class="message">You have no permissions.</p>
|
|
11
|
-
<% end %>
|
|
12
|
-
<% else %>
|
|
13
|
-
<p class="message">You are not logged in.</p>
|
|
14
|
-
<% end %>
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
YiffSpace::Auth::Engine.routes.draw do
|
|
4
|
-
constraints(YiffSpace::Auth::SetClientName.default) do
|
|
5
|
-
post(:webhook, controller: :webhook)
|
|
6
|
-
get(:cb, controller: :root)
|
|
7
|
-
get(:logout, controller: :root)
|
|
8
|
-
get(:permissions, controller: :root)
|
|
9
|
-
get(:debug, controller: :root) if YiffSpace::Auth.enable_debug_action?
|
|
10
|
-
root(action: :show, controller: :root, as: :auth)
|
|
11
|
-
end
|
|
12
|
-
end
|
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
namespace(:yiffspace) do
|
|
4
|
-
desc("Report and interactively remove duplicate/orphaned Logto users left behind by " \
|
|
5
|
-
"get_or_create_user races. Prompts for confirmation before deleting each one. " \
|
|
6
|
-
"Pass AUTH_CLIENT=name to use a registered auth client other than :default " \
|
|
7
|
-
"(e.g. AUTH_CLIENT=yiffyapi_manage).")
|
|
8
|
-
task(dedupe_users: :environment) do
|
|
9
|
-
client_name = (ENV["AUTH_CLIENT"] || YiffSpace::Auth::DEFAULT_CLIENT_NAME).to_sym
|
|
10
|
-
management = YiffSpace::Auth[client_name].logto_management
|
|
11
|
-
|
|
12
|
-
puts("Scanning users via auth client #{client_name.inspect}...")
|
|
13
|
-
result = YiffSpace::Utils::UserDeduper.scan(management)
|
|
14
|
-
|
|
15
|
-
puts("\n#{result[:conflicts].size} discord id(s) with more than one linked user (ambiguous - not handled by this task, review manually):")
|
|
16
|
-
result[:conflicts].each do |discord_id, group|
|
|
17
|
-
puts(" discordId=#{discord_id}: #{group.map { |u| "#{u.id} (#{u.name})" }.join(', ')}")
|
|
18
|
-
end
|
|
19
|
-
|
|
20
|
-
puts("\n#{result[:unresolved_orphans].size} orphaned user(s) with no matching linked account (not handled by this task, review manually):")
|
|
21
|
-
result[:unresolved_orphans].each do |user|
|
|
22
|
-
puts(" #{user.id} (name=#{user.name}, avatar=#{user.data.avatar})")
|
|
23
|
-
end
|
|
24
|
-
|
|
25
|
-
puts("\n#{result[:deletable_orphans].size} confirmed duplicate(s) - orphan left by a losing get_or_create_user race:")
|
|
26
|
-
if result[:deletable_orphans].empty?
|
|
27
|
-
puts(" none found")
|
|
28
|
-
else
|
|
29
|
-
result[:deletable_orphans].each do |orphan, keeper|
|
|
30
|
-
print(" delete #{orphan.id} (name=#{orphan.name}, avatar=#{orphan.data.avatar}), keeping #{keeper.id} (name=#{keeper.name}) for discordId=#{YiffSpace::Utils::UserDeduper.discord_id_for(keeper)}? [y/N] ")
|
|
31
|
-
answer = $stdin.gets&.strip&.downcase
|
|
32
|
-
if answer == "y"
|
|
33
|
-
management.delete_user(orphan.id)
|
|
34
|
-
puts(" deleted #{orphan.id}")
|
|
35
|
-
else
|
|
36
|
-
puts(" skipped")
|
|
37
|
-
end
|
|
38
|
-
end
|
|
39
|
-
end
|
|
40
|
-
end
|
|
41
|
-
end
|
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module YiffSpace
|
|
4
|
-
module Auth
|
|
5
|
-
class ApiUser
|
|
6
|
-
attr_reader(:data)
|
|
7
|
-
|
|
8
|
-
def initialize(data)
|
|
9
|
-
@data = Utils::OpenHash.from(data)
|
|
10
|
-
end
|
|
11
|
-
|
|
12
|
-
delegate(:id, :name, to: :data)
|
|
13
|
-
|
|
14
|
-
def discord_id
|
|
15
|
-
data.identities.discord.userId
|
|
16
|
-
end
|
|
17
|
-
|
|
18
|
-
def created_at
|
|
19
|
-
Time.zone.at(data.createdAt)
|
|
20
|
-
end
|
|
21
|
-
|
|
22
|
-
def updated_at
|
|
23
|
-
Time.zone.at(data.updatedAt)
|
|
24
|
-
end
|
|
25
|
-
|
|
26
|
-
def last_sign_in_at
|
|
27
|
-
data.lastSignInAt.nil? ? nil : Time.zone.at(data.lastSignInAt)
|
|
28
|
-
end
|
|
29
|
-
|
|
30
|
-
def discord
|
|
31
|
-
DiscordInfo.new(data.identities.discord.details.rawData)
|
|
32
|
-
end
|
|
33
|
-
|
|
34
|
-
def avatar
|
|
35
|
-
Images::Avatar.get_for(discord_id, :discord)
|
|
36
|
-
end
|
|
37
|
-
|
|
38
|
-
def banner
|
|
39
|
-
Images::Banner.get_for(discord_id, :discord)
|
|
40
|
-
end
|
|
41
|
-
end
|
|
42
|
-
end
|
|
43
|
-
end
|
|
@@ -1,60 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
require("singleton")
|
|
4
|
-
|
|
5
|
-
module YiffSpace
|
|
6
|
-
module Auth
|
|
7
|
-
class AuthInfo
|
|
8
|
-
class Anonymous
|
|
9
|
-
include(::Singleton)
|
|
10
|
-
|
|
11
|
-
%i[id token].each do |attr|
|
|
12
|
-
define_method(attr) { |*, **| raise(NotImplementedError, "#{attr} is not present on anonymous auth") }
|
|
13
|
-
end
|
|
14
|
-
|
|
15
|
-
def roles
|
|
16
|
-
[]
|
|
17
|
-
end
|
|
18
|
-
|
|
19
|
-
def permissions
|
|
20
|
-
Permissions.new([])
|
|
21
|
-
end
|
|
22
|
-
|
|
23
|
-
def has_permission?(*)
|
|
24
|
-
false
|
|
25
|
-
end
|
|
26
|
-
|
|
27
|
-
def anonymous?
|
|
28
|
-
true
|
|
29
|
-
end
|
|
30
|
-
|
|
31
|
-
# this feels wrong, but it hopefully shouldn't break anything
|
|
32
|
-
def present?
|
|
33
|
-
false
|
|
34
|
-
end
|
|
35
|
-
|
|
36
|
-
def blank?
|
|
37
|
-
true
|
|
38
|
-
end
|
|
39
|
-
|
|
40
|
-
def serializable_hash(*)
|
|
41
|
-
nil
|
|
42
|
-
end
|
|
43
|
-
|
|
44
|
-
def to_session
|
|
45
|
-
serializable_hash
|
|
46
|
-
end
|
|
47
|
-
|
|
48
|
-
def self.from_json(*)
|
|
49
|
-
Anonymous.instance
|
|
50
|
-
end
|
|
51
|
-
|
|
52
|
-
def self.from_session(data)
|
|
53
|
-
return nil if data.blank?
|
|
54
|
-
|
|
55
|
-
from_json(data)
|
|
56
|
-
end
|
|
57
|
-
end
|
|
58
|
-
end
|
|
59
|
-
end
|
|
60
|
-
end
|