@@ -4,169 +4,171 @@ require "../sortable_json"
44require " ../tag"
55
66module LavinMQ
7- class User
8- include SortableJSON
9- getter name, password, permissions
10- property tags, plain_text_password
11- alias Permissions = NamedTuple (config: Regex , read: Regex , write: Regex )
12-
13- @name : String
14- @permissions = Hash (String , Permissions ).new
15- @password : Auth ::Password ? = nil
16- @plain_text_password : String ?
17- @tags = Array (Tag ).new
18-
19- def initialize (pull : JSON ::PullParser )
20- loc = pull.location
21- name = hash = hash_algo = nil
22- pull.read_object do |key |
23- case key
24- when " name"
25- name = pull.read_string
26- when " password_hash"
27- hash = pull.read_string
28- when " hashing_algorithm"
29- hash_algo = pull.read_string
30- when " permissions"
31- parse_permissions(pull)
32- when " tags"
33- @tags = Tag .parse_list(pull.read_string)
34- else nil
7+ module Auth
8+ class User
9+ include SortableJSON
10+ getter name, password, permissions
11+ property tags, plain_text_password
12+ alias Permissions = NamedTuple (config: Regex , read: Regex , write: Regex )
13+
14+ @name : String
15+ @permissions = Hash (String , Permissions ).new
16+ @password : Auth ::Password ? = nil
17+ @plain_text_password : String ?
18+ @tags = Array (Tag ).new
19+
20+ def initialize (pull : JSON ::PullParser )
21+ loc = pull.location
22+ name = hash = hash_algo = nil
23+ pull.read_object do |key |
24+ case key
25+ when " name"
26+ name = pull.read_string
27+ when " password_hash"
28+ hash = pull.read_string
29+ when " hashing_algorithm"
30+ hash_algo = pull.read_string
31+ when " permissions"
32+ parse_permissions(pull)
33+ when " tags"
34+ @tags = Tag .parse_list(pull.read_string)
35+ else nil
36+ end
3537 end
38+ raise JSON ::ParseException .new(" Missing json attribute: name" , * loc) if name.nil?
39+ raise JSON ::ParseException .new(" Missing json attribute: password_hash" , * loc) if hash.nil?
40+ @name = name
41+ @password = parse_password(hash, hash_algo, loc)
3642 end
37- raise JSON ::ParseException .new(" Missing json attribute: name" , * loc) if name.nil?
38- raise JSON ::ParseException .new(" Missing json attribute: password_hash" , * loc) if hash.nil?
39- @name = name
40- @password = parse_password(hash, hash_algo, loc)
41- end
4243
43- def self.create (name : String , password : String , hash_algorithm : String , tags : Array (Tag ))
44- pwd = hash_password(password, hash_algorithm)
45- self .new(name, pwd, tags)
46- end
44+ def self.create (name : String , password : String , hash_algorithm : String , tags : Array (Tag ))
45+ pwd = hash_password(password, hash_algorithm)
46+ self .new(name, pwd, tags)
47+ end
4748
48- def self.hash_password (password, hash_algorithm)
49- case hash_algorithm
50- when /bcrypt$/i then Auth ::Password ::BcryptPassword .create(password, cost: 4 )
51- when /sha256$/i then Auth ::Password ::SHA256Password .create(password)
52- when /sha512$/i then Auth ::Password ::SHA512Password .create(password)
53- when /md5$/i then Auth ::Password ::MD5Password .create(password)
54- else raise UnknownHashAlgoritm .new(hash_algorithm)
49+ def self.hash_password (password, hash_algorithm)
50+ case hash_algorithm
51+ when /bcrypt$/i then Auth ::Password ::BcryptPassword .create(password, cost: 4 )
52+ when /sha256$/i then Auth ::Password ::SHA256Password .create(password)
53+ when /sha512$/i then Auth ::Password ::SHA512Password .create(password)
54+ when /md5$/i then Auth ::Password ::MD5Password .create(password)
55+ else raise UnknownHashAlgoritm .new(hash_algorithm)
56+ end
5557 end
56- end
5758
58- private def parse_password (hash , hash_algorithm , loc = nil )
59- case hash_algorithm
60- when /bcrypt$/i then Auth ::Password ::BcryptPassword .new(hash)
61- when /sha256$/i then Auth ::Password ::SHA256Password .new(hash)
62- when /sha512$/i then Auth ::Password ::SHA512Password .new(hash)
63- when /md5$/i , nil then Auth ::Password ::MD5Password .new(hash)
64- else
65- if loc
66- raise JSON ::ParseException .new(" Unsupported hash algorithm" , * loc)
59+ private def parse_password (hash , hash_algorithm , loc = nil )
60+ case hash_algorithm
61+ when /bcrypt$/i then Auth ::Password ::BcryptPassword .new(hash)
62+ when /sha256$/i then Auth ::Password ::SHA256Password .new(hash)
63+ when /sha512$/i then Auth ::Password ::SHA512Password .new(hash)
64+ when /md5$/i , nil then Auth ::Password ::MD5Password .new(hash)
6765 else
68- raise UnknownHashAlgoritm .new(hash_algorithm)
66+ if loc
67+ raise JSON ::ParseException .new(" Unsupported hash algorithm" , * loc)
68+ else
69+ raise UnknownHashAlgoritm .new(hash_algorithm)
70+ end
6971 end
7072 end
71- end
7273
73- def self.create_hidden_user (name )
74- password = Random ::Secure .urlsafe_base64 (32 )
75- password_hash = hash_password(password, " sha256" )
76- user = self .new(name, password_hash, [Tag ::Administrator ])
77- user.plain_text_password = password
78- user
79- end
74+ def self.create_hidden_user (name )
75+ password = Random ::Secure .urlsafe_base64 (32 )
76+ password_hash = hash_password(password, " sha256" )
77+ user = self .new(name, password_hash, [Tag ::Administrator ])
78+ user.plain_text_password = password
79+ user
80+ end
8081
81- def initialize (@name , password_hash, hash_algorithm, @tags )
82- update_password_hash(password_hash, hash_algorithm)
83- end
82+ def initialize (@name , password_hash, hash_algorithm, @tags )
83+ update_password_hash(password_hash, hash_algorithm)
84+ end
8485
85- def initialize (@name , @password , @tags )
86- end
86+ def initialize (@name , @password , @tags )
87+ end
8788
88- def hidden ?
89- UserStore .hidden?(@name )
90- end
89+ def hidden ?
90+ UserStore .hidden?(@name )
91+ end
9192
92- def update_password_hash (password_hash, hash_algorithm)
93- if password_hash.empty?
94- @password = nil
95- return
93+ def update_password_hash (password_hash, hash_algorithm)
94+ if password_hash.empty?
95+ @password = nil
96+ return
97+ end
98+ @password = parse_password(password_hash, hash_algorithm)
9699 end
97- @password = parse_password(password_hash, hash_algorithm)
98- end
99100
100- def update_password (password, hash_algorithm = " sha256" )
101- return if @password .try & .verify(password)
102- @password = User .hash_password(password, hash_algorithm)
103- end
101+ def update_password (password, hash_algorithm = " sha256" )
102+ return if @password .try & .verify(password)
103+ @password = User .hash_password(password, hash_algorithm)
104+ end
104105
105- def details_tuple
106- user_details.merge(permissions: @permissions )
107- end
106+ def details_tuple
107+ user_details.merge(permissions: @permissions )
108+ end
108109
109- def user_details
110- {
111- name: @name ,
112- password_hash: @password ,
113- hashing_algorithm: @password .try & .hash_algorithm,
114- tags: @tags .map(& .to_s.downcase).join(" ," ),
115- }
116- end
110+ def user_details
111+ {
112+ name: @name ,
113+ password_hash: @password ,
114+ hashing_algorithm: @password .try & .hash_algorithm,
115+ tags: @tags .map(& .to_s.downcase).join(" ," ),
116+ }
117+ end
117118
118- def permissions_details
119- @permissions .map { |k , p | permissions_details(k, p) }
120- end
119+ def permissions_details
120+ @permissions .map { |k , p | permissions_details(k, p) }
121+ end
121122
122- def permissions_details (vhost, p)
123- {
124- user: @name ,
125- vhost: vhost,
126- configure: p[:config ],
127- read: p[:read ],
128- write: p[:write ],
129- }
130- end
123+ def permissions_details (vhost, p)
124+ {
125+ user: @name ,
126+ vhost: vhost,
127+ configure: p[:config ],
128+ read: p[:read ],
129+ write: p[:write ],
130+ }
131+ end
131132
132- def can_write ?(vhost, name) : Bool
133- perm = permissions[vhost]?
134- perm ? perm_match?(perm[:write ], name) : false
135- end
133+ def can_write ?(vhost, name) : Bool
134+ perm = permissions[vhost]?
135+ perm ? perm_match?(perm[:write ], name) : false
136+ end
136137
137- def can_read ?(vhost, name) : Bool
138- perm = permissions[vhost]?
139- perm ? perm_match?(perm[:read ], name) : false
140- end
138+ def can_read ?(vhost, name) : Bool
139+ perm = permissions[vhost]?
140+ perm ? perm_match?(perm[:read ], name) : false
141+ end
141142
142- def can_config ?(vhost, name) : Bool
143- perm = permissions[vhost]?
144- perm ? perm_match?(perm[:config ], name) : false
145- end
143+ def can_config ?(vhost, name) : Bool
144+ perm = permissions[vhost]?
145+ perm ? perm_match?(perm[:config ], name) : false
146+ end
146147
147- def can_impersonate ?
148- @tags .includes? Tag ::Impersonator
149- end
148+ def can_impersonate ?
149+ @tags .includes? Tag ::Impersonator
150+ end
150151
151- private def parse_permissions (pull )
152- pull.read_object do |vhost |
153- config = read = write = /^$/
154- pull.read_object do |ikey |
155- case ikey
156- when " config" then config = Regex .from_json(pull)
157- when " read" then read = Regex .from_json(pull)
158- when " write" then write = Regex .from_json(pull)
159- else nil
152+ private def parse_permissions (pull )
153+ pull.read_object do |vhost |
154+ config = read = write = /^$/
155+ pull.read_object do |ikey |
156+ case ikey
157+ when " config" then config = Regex .from_json(pull)
158+ when " read" then read = Regex .from_json(pull)
159+ when " write" then write = Regex .from_json(pull)
160+ else nil
161+ end
160162 end
163+ @permissions [vhost] = {config: config, read: read, write: write}
161164 end
162- @permissions [vhost] = {config: config, read: read, write: write}
163165 end
164- end
165166
166- private def perm_match? (perm , name )
167- perm != /^$/ && perm != // && perm.matches? name
168- end
167+ private def perm_match? (perm , name )
168+ perm != /^$/ && perm != // && perm.matches? name
169+ end
169170
170- class UnknownHashAlgoritm < Exception ; end
171+ class UnknownHashAlgoritm < Exception ; end
172+ end
171173 end
172174end
0 commit comments