yiffspace 0.0.11 → 0.0.12
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
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: db133305de79cf1a94b029e1e149359cd4b94764850b020316e7c14be52a4104
|
|
4
|
+
data.tar.gz: e9add13312cffed633e8ccb8594843b0468d8dc8a691bdc8910bc8df05ccb9a9
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 78c7fcfe985b6f98b9ff42d0cbff09b75442443ab950ac6e013a62bdbf23aca5452f9bde3c8248fa7e10635254b2b5746dd6c6cd4858a58433463556b9a3ba28
|
|
7
|
+
data.tar.gz: 1dead8a526b3c5325b79b0c351183d4813c6c4d42d9158d7308376dd05eaf5bcfc633d36abd4c9c6873612bb24e1cabda5306d0e7418085e307a54bbef460a0f
|
|
@@ -0,0 +1,43 @@
|
|
|
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, 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
|
+
data.identities.discord.details.blank? ? nil : 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,6 +1,7 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
require_relative("../core_ext/logto/named_session_storage")
|
|
4
|
+
require("httparty")
|
|
4
5
|
|
|
5
6
|
module YiffSpace
|
|
6
7
|
module Auth
|
|
@@ -38,6 +39,18 @@ module YiffSpace
|
|
|
38
39
|
storage: LogtoClient::NamedSessionStorage.new("yiffspace", controller.session, app_id: @name),
|
|
39
40
|
)
|
|
40
41
|
end
|
|
42
|
+
|
|
43
|
+
def logto_management
|
|
44
|
+
@logto_management ||= LogtoManagementClient.new(self)
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def fetch_discord_user(id)
|
|
48
|
+
response = HTTParty.get("https://discord.com/api/v10/users/#{id}", { headers: { "Authorization" => "Bot #{YiffSpace.config.discord_bot_token}" } })
|
|
49
|
+
return nil if response.code == 404
|
|
50
|
+
raise("failed to fetch discord user: #{response.code} #{response.message}\n#{response.parsed_response.inspect}") if response.code != 200
|
|
51
|
+
|
|
52
|
+
DiscordInfo.new(response.parsed_response)
|
|
53
|
+
end
|
|
41
54
|
end
|
|
42
55
|
end
|
|
43
56
|
end
|
|
@@ -3,13 +3,15 @@
|
|
|
3
3
|
module YiffSpace
|
|
4
4
|
module Auth
|
|
5
5
|
class DiscordInfo
|
|
6
|
-
|
|
7
|
-
|
|
6
|
+
# locale, mfa_enabled, and premium_type are not present for legacy users backfilled from api data,
|
|
7
|
+
# we don't need that data either way
|
|
8
|
+
ATTRIBUTES = %i[id flags avatar banner username global_name public_flags discriminator].freeze
|
|
9
|
+
attr_reader(:data, *ATTRIBUTES)
|
|
8
10
|
|
|
9
11
|
def initialize(options = {}, **kwargs)
|
|
10
|
-
|
|
12
|
+
@data = options.merge(kwargs).with_indifferent_access
|
|
11
13
|
ATTRIBUTES.each do |attr|
|
|
12
|
-
instance_variable_set("@#{attr}",
|
|
14
|
+
instance_variable_set("@#{attr}", @data[attr])
|
|
13
15
|
end
|
|
14
16
|
|
|
15
17
|
return unless YiffSpace.config.auth.update_discord_images
|
|
@@ -31,6 +31,12 @@ 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
|
+
|
|
34
40
|
# The anonymous user's name, can be a proc
|
|
35
41
|
attr_reader(:anonymous_user_name)
|
|
36
42
|
|
|
@@ -43,15 +49,19 @@ module YiffSpace
|
|
|
43
49
|
attr_writer(:system_user_getter)
|
|
44
50
|
|
|
45
51
|
def initialize
|
|
46
|
-
@max_multi_count
|
|
47
|
-
@redis_url
|
|
48
|
-
@user_class
|
|
49
|
-
@user_like_class
|
|
50
|
-
@user_resolvable_class
|
|
51
|
-
@current_class
|
|
52
|
-
@default_ip_address
|
|
53
|
-
@last_ip_addr_attribute
|
|
54
|
-
@anonymous_user_name
|
|
52
|
+
@max_multi_count = -> { 100 }
|
|
53
|
+
@redis_url = -> {}
|
|
54
|
+
@user_class = nil
|
|
55
|
+
@user_like_class = nil
|
|
56
|
+
@user_resolvable_class = nil
|
|
57
|
+
@current_class = nil
|
|
58
|
+
@default_ip_address = "127.0.0.1"
|
|
59
|
+
@last_ip_addr_attribute = :last_ip_addr
|
|
60
|
+
@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
|
|
55
65
|
end
|
|
56
66
|
|
|
57
67
|
def user_class
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require("active_support/core_ext/integer/time")
|
|
4
|
+
require("httparty")
|
|
5
|
+
|
|
6
|
+
module YiffSpace
|
|
7
|
+
class LogtoManagementClient
|
|
8
|
+
attr_reader(:auth)
|
|
9
|
+
|
|
10
|
+
def initialize(auth)
|
|
11
|
+
@auth = auth
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def get_token # rubocop:disable Naming/AccessorMethodName
|
|
15
|
+
if @_cached_token
|
|
16
|
+
return @_cached_token if @_cache_expire_time > Time.current
|
|
17
|
+
|
|
18
|
+
@_cached_token = nil
|
|
19
|
+
@_cache_expire_time = nil
|
|
20
|
+
end
|
|
21
|
+
response = HTTParty.post("#{auth.server_url}/oidc/token", {
|
|
22
|
+
body: {
|
|
23
|
+
grant_type: "client_credentials",
|
|
24
|
+
client_id: YiffSpace.config.logto_api_client_id,
|
|
25
|
+
client_secret: YiffSpace.config.logto_api_client_secret,
|
|
26
|
+
resource: YiffSpace.config.logto_api_resource,
|
|
27
|
+
scope: "all",
|
|
28
|
+
},
|
|
29
|
+
})
|
|
30
|
+
raise("failed to get access token: #{response.to_json}") unless response.key?("access_token")
|
|
31
|
+
|
|
32
|
+
@_cached_token = response["access_token"]
|
|
33
|
+
@_cache_expire_time = response["expires_in"].to_i.seconds.from_now
|
|
34
|
+
response["access_token"]
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def get_user(id)
|
|
38
|
+
response = HTTParty.get("#{auth.server_url}/api/users?discordId=#{id}", { headers: { "Authorization" => "Bearer #{get_token}" } })
|
|
39
|
+
return nil if response.code == 404 || (response.parsed_response.is_a?(Array) && response.parsed_response.empty?)
|
|
40
|
+
raise("failed to get user: #{response.code} #{response.message}\n#{response.parsed_response.inspect}") if response.code != 200 || !response.parsed_response.is_a?(Array)
|
|
41
|
+
|
|
42
|
+
Utils::TraceLogger.warn("LogtoManagementClient", "query discordId=#{id} returned more than one user:\n#{response.parsed_response.inspect}") if response.parsed_response.length > 1
|
|
43
|
+
|
|
44
|
+
Auth::ApiUser.new(response.parsed_response.first)
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def create_user(id)
|
|
48
|
+
details = auth.fetch_discord_user(id)&.data
|
|
49
|
+
raise("invalid discord user: #{id}") if details.blank?
|
|
50
|
+
|
|
51
|
+
response = HTTParty.post("#{auth.server_url}/api/users", {
|
|
52
|
+
headers: { "Authorization" => "Bearer #{get_token}", "Content-Type" => "application/json" },
|
|
53
|
+
body: { avatar: "https://cdn.discordapp.com/avatars/#{details['id']}/#{details['avatar']}", username: details["username"] }.to_json,
|
|
54
|
+
})
|
|
55
|
+
raise("failed to create user: #{response.code} #{response.message}\n#{response.parsed_response.inspect}") if response.code != 200
|
|
56
|
+
|
|
57
|
+
response2 = HTTParty.put("#{auth.server_url}/api/users/#{response.parsed_response['id']}/identities/discord", {
|
|
58
|
+
headers: { "Authorization" => "Bearer #{get_token}", "Content-Type" => "application/json" },
|
|
59
|
+
body: {
|
|
60
|
+
userId: details["id"],
|
|
61
|
+
details: {
|
|
62
|
+
id: details["id"],
|
|
63
|
+
name: details["username"],
|
|
64
|
+
avatar: "https://cdn.discordapp.com/avatars/#{details['id']}/#{details['avatar']}",
|
|
65
|
+
rawData: details,
|
|
66
|
+
},
|
|
67
|
+
}.to_json,
|
|
68
|
+
})
|
|
69
|
+
raise("failed to add discord identity: #{response2.code} #{response2.message}\n#{response2.parsed_response.inspect}") if response2.code != 201
|
|
70
|
+
|
|
71
|
+
Auth::ApiUser.new(response.parsed_response)
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
def get_or_create_user(id)
|
|
75
|
+
get_user(id) || create_user(id)
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
end
|
data/lib/yiffspace/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: yiffspace
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.0.
|
|
4
|
+
version: 0.0.12
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Donovan_DMC
|
|
8
8
|
bindir: bin
|
|
9
9
|
cert_chain: []
|
|
10
|
-
date: 2026-06-
|
|
10
|
+
date: 2026-06-21 00:00:00.000000000 Z
|
|
11
11
|
dependencies:
|
|
12
12
|
- !ruby/object:Gem::Dependency
|
|
13
13
|
name: abbrev
|
|
@@ -119,6 +119,7 @@ files:
|
|
|
119
119
|
- lib/tasks/yiff_space_tasks.rake
|
|
120
120
|
- lib/yiffspace.rb
|
|
121
121
|
- lib/yiffspace/auth.rb
|
|
122
|
+
- lib/yiffspace/auth/api_user.rb
|
|
122
123
|
- lib/yiffspace/auth/auth_info.rb
|
|
123
124
|
- lib/yiffspace/auth/auth_info/anonymous.rb
|
|
124
125
|
- lib/yiffspace/auth/client.rb
|
|
@@ -201,6 +202,7 @@ files:
|
|
|
201
202
|
- lib/yiffspace/include/user_attribute.rb
|
|
202
203
|
- lib/yiffspace/include/user_like.rb
|
|
203
204
|
- lib/yiffspace/include/user_resolvable.rb
|
|
205
|
+
- lib/yiffspace/logto_management_client.rb
|
|
204
206
|
- lib/yiffspace/railtie.rb
|
|
205
207
|
- lib/yiffspace/search/query_builder.rb
|
|
206
208
|
- lib/yiffspace/search/query_dsl.rb
|