2012-11-19 13:24:05 -05:00
|
|
|
# == Schema Information
|
|
|
|
#
|
|
|
|
# Table name: users
|
|
|
|
#
|
|
|
|
# id :integer not null, primary key
|
|
|
|
# email :string(255) default(""), not null
|
2013-08-21 05:34:02 -04:00
|
|
|
# encrypted_password :string(255) default(""), not null
|
2012-11-19 13:24:05 -05:00
|
|
|
# reset_password_token :string(255)
|
|
|
|
# reset_password_sent_at :datetime
|
|
|
|
# remember_created_at :datetime
|
|
|
|
# sign_in_count :integer default(0)
|
|
|
|
# current_sign_in_at :datetime
|
|
|
|
# last_sign_in_at :datetime
|
|
|
|
# current_sign_in_ip :string(255)
|
|
|
|
# last_sign_in_ip :string(255)
|
2013-08-21 05:34:02 -04:00
|
|
|
# created_at :datetime not null
|
|
|
|
# updated_at :datetime not null
|
2012-11-19 13:24:05 -05:00
|
|
|
# name :string(255)
|
|
|
|
# admin :boolean default(FALSE), not null
|
|
|
|
# projects_limit :integer default(10)
|
|
|
|
# skype :string(255) default(""), not null
|
|
|
|
# linkedin :string(255) default(""), not null
|
|
|
|
# twitter :string(255) default(""), not null
|
|
|
|
# authentication_token :string(255)
|
|
|
|
# theme_id :integer default(1), not null
|
|
|
|
# bio :string(255)
|
|
|
|
# failed_attempts :integer default(0)
|
|
|
|
# locked_at :datetime
|
|
|
|
# extern_uid :string(255)
|
|
|
|
# provider :string(255)
|
2012-11-24 15:16:51 -05:00
|
|
|
# username :string(255)
|
2013-01-31 02:11:35 -05:00
|
|
|
# can_create_group :boolean default(TRUE), not null
|
|
|
|
# can_create_team :boolean default(TRUE), not null
|
2013-03-15 09:16:02 -04:00
|
|
|
# state :string(255)
|
|
|
|
# color_scheme_id :integer default(1), not null
|
2013-03-27 12:26:37 -04:00
|
|
|
# notification_level :integer default(1), not null
|
2013-06-19 08:40:33 -04:00
|
|
|
# password_expires_at :datetime
|
|
|
|
# created_by_id :integer
|
2013-11-13 07:10:03 -05:00
|
|
|
# avatar :string(255)
|
|
|
|
# confirmation_token :string(255)
|
|
|
|
# confirmed_at :datetime
|
|
|
|
# confirmation_sent_at :datetime
|
|
|
|
# unconfirmed_email :string(255)
|
2013-12-14 20:28:17 -05:00
|
|
|
# hide_no_ssh_key :boolean default(FALSE), not null
|
2012-11-19 13:24:05 -05:00
|
|
|
#
|
|
|
|
|
2013-10-06 14:13:56 -04:00
|
|
|
require 'carrierwave/orm/activerecord'
|
|
|
|
require 'file_size_validator'
|
|
|
|
|
2011-10-08 17:36:38 -04:00
|
|
|
class User < ActiveRecord::Base
|
2013-10-09 08:25:31 -04:00
|
|
|
devise :database_authenticatable, :token_authenticatable, :lockable, :async,
|
2013-10-09 08:26:30 -04:00
|
|
|
:recoverable, :rememberable, :trackable, :validatable, :omniauthable, :confirmable, :registerable
|
2011-10-08 17:36:38 -04:00
|
|
|
|
2012-11-22 23:11:09 -05:00
|
|
|
attr_accessible :email, :password, :password_confirmation, :remember_me, :bio, :name, :username,
|
2013-03-15 09:09:34 -04:00
|
|
|
:skype, :linkedin, :twitter, :color_scheme_id, :theme_id, :force_random_password,
|
2013-12-14 20:28:17 -05:00
|
|
|
:extern_uid, :provider, :password_expires_at, :avatar, :hide_no_ssh_key,
|
2013-06-13 13:06:33 -04:00
|
|
|
as: [:default, :admin]
|
|
|
|
|
2013-08-21 05:31:47 -04:00
|
|
|
attr_accessible :projects_limit, :can_create_group,
|
2013-06-13 13:06:33 -04:00
|
|
|
as: :admin
|
2012-06-26 17:59:08 -04:00
|
|
|
|
|
|
|
attr_accessor :force_random_password
|
2011-10-08 17:36:38 -04:00
|
|
|
|
2013-03-25 10:10:14 -04:00
|
|
|
# Virtual attribute for authenticating by either username or email
|
|
|
|
attr_accessor :login
|
|
|
|
|
|
|
|
# Add login to attr_accessible
|
|
|
|
attr_accessible :login
|
|
|
|
|
|
|
|
|
2013-03-05 02:27:06 -05:00
|
|
|
#
|
|
|
|
# Relations
|
|
|
|
#
|
|
|
|
|
2012-11-22 23:11:09 -05:00
|
|
|
# Namespace for personal projects
|
2013-12-09 14:02:36 -05:00
|
|
|
has_one :namespace, -> { where type: nil }, dependent: :destroy, foreign_key: :owner_id, class_name: "Namespace"
|
2013-04-02 18:28:12 -04:00
|
|
|
|
2013-03-05 02:27:06 -05:00
|
|
|
# Profile
|
|
|
|
has_many :keys, dependent: :destroy
|
|
|
|
|
|
|
|
# Groups
|
2013-06-17 12:59:41 -04:00
|
|
|
has_many :users_groups, dependent: :destroy
|
|
|
|
has_many :groups, through: :users_groups
|
2013-12-09 16:17:03 -05:00
|
|
|
has_many :owned_groups, -> { where users_groups: { group_access: UsersGroup::OWNER } }, through: :users_groups, source: :group
|
2013-03-05 02:27:06 -05:00
|
|
|
# Projects
|
2013-11-05 09:58:13 -05:00
|
|
|
has_many :groups_projects, through: :groups, source: :projects
|
|
|
|
has_many :personal_projects, through: :namespace, source: :projects
|
|
|
|
has_many :projects, through: :users_projects
|
|
|
|
has_many :created_projects, foreign_key: :creator_id, class_name: 'Project'
|
|
|
|
|
2013-03-24 15:09:59 -04:00
|
|
|
has_many :snippets, dependent: :destroy, foreign_key: :author_id, class_name: "Snippet"
|
2013-01-19 12:06:50 -05:00
|
|
|
has_many :users_projects, dependent: :destroy
|
|
|
|
has_many :issues, dependent: :destroy, foreign_key: :author_id
|
|
|
|
has_many :notes, dependent: :destroy, foreign_key: :author_id
|
|
|
|
has_many :merge_requests, dependent: :destroy, foreign_key: :author_id
|
|
|
|
has_many :events, dependent: :destroy, foreign_key: :author_id, class_name: "Event"
|
2013-12-09 14:02:36 -05:00
|
|
|
has_many :recent_events, -> { order "id DESC" }, foreign_key: :author_id, class_name: "Event"
|
2013-01-19 12:06:50 -05:00
|
|
|
has_many :assigned_issues, dependent: :destroy, foreign_key: :assignee_id, class_name: "Issue"
|
|
|
|
has_many :assigned_merge_requests, dependent: :destroy, foreign_key: :assignee_id, class_name: "MergeRequest"
|
|
|
|
|
2012-04-24 03:42:30 -04:00
|
|
|
|
2013-03-05 02:27:06 -05:00
|
|
|
#
|
|
|
|
# Validations
|
|
|
|
#
|
2012-12-12 11:53:43 -05:00
|
|
|
validates :name, presence: true
|
2013-02-26 04:09:32 -05:00
|
|
|
validates :email, presence: true, format: { with: /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\Z/ }
|
2013-12-06 10:05:34 -05:00
|
|
|
validates :bio, length: { maximum: 255 }, allow_blank: true
|
2012-11-27 22:14:05 -05:00
|
|
|
validates :extern_uid, allow_blank: true, uniqueness: {scope: :provider}
|
2012-09-27 02:20:36 -04:00
|
|
|
validates :projects_limit, presence: true, numericality: {greater_than_or_equal_to: 0}
|
2012-11-27 22:14:05 -05:00
|
|
|
validates :username, presence: true, uniqueness: true,
|
2013-06-12 15:11:35 -04:00
|
|
|
exclusion: { in: Gitlab::Blacklist.path },
|
2012-11-27 22:14:05 -05:00
|
|
|
format: { with: Gitlab::Regex.username_regex,
|
|
|
|
message: "only letters, digits & '_' '-' '.' allowed. Letter should be first" }
|
|
|
|
|
2013-04-02 18:28:12 -04:00
|
|
|
validates :notification_level, inclusion: { in: Notification.notification_levels }, presence: true
|
2013-01-07 10:36:24 -05:00
|
|
|
validate :namespace_uniq, if: ->(user) { user.username_changed? }
|
2013-12-23 13:28:59 -05:00
|
|
|
validate :avatar_type, if: ->(user) { user.avatar_changed? }
|
2013-10-06 14:13:56 -04:00
|
|
|
validates :avatar, file_size: { maximum: 100.kilobytes.to_i }
|
|
|
|
|
2012-08-10 18:07:50 -04:00
|
|
|
before_validation :generate_password, on: :create
|
2013-07-10 06:48:03 -04:00
|
|
|
before_validation :sanitize_attrs
|
|
|
|
|
2012-09-27 02:20:36 -04:00
|
|
|
before_save :ensure_authentication_token
|
2013-07-10 06:48:03 -04:00
|
|
|
|
2012-09-27 02:20:36 -04:00
|
|
|
alias_attribute :private_token, :authentication_token
|
2012-06-24 16:26:13 -04:00
|
|
|
|
2012-11-23 13:11:09 -05:00
|
|
|
delegate :path, to: :namespace, allow_nil: true, prefix: true
|
2012-11-23 01:11:09 -05:00
|
|
|
|
2013-03-04 09:52:30 -05:00
|
|
|
state_machine :state, initial: :active do
|
|
|
|
after_transition any => :blocked do |user, transition|
|
|
|
|
# Remove user from all projects and
|
|
|
|
user.users_projects.find_each do |membership|
|
2013-08-27 05:01:45 -04:00
|
|
|
# skip owned resources
|
|
|
|
next if membership.project.owner == user
|
|
|
|
|
|
|
|
return false unless membership.destroy
|
|
|
|
end
|
|
|
|
|
|
|
|
# Remove user from all groups
|
|
|
|
user.users_groups.find_each do |membership|
|
|
|
|
# skip owned resources
|
2013-09-26 07:49:22 -04:00
|
|
|
next if membership.group.last_owner?(user)
|
2013-08-27 05:01:45 -04:00
|
|
|
|
2013-03-04 09:52:30 -05:00
|
|
|
return false unless membership.destroy
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
event :block do
|
|
|
|
transition active: :blocked
|
|
|
|
end
|
|
|
|
|
|
|
|
event :activate do
|
|
|
|
transition blocked: :active
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2013-10-06 14:13:56 -04:00
|
|
|
mount_uploader :avatar, AttachmentUploader
|
|
|
|
|
2012-10-08 20:10:04 -04:00
|
|
|
# Scopes
|
2013-02-12 02:16:45 -05:00
|
|
|
scope :admins, -> { where(admin: true) }
|
2013-03-04 09:52:30 -05:00
|
|
|
scope :blocked, -> { with_state(:blocked) }
|
|
|
|
scope :active, -> { with_state(:active) }
|
2013-02-12 02:16:45 -05:00
|
|
|
scope :alphabetically, -> { order('name ASC') }
|
2013-01-19 12:06:50 -05:00
|
|
|
scope :in_team, ->(team){ where(id: team.member_ids) }
|
|
|
|
scope :not_in_team, ->(team){ where('users.id NOT IN (:ids)', ids: team.member_ids) }
|
2013-12-14 08:43:48 -05:00
|
|
|
scope :not_in_project, ->(project) { project.users.present? ? where("id not in (:ids)", ids: project.users.map(&:id) ) : all }
|
2013-04-02 18:28:12 -04:00
|
|
|
scope :without_projects, -> { where('id NOT IN (SELECT DISTINCT(user_id) FROM users_projects)') }
|
2013-09-02 16:35:40 -04:00
|
|
|
scope :ldap, -> { where(provider: 'ldap') }
|
2013-04-02 18:28:12 -04:00
|
|
|
|
2013-01-25 08:36:10 -05:00
|
|
|
scope :potential_team_members, ->(team) { team.members.any? ? active.not_in_team(team) : active }
|
2012-10-08 20:10:04 -04:00
|
|
|
|
2013-01-02 12:00:00 -05:00
|
|
|
#
|
|
|
|
# Class methods
|
|
|
|
#
|
2012-10-08 20:10:04 -04:00
|
|
|
class << self
|
2013-10-03 05:04:51 -04:00
|
|
|
# Devise method overridden to allow sign in with email or username
|
2013-03-25 10:10:14 -04:00
|
|
|
def find_for_database_authentication(warden_conditions)
|
|
|
|
conditions = warden_conditions.dup
|
|
|
|
if login = conditions.delete(:login)
|
|
|
|
where(conditions).where(["lower(username) = :value OR lower(email) = :value", { value: login.downcase }]).first
|
|
|
|
else
|
|
|
|
where(conditions).first
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2012-10-08 20:10:04 -04:00
|
|
|
def filter filter_name
|
|
|
|
case filter_name
|
|
|
|
when "admins"; self.admins
|
|
|
|
when "blocked"; self.blocked
|
|
|
|
when "wop"; self.without_projects
|
|
|
|
else
|
|
|
|
self.active
|
|
|
|
end
|
2012-06-24 16:26:13 -04:00
|
|
|
end
|
|
|
|
|
2012-10-08 20:10:04 -04:00
|
|
|
def search query
|
2013-02-13 10:28:28 -05:00
|
|
|
where("name LIKE :query OR email LIKE :query OR username LIKE :query", query: "%#{query}%")
|
2012-10-08 20:10:04 -04:00
|
|
|
end
|
2013-06-28 08:59:05 -04:00
|
|
|
|
|
|
|
def by_username_or_id(name_or_id)
|
2013-12-10 06:20:35 -05:00
|
|
|
where('users.username = ? OR users.id = ?', name_or_id, name_or_id.to_i).first
|
2013-06-28 08:59:05 -04:00
|
|
|
end
|
2013-08-08 14:09:33 -04:00
|
|
|
|
2013-08-15 17:43:46 -04:00
|
|
|
def build_user(attrs = {}, options= {})
|
2013-09-14 13:51:16 -04:00
|
|
|
if options[:as] == :admin
|
|
|
|
User.new(defaults.merge(attrs.symbolize_keys), options)
|
|
|
|
else
|
|
|
|
User.new(attrs, options).with_defaults
|
|
|
|
end
|
2013-08-08 14:09:33 -04:00
|
|
|
end
|
|
|
|
|
2013-08-15 17:43:46 -04:00
|
|
|
def defaults
|
2013-09-11 12:23:04 -04:00
|
|
|
{
|
|
|
|
projects_limit: Gitlab.config.gitlab.default_projects_limit,
|
|
|
|
can_create_group: Gitlab.config.gitlab.default_can_create_group,
|
2013-09-16 13:31:22 -04:00
|
|
|
theme_id: Gitlab.config.gitlab.default_theme
|
2013-09-11 12:23:04 -04:00
|
|
|
}
|
2013-08-15 17:43:46 -04:00
|
|
|
end
|
2012-01-28 08:23:17 -05:00
|
|
|
end
|
2012-06-21 12:05:09 -04:00
|
|
|
|
2013-01-02 12:00:00 -05:00
|
|
|
#
|
|
|
|
# Instance methods
|
|
|
|
#
|
2013-01-25 13:35:58 -05:00
|
|
|
|
|
|
|
def to_param
|
|
|
|
username
|
|
|
|
end
|
|
|
|
|
2013-03-27 13:04:29 -04:00
|
|
|
def notification
|
|
|
|
@notification ||= Notification.new(self)
|
|
|
|
end
|
|
|
|
|
2012-10-08 20:10:04 -04:00
|
|
|
def generate_password
|
|
|
|
if self.force_random_password
|
|
|
|
self.password = self.password_confirmation = Devise.friendly_token.first(8)
|
|
|
|
end
|
2012-06-21 12:05:09 -04:00
|
|
|
end
|
2013-01-02 12:00:00 -05:00
|
|
|
|
2013-01-07 10:36:24 -05:00
|
|
|
def namespace_uniq
|
|
|
|
namespace_name = self.username
|
|
|
|
if Namespace.find_by_path(namespace_name)
|
|
|
|
self.errors.add :username, "already exist"
|
|
|
|
end
|
|
|
|
end
|
2013-01-02 12:00:00 -05:00
|
|
|
|
2013-12-23 13:28:59 -05:00
|
|
|
def avatar_type
|
|
|
|
unless self.avatar.image?
|
|
|
|
self.errors.add :avatar, "only images allowed"
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2013-01-02 12:00:00 -05:00
|
|
|
# Groups user has access to
|
|
|
|
def authorized_groups
|
2013-06-21 09:36:28 -04:00
|
|
|
@authorized_groups ||= begin
|
2013-11-05 09:58:13 -05:00
|
|
|
group_ids = (groups.pluck(:id) + authorized_projects.pluck(:namespace_id))
|
2013-06-22 06:39:34 -04:00
|
|
|
Group.where(id: group_ids).order('namespaces.name ASC')
|
2013-06-21 09:36:28 -04:00
|
|
|
end
|
2013-01-02 12:00:00 -05:00
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
# Projects user has access to
|
|
|
|
def authorized_projects
|
2013-06-21 09:36:28 -04:00
|
|
|
@authorized_projects ||= begin
|
2013-11-05 09:58:13 -05:00
|
|
|
project_ids = (personal_projects.pluck(:id) + groups_projects.pluck(:id) + projects.pluck(:id)).uniq
|
2013-06-22 06:39:34 -04:00
|
|
|
Project.where(id: project_ids).joins(:namespace).order('namespaces.name ASC')
|
2013-06-21 09:36:28 -04:00
|
|
|
end
|
2013-01-02 12:00:00 -05:00
|
|
|
end
|
|
|
|
|
2013-11-05 10:15:43 -05:00
|
|
|
def owned_projects
|
|
|
|
@owned_projects ||= begin
|
|
|
|
Project.where(namespace_id: owned_groups.pluck(:id).push(namespace.id)).joins(:namespace)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2013-01-21 07:16:48 -05:00
|
|
|
# Team membership in authorized projects
|
|
|
|
def tm_in_authorized_projects
|
2013-04-02 18:28:12 -04:00
|
|
|
UsersProject.where(project_id: authorized_projects.map(&:id), user_id: self.id)
|
2013-01-02 12:32:34 -05:00
|
|
|
end
|
2013-01-02 16:35:11 -05:00
|
|
|
|
|
|
|
def is_admin?
|
|
|
|
admin
|
|
|
|
end
|
|
|
|
|
|
|
|
def require_ssh_key?
|
|
|
|
keys.count == 0
|
|
|
|
end
|
|
|
|
|
2013-01-30 15:14:34 -05:00
|
|
|
def can_change_username?
|
|
|
|
Gitlab.config.gitlab.username_changing_enabled
|
|
|
|
end
|
|
|
|
|
2013-01-02 16:35:11 -05:00
|
|
|
def can_create_project?
|
2013-07-09 13:51:49 -04:00
|
|
|
projects_limit_left > 0
|
2013-01-02 16:35:11 -05:00
|
|
|
end
|
|
|
|
|
|
|
|
def can_create_group?
|
2013-01-25 04:30:49 -05:00
|
|
|
can?(:create_group, nil)
|
2013-01-02 16:35:11 -05:00
|
|
|
end
|
|
|
|
|
|
|
|
def abilities
|
|
|
|
@abilities ||= begin
|
|
|
|
abilities = Six.new
|
|
|
|
abilities << Ability
|
|
|
|
abilities
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2013-01-17 10:35:57 -05:00
|
|
|
def can_select_namespace?
|
|
|
|
several_namespaces? || admin
|
|
|
|
end
|
|
|
|
|
2013-01-02 16:35:11 -05:00
|
|
|
def can? action, subject
|
|
|
|
abilities.allowed?(self, action, subject)
|
|
|
|
end
|
|
|
|
|
|
|
|
def first_name
|
|
|
|
name.split.first unless name.blank?
|
|
|
|
end
|
|
|
|
|
|
|
|
def cared_merge_requests
|
2013-02-19 02:43:41 -05:00
|
|
|
MergeRequest.cared(self)
|
2013-01-02 16:35:11 -05:00
|
|
|
end
|
|
|
|
|
2013-04-03 11:36:37 -04:00
|
|
|
def projects_limit_left
|
2013-06-26 07:41:03 -04:00
|
|
|
projects_limit - personal_projects.count
|
2013-04-03 11:36:37 -04:00
|
|
|
end
|
|
|
|
|
2013-01-02 16:35:11 -05:00
|
|
|
def projects_limit_percent
|
|
|
|
return 100 if projects_limit.zero?
|
2013-06-26 07:41:03 -04:00
|
|
|
(personal_projects.count.to_f / projects_limit) * 100
|
2013-01-02 16:35:11 -05:00
|
|
|
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?
|
2013-11-05 10:15:43 -05:00
|
|
|
owned_groups.any?
|
2013-01-02 16:35:11 -05:00
|
|
|
end
|
|
|
|
|
|
|
|
def namespace_id
|
|
|
|
namespace.try :id
|
|
|
|
end
|
2013-01-25 08:51:45 -05:00
|
|
|
|
2013-03-13 13:24:30 -04:00
|
|
|
def name_with_username
|
|
|
|
"#{name} (#{username})"
|
|
|
|
end
|
2013-04-04 03:53:39 -04:00
|
|
|
|
|
|
|
def tm_of(project)
|
|
|
|
project.team_member_by_id(self.id)
|
|
|
|
end
|
2013-05-08 12:40:31 -04:00
|
|
|
|
|
|
|
def already_forked? project
|
|
|
|
!!fork_of(project)
|
|
|
|
end
|
|
|
|
|
|
|
|
def fork_of project
|
|
|
|
links = ForkedProjectLink.where(forked_from_project_id: project, forked_to_project_id: personal_projects)
|
|
|
|
|
|
|
|
if links.any?
|
|
|
|
links.first.forked_to_project
|
|
|
|
else
|
|
|
|
nil
|
|
|
|
end
|
|
|
|
end
|
2013-05-24 10:12:27 -04:00
|
|
|
|
|
|
|
def ldap_user?
|
|
|
|
extern_uid && provider == 'ldap'
|
|
|
|
end
|
2013-06-03 12:49:04 -04:00
|
|
|
|
2013-06-04 10:50:51 -04:00
|
|
|
def accessible_deploy_keys
|
2013-12-06 11:20:17 -05:00
|
|
|
DeployKey.in_projects(self.authorized_projects.pluck(:id)).uniq
|
2013-06-03 12:49:04 -04:00
|
|
|
end
|
2013-06-13 14:06:27 -04:00
|
|
|
|
|
|
|
def created_by
|
|
|
|
User.find_by_id(created_by_id) if created_by_id
|
|
|
|
end
|
2013-07-10 06:48:03 -04:00
|
|
|
|
|
|
|
def sanitize_attrs
|
|
|
|
%w(name username skype linkedin twitter bio).each do |attr|
|
|
|
|
value = self.send(attr)
|
|
|
|
self.send("#{attr}=", Sanitize.clean(value)) if value.present?
|
|
|
|
end
|
|
|
|
end
|
2013-08-27 13:40:42 -04:00
|
|
|
|
|
|
|
def solo_owned_groups
|
|
|
|
@solo_owned_groups ||= owned_groups.select do |group|
|
|
|
|
group.owners == [self]
|
|
|
|
end
|
|
|
|
end
|
2013-08-15 17:43:46 -04:00
|
|
|
|
|
|
|
def with_defaults
|
2013-09-14 13:51:16 -04:00
|
|
|
User.defaults.each do |k, v|
|
|
|
|
self.send("#{k}=", v)
|
2013-08-15 17:43:46 -04:00
|
|
|
end
|
2013-09-14 13:51:16 -04:00
|
|
|
|
|
|
|
self
|
2013-08-15 17:43:46 -04:00
|
|
|
end
|
2013-11-05 09:41:29 -05:00
|
|
|
|
|
|
|
def can_leave_project?(project)
|
|
|
|
project.namespace != namespace &&
|
|
|
|
project.project_member(self)
|
|
|
|
end
|
2013-12-11 10:30:22 -05:00
|
|
|
|
|
|
|
# Reset project events cache related to this user
|
|
|
|
#
|
|
|
|
# Since we do cache @event we need to reset cache in special cases:
|
|
|
|
# * when the user changes their avatar
|
|
|
|
# Events cache stored like events/23-20130109142513.
|
|
|
|
# The cache key includes updated_at timestamp.
|
|
|
|
# Thus it will automatically generate a new fragment
|
|
|
|
# when the event is updated because the key changes.
|
|
|
|
def reset_events_cache
|
|
|
|
Event.where(author_id: self.id).
|
|
|
|
order('id DESC').limit(1000).
|
|
|
|
update_all(updated_at: Time.now)
|
|
|
|
end
|
2013-10-09 08:26:30 -04:00
|
|
|
end
|