| 
									
										
										
										
											2018-04-04 22:44:39 +03:00
										 |  |  | require "mongoid" | 
					
						
							|  |  |  | require_relative "role" | 
					
						
							| 
									
										
										
										
											2014-05-08 15:34:26 +04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-06 12:20:30 +03:00
										 |  |  | module Devops | 
					
						
							|  |  |  |   module Model | 
					
						
							| 
									
										
										
										
											2018-04-04 22:44:39 +03:00
										 |  |  |     class User | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       include ::Mongoid::Document | 
					
						
							|  |  |  |       include ::Mongoid::Timestamps::CreatedInt | 
					
						
							|  |  |  |       include ::ActiveModel::Validations | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       store_in collection: "users" | 
					
						
							| 
									
										
										
										
											2015-03-06 12:20:30 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  |       ROOT_USER_NAME = 'root' | 
					
						
							| 
									
										
										
										
											2018-04-04 22:44:39 +03:00
										 |  |  |       ROOT_PASSWORD = 'super_user' | 
					
						
							|  |  |  |       USER_NAME_REGEX = /[\w-]+/ | 
					
						
							| 
									
										
										
										
											2014-05-08 15:34:26 +04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-04-04 22:44:39 +03:00
										 |  |  |       ALL_POLICIES_KEY = 'all' | 
					
						
							| 
									
										
										
										
											2015-10-06 13:50:26 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-04-04 22:44:39 +03:00
										 |  |  |       field :_id, as: :'id', overwrite: true, type: String | 
					
						
							|  |  |  |       field :password, type: String | 
					
						
							|  |  |  |       field :email, type: String | 
					
						
							|  |  |  |       field :roles, type: Array, default: ->{ [] } | 
					
						
							| 
									
										
										
										
											2014-05-08 15:34:26 +04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-04-04 22:44:39 +03:00
										 |  |  |       validates_presence_of :id, message: "'id' is undefined" | 
					
						
							|  |  |  |       validates_length_of :id, minimum: 1, maximum: 100
 | 
					
						
							|  |  |  |       validates_format_of :id, with: USER_NAME_REGEX, message: "invalid id, it should contains '_a-zA-Z0-9-.' symbols" | 
					
						
							|  |  |  |       validates_uniqueness_of :id, on: :create | 
					
						
							| 
									
										
										
										
											2014-05-08 15:34:26 +04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-04-04 22:44:39 +03:00
										 |  |  |       validates_presence_of :password, message: "'password' is undefined" | 
					
						
							|  |  |  |       validates_length_of :password, maximum: 31, minimum: 5
 | 
					
						
							| 
									
										
										
										
											2014-05-08 15:34:26 +04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-04-04 22:44:39 +03:00
										 |  |  |       validates_format_of :email, with: /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\z/i, message: "Invalid email" | 
					
						
							| 
									
										
										
										
											2014-05-08 15:34:26 +04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-04-04 22:44:39 +03:00
										 |  |  |       validate :validate_roles | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       def initialize hash | 
					
						
							|  |  |  |         raise InvalidRecord.new("Parameter 'id' is not a string") unless hash["id"].is_a?(String) | 
					
						
							|  |  |  |         raise InvalidRecord.new("Parameter 'password' is not a string") unless hash["password"].is_a?(String) | 
					
						
							|  |  |  |         raise InvalidRecord.new("Parameter 'email' is not a string") unless hash["email"].is_a?(String) | 
					
						
							|  |  |  |         raise InvalidRecord.new("Parameter 'roles' is not an array") unless hash["roles"].is_a?(Array) | 
					
						
							|  |  |  |         super(hash) | 
					
						
							| 
									
										
										
										
											2015-03-06 12:20:30 +03:00
										 |  |  |       end | 
					
						
							| 
									
										
										
										
											2014-05-08 15:34:26 +04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-04-04 22:44:39 +03:00
										 |  |  |       def validate_roles | 
					
						
							|  |  |  |         dbroles = Role.in({'_id' => self.roles}) | 
					
						
							|  |  |  |         dbroles = dbroles.map{|r| r.id} | 
					
						
							|  |  |  |         buf = self.roles - dbroles | 
					
						
							|  |  |  |         unless buf.empty? | 
					
						
							|  |  |  |           errors.add(:roles, "Invalid roles: #{buf.join(', ')}") | 
					
						
							| 
									
										
										
										
											2015-07-27 18:27:52 +03:00
										 |  |  |         end | 
					
						
							| 
									
										
										
										
											2015-03-06 12:20:30 +03:00
										 |  |  |       end | 
					
						
							| 
									
										
										
										
											2014-05-08 15:34:26 +04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-06 12:20:30 +03:00
										 |  |  |       def self.create_root | 
					
						
							| 
									
										
										
										
											2018-04-04 22:44:39 +03:00
										 |  |  |         unless Role.where(:id => Role::SUPER_USER_ROLE).exists? | 
					
						
							|  |  |  |           role = Role.new({'id' => Role::SUPER_USER_ROLE, 'name' => Role::SUPER_USER_ROLE, 'description' => "All policies", 'policies' => ['all']}) | 
					
						
							|  |  |  |           role.save! | 
					
						
							|  |  |  |           DevopsLogger.logger.info("Role '#{Role::SUPER_USER_ROLE}' has been created") | 
					
						
							|  |  |  |         end | 
					
						
							|  |  |  |         unless User.where(:id => ROOT_USER_NAME).exists? | 
					
						
							|  |  |  |           root = Devops::Model::User.new({'id' => ROOT_USER_NAME, 'password' => ROOT_PASSWORD, 'email' => "#{ROOT_USER_NAME}@host.ru", 'roles' => []}) | 
					
						
							|  |  |  |           root.save! | 
					
						
							|  |  |  |           DevopsLogger.logger.info("User '#{ROOT_USER_NAME}' has been created") | 
					
						
							|  |  |  |           root | 
					
						
							|  |  |  |         end | 
					
						
							| 
									
										
										
										
											2015-03-06 12:20:30 +03:00
										 |  |  |       end | 
					
						
							| 
									
										
										
										
											2014-05-08 15:34:26 +04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-04-04 22:44:39 +03:00
										 |  |  |       def self.auth login, password | 
					
						
							|  |  |  |         User.find_by({id: login, password: password}) | 
					
						
							|  |  |  |       rescue Mongoid::Errors::DocumentNotFound | 
					
						
							|  |  |  |         nil | 
					
						
							| 
									
										
										
										
											2015-07-16 17:18:55 +03:00
										 |  |  |       end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-04-04 22:44:39 +03:00
										 |  |  |       def to_hash | 
					
						
							|  |  |  |         hash = self.attributes | 
					
						
							|  |  |  |         hash.delete("password") | 
					
						
							|  |  |  |         hash["id"] = hash.delete("_id") | 
					
						
							|  |  |  |         hash | 
					
						
							|  |  |  |       end | 
					
						
							| 
									
										
										
										
											2015-03-06 12:20:30 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-04-04 22:44:39 +03:00
										 |  |  |       def check_policy policy | 
					
						
							|  |  |  |         return true if self.id == ROOT_USER_NAME | 
					
						
							|  |  |  |         policies = Set.new | 
					
						
							|  |  |  |         Devops::Model::Role.find(self.roles).each{|r| policies.merge(r.policies)} | 
					
						
							|  |  |  |         return true if policies.include?(ALL_POLICIES_KEY) | 
					
						
							|  |  |  |         raise Devops::Exception::Unauthorized.new("Access denied for user '#{self.id}'") unless policies.include?(policy.to_s) | 
					
						
							|  |  |  |         true | 
					
						
							|  |  |  |       rescue Mongoid::Errors::DocumentNotFound | 
					
						
							|  |  |  |         raise Devops::Exception::Unauthorized.new("Access denied for user '#{self.id}', no roles with policy '#{policy}' found") | 
					
						
							| 
									
										
										
										
											2015-03-06 12:20:30 +03:00
										 |  |  |       end | 
					
						
							| 
									
										
										
										
											2014-05-08 15:34:26 +04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-06 12:20:30 +03:00
										 |  |  |     end | 
					
						
							| 
									
										
										
										
											2014-05-08 15:34:26 +04:00
										 |  |  |   end | 
					
						
							|  |  |  | end |