require "exceptions/invalid_record" require "exceptions/invalid_command" require "exceptions/invalid_privileges" require "db/mongo/models/mongo_model" module Devops module Model class User < MongoModel ROOT_USER_NAME = 'root' ROOT_PASSWORD = '' PRIVILEGES = ["r", "w", "x"] PRIVILEGES_REGEX = /^r?w?x?$/ KNOWN_ENTITIES = %w(flavor group image project server key user filter network provider script templates stack_template stack) set_field_validators :id, ::Validators::FieldValidator::NotNil, ::Validators::FieldValidator::FieldType::String, ::Validators::FieldValidator::Name set_field_validators :password, ::Validators::FieldValidator::NotNil, ::Validators::FieldValidator::FieldType::String set_field_validators :email, ::Validators::FieldValidator::NotNil, ::Validators::FieldValidator::FieldType::String set_field_validators :privileges, ::Validators::FieldValidator::NotNil, ::Validators::FieldValidator::FieldType::Hash def initialize p={} self.id = p['username'] self.email = p['email'] self.password = p['password'] self.privileges = p["privileges"] || self.default_privileges end def validate! validate_id! validate_password! validate_email! validate_privileges! end def all_privileges privileges_with_value("rwx") end def default_privileges privileges_with_value("r", "user" => "") end def grant cmd, priv='' priv='' if priv.nil? cmd='' if cmd.nil? if !priv.empty? and PRIVILEGES_REGEX.match(priv).to_s.empty? raise InvalidCommand.new "Invalid privileges '#{priv}'. Available values are '#{PRIVILEGES.join("', '")}'" end raise ::InvalidPrivileges.new "Can't grant privileges to root" if self.id == ROOT_USER_NAME case cmd when "all" self.privileges.each_key do |key| self.privileges[key] = priv end when "" self.privileges = self.default_privileges else raise InvalidCommand.new "Unsupported command '#{cmd}'" unless self.all_privileges.include?(cmd) self.privileges[cmd] = priv end end def self.build_from_bson s user = User.new s user.id = s["_id"] user end def self.create_from_json json User.new( JSON.parse(json) ) end def to_hash_without_id o = { "email" => self.email, "password" => self.password, "privileges" => self.privileges } o end def check_privileges cmd, required_privelege unless PRIVILEGES.include?(required_privelege) raise InvalidPrivileges.new("Access internal problem with privilege '#{required_privelege}'") end # can?(cmd, required_privelege) unless can?(cmd, required_privelege) raise InvalidPrivileges.new("Access denied for '#{id}'") end end def self.create_root root = User.new({'username' => ROOT_USER_NAME, 'password' => ROOT_PASSWORD}) root.privileges = root.all_privileges root.email = "#{ROOT_USER_NAME}@host" root end private def can?(command, privilege) p = self.privileges[command] || [] p.include?(privilege) end def privileges_with_value value, options={} privileges = {} KNOWN_ENTITIES.each { |t| privileges.store(t, value) } privileges.merge(options) end end end end