mumukit-auth 7.10.0 → 7.13.0
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/lib/mumukit/auth/permissions.rb +40 -7
- data/lib/mumukit/auth/role.rb +42 -6
- data/lib/mumukit/auth/roles.rb +1 -1
- data/lib/mumukit/auth/scope.rb +12 -8
- data/lib/mumukit/auth/slug.rb +33 -7
- data/lib/mumukit/auth/token.rb +48 -6
- data/lib/mumukit/auth/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5a77054a911454b7372cadecd8bda02e894ff80bd24ee5d19eb4b9086fb17dcc
|
4
|
+
data.tar.gz: 69b57019319e45c0a2c49425fea3964d9e270c5452c61c3f20d374ee41077464
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 36a9d0459ed2513e94851f01312aab4ed88e8abcf17707c2c9c7bb3a86a9be406e8b5d43ac6d7194d568118622bb2801125aba27996c4eff7b12dd6824c538f6
|
7
|
+
data.tar.gz: e16a35c4478a206125c1d489b24ea79c84e0ba5d0082057363deb0d653c44d09e1bf7cc6e86f31268fad9b76d66c3d240eaf1b6f5643121dd7930f4765963289
|
@@ -2,18 +2,15 @@ class Mumukit::Auth::Permissions
|
|
2
2
|
include Mumukit::Auth::Roles
|
3
3
|
include Mumukit::Auth::Protection
|
4
4
|
|
5
|
-
delegate :empty?, to: :scopes
|
6
|
-
|
7
5
|
attr_accessor :scopes
|
8
6
|
|
9
7
|
def initialize(scopes={})
|
10
|
-
|
11
|
-
|
12
|
-
@scopes = scopes.with_indifferent_access
|
8
|
+
@scopes = {}.with_indifferent_access
|
9
|
+
add_scopes! scopes
|
13
10
|
end
|
14
11
|
|
15
12
|
def has_permission?(role, resource_slug)
|
16
|
-
|
13
|
+
role.to_mumukit_role.allows?(resource_slug, self)
|
17
14
|
end
|
18
15
|
|
19
16
|
def role_allows?(role, resource_slug)
|
@@ -28,6 +25,21 @@ class Mumukit::Auth::Permissions
|
|
28
25
|
self.scopes[role] ||= Mumukit::Auth::Scope.new
|
29
26
|
end
|
30
27
|
|
28
|
+
def empty?
|
29
|
+
scopes.all? { |_, it| it.empty? }
|
30
|
+
end
|
31
|
+
|
32
|
+
def compact!
|
33
|
+
old_scopes = @scopes.dup
|
34
|
+
@scopes = {}.with_indifferent_access
|
35
|
+
|
36
|
+
old_scopes.each do |role, scope|
|
37
|
+
scope.grants.each do |grant|
|
38
|
+
push_and_compact! role, grant
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
31
43
|
# Deprecated: use `student_granted_organizations` organizations instead
|
32
44
|
def accessible_organizations
|
33
45
|
warn "Don't use accessible_organizations, since this method is probably not doing what you would expect.\n" +
|
@@ -54,7 +66,13 @@ class Mumukit::Auth::Permissions
|
|
54
66
|
end
|
55
67
|
|
56
68
|
def add_permission!(role, *grants)
|
57
|
-
|
69
|
+
role = role.to_mumukit_role
|
70
|
+
grants.each { |grant| push_and_compact! role, grant }
|
71
|
+
end
|
72
|
+
|
73
|
+
def add_scopes!(scopes)
|
74
|
+
raise 'invalid scopes' if scopes.any? { |key, value| value.class != Mumukit::Auth::Scope }
|
75
|
+
scopes.each { |role, scope| add_permission! role, *scope.grants }
|
58
76
|
end
|
59
77
|
|
60
78
|
def merge(other)
|
@@ -146,4 +164,19 @@ class Mumukit::Auth::Permissions
|
|
146
164
|
scope.grants.all? { |grant| has_permission? role, grant }
|
147
165
|
end
|
148
166
|
|
167
|
+
def push_and_compact!(role, grant)
|
168
|
+
role = role.to_mumukit_role
|
169
|
+
grant = grant.to_mumukit_grant
|
170
|
+
|
171
|
+
scopes.each do |other_role, other_scope|
|
172
|
+
other_role = other_role.to_mumukit_role
|
173
|
+
|
174
|
+
if other_role.narrower_than?(role)
|
175
|
+
other_scope.remove_narrower_grants!(grant)
|
176
|
+
elsif other_role.broader_than?(role) && other_scope.has_broader_grant?(grant)
|
177
|
+
return
|
178
|
+
end
|
179
|
+
end
|
180
|
+
scope_for(role.to_sym).add_grant! grant
|
181
|
+
end
|
149
182
|
end
|
data/lib/mumukit/auth/role.rb
CHANGED
@@ -1,3 +1,16 @@
|
|
1
|
+
|
2
|
+
class String
|
3
|
+
def to_mumukit_role
|
4
|
+
Mumukit::Auth::Role.parse self
|
5
|
+
end
|
6
|
+
end
|
7
|
+
|
8
|
+
class Symbol
|
9
|
+
def to_mumukit_role
|
10
|
+
Mumukit::Auth::Role.parse self
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
1
14
|
module Mumukit::Auth
|
2
15
|
class Role
|
3
16
|
def initialize(symbol)
|
@@ -17,17 +30,36 @@ module Mumukit::Auth
|
|
17
30
|
@symbol
|
18
31
|
end
|
19
32
|
|
20
|
-
|
33
|
+
def broader_than?(other)
|
34
|
+
other.narrower_than? self
|
35
|
+
end
|
36
|
+
|
37
|
+
def narrower_than?(other)
|
38
|
+
other.class != self.class && _narrower_than_other?(other)
|
39
|
+
end
|
21
40
|
|
22
|
-
def
|
23
|
-
|
41
|
+
def to_mumukit_role
|
42
|
+
self
|
24
43
|
end
|
25
44
|
|
26
|
-
def
|
27
|
-
|
28
|
-
@roles[role] ||= "Mumukit::Auth::Role::#{role.to_s.camelize}".constantize.new(role.to_sym)
|
45
|
+
def _narrower_than_other?(other)
|
46
|
+
self.parent.class == other.class || self.parent._narrower_than_other?(other)
|
29
47
|
end
|
30
48
|
|
49
|
+
class << self
|
50
|
+
def parent(parent)
|
51
|
+
define_method(:parent) { self.class.parse(parent) }
|
52
|
+
end
|
53
|
+
|
54
|
+
def parse(role)
|
55
|
+
@roles ||= {}
|
56
|
+
@roles[role.to_sym] ||= "Mumukit::Auth::Role::#{role.to_s.camelize}".constantize.new(role.to_sym)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
class ExStudent < Role
|
61
|
+
parent :student
|
62
|
+
end
|
31
63
|
class Student < Role
|
32
64
|
parent :teacher
|
33
65
|
end
|
@@ -61,6 +93,10 @@ module Mumukit::Auth
|
|
61
93
|
def parent_allows?(*)
|
62
94
|
false
|
63
95
|
end
|
96
|
+
|
97
|
+
def _narrower_than_other?(*)
|
98
|
+
false
|
99
|
+
end
|
64
100
|
end
|
65
101
|
end
|
66
102
|
end
|
data/lib/mumukit/auth/roles.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
module Mumukit::Auth
|
2
2
|
module Roles
|
3
|
-
ROLES = [:student, :teacher, :headmaster, :writer, :editor, :janitor, :moderator, :forum_supervisor, :admin, :owner]
|
3
|
+
ROLES = [:ex_student, :student, :teacher, :headmaster, :writer, :editor, :janitor, :moderator, :forum_supervisor, :admin, :owner]
|
4
4
|
|
5
5
|
ROLES.each do |role|
|
6
6
|
define_method "#{role}?" do |scope = Mumukit::Auth::Slug.any|
|
data/lib/mumukit/auth/scope.rb
CHANGED
@@ -20,6 +20,10 @@ module Mumukit::Auth
|
|
20
20
|
self.grants.delete(grant)
|
21
21
|
end
|
22
22
|
|
23
|
+
def empty?
|
24
|
+
grants.empty?
|
25
|
+
end
|
26
|
+
|
23
27
|
def merge(other)
|
24
28
|
self.class.new grants + other.grants
|
25
29
|
end
|
@@ -54,6 +58,14 @@ module Mumukit::Auth
|
|
54
58
|
to_s
|
55
59
|
end
|
56
60
|
|
61
|
+
def remove_narrower_grants!(grant)
|
62
|
+
grants.reject! { |it| grant.allows? it }
|
63
|
+
end
|
64
|
+
|
65
|
+
def has_broader_grant?(grant)
|
66
|
+
grants.any? { |it| it.allows? grant }
|
67
|
+
end
|
68
|
+
|
57
69
|
private
|
58
70
|
|
59
71
|
def any_grant?(&block)
|
@@ -66,13 +78,5 @@ module Mumukit::Auth
|
|
66
78
|
remove_narrower_grants! grant
|
67
79
|
grants << grant
|
68
80
|
end
|
69
|
-
|
70
|
-
def remove_narrower_grants!(grant)
|
71
|
-
grants.reject! { |it| grant.allows? it }
|
72
|
-
end
|
73
|
-
|
74
|
-
def has_broader_grant?(grant)
|
75
|
-
grants.any? { |it| it.allows? grant }
|
76
|
-
end
|
77
81
|
end
|
78
82
|
end
|
data/lib/mumukit/auth/slug.rb
CHANGED
@@ -35,11 +35,11 @@ module Mumukit::Auth
|
|
35
35
|
end
|
36
36
|
|
37
37
|
def ==(o)
|
38
|
-
|
38
|
+
o.is_a?(Mumukit::Auth::Slug) && self.normalize.eql?(o.normalize)
|
39
39
|
end
|
40
40
|
|
41
41
|
def eql?(o)
|
42
|
-
|
42
|
+
o.is_a?(Mumukit::Auth::Slug) && to_s == o.to_s
|
43
43
|
end
|
44
44
|
|
45
45
|
def hash
|
@@ -57,7 +57,15 @@ module Mumukit::Auth
|
|
57
57
|
end
|
58
58
|
|
59
59
|
def normalize
|
60
|
-
|
60
|
+
Normalized.new(first, second)
|
61
|
+
end
|
62
|
+
|
63
|
+
def normalized_s
|
64
|
+
normalize.to_s
|
65
|
+
end
|
66
|
+
|
67
|
+
def normalized?
|
68
|
+
normalize.eql? self
|
61
69
|
end
|
62
70
|
|
63
71
|
def inspect
|
@@ -99,7 +107,7 @@ module Mumukit::Auth
|
|
99
107
|
end
|
100
108
|
|
101
109
|
def self.normalize(first, second)
|
102
|
-
new(first, second)
|
110
|
+
Normalized.new(first, second)
|
103
111
|
end
|
104
112
|
|
105
113
|
private
|
@@ -117,11 +125,29 @@ module Mumukit::Auth
|
|
117
125
|
raise Mumukit::Auth::InvalidSlugFormatError, "Invalid slug: #{slug}. It must be in first/second format"
|
118
126
|
end
|
119
127
|
end
|
128
|
+
|
129
|
+
class Normalized < Slug
|
130
|
+
alias_method :_normalize!, :normalize!
|
131
|
+
|
132
|
+
def initialize(*)
|
133
|
+
super
|
134
|
+
_normalize!
|
135
|
+
end
|
136
|
+
|
137
|
+
def normalize
|
138
|
+
self
|
139
|
+
end
|
140
|
+
|
141
|
+
def normalize!
|
142
|
+
self
|
143
|
+
end
|
144
|
+
|
145
|
+
def normalized?
|
146
|
+
true
|
147
|
+
end
|
148
|
+
end
|
120
149
|
end
|
121
150
|
|
122
151
|
class InvalidSlugFormatError < StandardError
|
123
152
|
end
|
124
153
|
end
|
125
|
-
|
126
|
-
|
127
|
-
|
data/lib/mumukit/auth/token.rb
CHANGED
@@ -2,7 +2,7 @@ module Mumukit::Auth
|
|
2
2
|
class Token
|
3
3
|
attr_reader :jwt, :client
|
4
4
|
|
5
|
-
def initialize(jwt, client)
|
5
|
+
def initialize(jwt = {}, client = Mumukit::Auth::Client.new)
|
6
6
|
@jwt = jwt
|
7
7
|
@client = client
|
8
8
|
end
|
@@ -15,6 +15,22 @@ module Mumukit::Auth
|
|
15
15
|
@uid ||= jwt['uid'] || jwt['email'] || jwt['sub']
|
16
16
|
end
|
17
17
|
|
18
|
+
def organization
|
19
|
+
@organization ||= jwt['org']
|
20
|
+
end
|
21
|
+
|
22
|
+
def expiration
|
23
|
+
@expiration ||= Time.at jwt['exp']
|
24
|
+
end
|
25
|
+
|
26
|
+
def subject_id
|
27
|
+
@subject_id ||= jwt['sbid']
|
28
|
+
end
|
29
|
+
|
30
|
+
def subject_type
|
31
|
+
@subject_type ||= jwt['sbt']
|
32
|
+
end
|
33
|
+
|
18
34
|
def verify_client!
|
19
35
|
raise Mumukit::Auth::InvalidTokenError.new('aud mismatch') if client.id != jwt['aud']
|
20
36
|
end
|
@@ -23,12 +39,13 @@ module Mumukit::Auth
|
|
23
39
|
client.encode jwt
|
24
40
|
end
|
25
41
|
|
26
|
-
def
|
27
|
-
|
42
|
+
def encode_header
|
43
|
+
'Bearer ' + encode
|
28
44
|
end
|
29
45
|
|
30
46
|
def self.encode(uid, metadata, client = Mumukit::Auth::Client.new)
|
31
|
-
|
47
|
+
warn "Deprecated: please use build and then encode"
|
48
|
+
build(uid, client, metadata: metadata).encode
|
32
49
|
end
|
33
50
|
|
34
51
|
def self.decode(encoded, client = Mumukit::Auth::Client.new)
|
@@ -38,7 +55,8 @@ module Mumukit::Auth
|
|
38
55
|
end
|
39
56
|
|
40
57
|
def self.encode_header(uid, metadata)
|
41
|
-
|
58
|
+
warn "Deprecated: please use build and then encode_header"
|
59
|
+
'Bearer ' + build(uid, metadata: metadata).encode_header
|
42
60
|
end
|
43
61
|
|
44
62
|
def self.decode_header(header, client = Mumukit::Auth::Client.new)
|
@@ -50,6 +68,30 @@ module Mumukit::Auth
|
|
50
68
|
header.split(' ').last
|
51
69
|
end
|
52
70
|
|
71
|
+
def self.build(uid, client = Mumukit::Auth::Client.new,
|
72
|
+
expiration: nil, organization: nil,
|
73
|
+
subject_id: nil, subject_type: nil,
|
74
|
+
metadata: {})
|
75
|
+
new({
|
76
|
+
'uid' => uid,
|
77
|
+
'aud' => client.id,
|
78
|
+
'exp' => expiration&.to_i,
|
79
|
+
'org' => organization,
|
80
|
+
'metadata' => metadata,
|
81
|
+
'sbid' => subject_id,
|
82
|
+
'sbt' => subject_type
|
83
|
+
}.compact,
|
84
|
+
client)
|
85
|
+
end
|
86
|
+
|
87
|
+
def self.load(encoded)
|
88
|
+
if encoded.present?
|
89
|
+
decode encoded rescue nil
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
def self.dump(decoded)
|
94
|
+
decoded.encode
|
95
|
+
end
|
53
96
|
end
|
54
97
|
end
|
55
|
-
|
data/lib/mumukit/auth/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: mumukit-auth
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 7.
|
4
|
+
version: 7.13.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Franco Leonardo Bulgarelli
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2022-07-08 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|