summaryrefslogtreecommitdiff
path: root/app/models/user.rb
diff options
context:
space:
mode:
Diffstat (limited to 'app/models/user.rb')
-rw-r--r--app/models/user.rb167
1 files changed, 163 insertions, 4 deletions
diff --git a/app/models/user.rb b/app/models/user.rb
index 1bc070f040d..55d75892fc4 100644
--- a/app/models/user.rb
+++ b/app/models/user.rb
@@ -34,8 +34,6 @@
#
class User < ActiveRecord::Base
- include Account
-
devise :database_authenticatable, :token_authenticatable, :lockable,
:recoverable, :rememberable, :trackable, :validatable, :omniauthable
@@ -51,7 +49,6 @@ class User < ActiveRecord::Base
has_many :groups, class_name: "Group", foreign_key: :owner_id
has_many :keys, dependent: :destroy
- has_many :projects, through: :users_projects
has_many :users_projects, dependent: :destroy
has_many :issues, foreign_key: :author_id, dependent: :destroy
has_many :notes, foreign_key: :author_id, dependent: :destroy
@@ -70,6 +67,8 @@ class User < ActiveRecord::Base
message: "only letters, digits & '_' '-' '.' allowed. Letter should be first" }
+ validate :namespace_uniq, if: ->(user) { user.username_changed? }
+
before_validation :generate_password, on: :create
before_save :ensure_authentication_token
alias_attribute :private_token, :authentication_token
@@ -77,11 +76,14 @@ class User < ActiveRecord::Base
delegate :path, to: :namespace, allow_nil: true, prefix: true
# Scopes
- scope :not_in_project, ->(project) { where("id not in (:ids)", ids: project.users.map(&:id) ) }
scope :admins, where(admin: true)
scope :blocked, where(blocked: true)
scope :active, where(blocked: false)
+ scope :alphabetically, order('name ASC')
+ #
+ # Class methods
+ #
class << self
def filter filter_name
case filter_name
@@ -93,6 +95,14 @@ class User < ActiveRecord::Base
end
end
+ def not_in_project(project)
+ if project.users.present?
+ where("id not in (:ids)", ids: project.users.map(&:id) )
+ else
+ scoped
+ end
+ end
+
def without_projects
where('id NOT IN (SELECT DISTINCT(user_id) FROM users_projects)')
end
@@ -118,9 +128,158 @@ class User < ActiveRecord::Base
end
end
+ #
+ # Instance methods
+ #
def generate_password
if self.force_random_password
self.password = self.password_confirmation = Devise.friendly_token.first(8)
end
end
+
+ def namespace_uniq
+ namespace_name = self.username
+ if Namespace.find_by_path(namespace_name)
+ self.errors.add :username, "already exist"
+ end
+ end
+
+ # Namespaces user has access to
+ def namespaces
+ namespaces = []
+
+ # Add user account namespace
+ namespaces << self.namespace if self.namespace
+
+ # Add groups you can manage
+ namespaces += if admin
+ Group.all
+ else
+ groups.all
+ end
+ namespaces
+ end
+
+ # Groups where user is an owner
+ def owned_groups
+ groups
+ end
+
+ # Groups user has access to
+ def authorized_groups
+ @authorized_groups ||= begin
+ groups = Group.where(id: self.authorized_projects.pluck(:namespace_id)).all
+ groups = groups + self.groups
+ groups.uniq
+ end
+ end
+
+
+ # Projects user has access to
+ def authorized_projects
+ project_ids = users_projects.pluck(:project_id)
+ project_ids = project_ids | owned_projects.pluck(:id)
+ Project.where(id: project_ids)
+ end
+
+ # Projects in user namespace
+ def personal_projects
+ Project.personal(self)
+ end
+
+ # Projects where user is an owner
+ def owned_projects
+ Project.where("(projects.namespace_id IN (:namespaces)) OR
+ (projects.namespace_id IS NULL AND projects.creator_id = :user_id)",
+ namespaces: namespaces.map(&:id), user_id: self.id)
+ end
+
+ # Team membership in personal projects
+ def tm_in_personal_projects
+ UsersProject.where(project_id: personal_projects.map(&:id), user_id: self.id)
+ end
+
+ # Returns a string for use as a Gitolite user identifier
+ #
+ # Note that Gitolite 2.x requires the following pattern for users:
+ #
+ # ^@?[0-9a-zA-Z][0-9a-zA-Z._\@+-]*$
+ def identifier
+ # Replace non-word chars with underscores, then make sure it starts with
+ # valid chars
+ email.gsub(/\W/, '_').gsub(/\A([\W\_])+/, '')
+ end
+
+ def is_admin?
+ admin
+ end
+
+ def require_ssh_key?
+ keys.count == 0
+ end
+
+ def can_create_project?
+ projects_limit > personal_projects.count
+ end
+
+ def can_create_group?
+ is_admin?
+ end
+
+ def abilities
+ @abilities ||= begin
+ abilities = Six.new
+ abilities << Ability
+ abilities
+ end
+ end
+
+ def can? action, subject
+ abilities.allowed?(self, action, subject)
+ end
+
+ def first_name
+ name.split.first unless name.blank?
+ end
+
+ def cared_merge_requests
+ MergeRequest.where("author_id = :id or assignee_id = :id", id: self.id)
+ end
+
+ # Remove user from all projects and
+ # set blocked attribute to true
+ def block
+ users_projects.find_each do |membership|
+ return false unless membership.destroy
+ end
+
+ self.blocked = true
+ save
+ end
+
+ def projects_limit_percent
+ return 100 if projects_limit.zero?
+ (personal_projects.count.to_f / projects_limit) * 100
+ end
+
+ def recent_push project_id = nil
+ # Get push events not earlier than 2 hours ago
+ events = recent_events.code_push.where("created_at > ?", Time.now - 2.hours)
+ events = events.where(project_id: project_id) if project_id
+
+ # Take only latest one
+ events = events.recent.limit(1).first
+ end
+
+ def projects_sorted_by_activity
+ authorized_projects.sorted_by_activity
+ end
+
+ def several_namespaces?
+ namespaces.size > 1
+ end
+
+ def namespace_id
+ namespace.try :id
+ end
end