-
Notifications
You must be signed in to change notification settings - Fork 433
/
group.rb
155 lines (129 loc) · 4.59 KB
/
group.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
require_dependency 'api_exception'
# The Group class represents a group record in the database and thus a group
# in the ActiveRbac model. Groups are arranged in trees and have a title.
# Groups have an arbitrary number of roles and users assigned to them.
#
class Group < ActiveRecord::Base
has_many :groups_users, inverse_of: :group, dependent: :destroy
has_many :group_maintainers, inverse_of: :group, dependent: :destroy
has_many :relationships, dependent: :destroy, inverse_of: :group
has_many :event_subscriptions, dependent: :destroy, inverse_of: :group
validates_format_of :title,
:with => %r{\A[\w\.\-]*\z},
:message => 'must not contain invalid characters.'
validates_length_of :title,
:in => 2..100, :allow_nil => true,
:too_long => 'must have less than 100 characters.',
:too_short => 'must have more than two characters.',
:allow_nil => false
# We want to validate a group's title pretty thoroughly.
validates_uniqueness_of :title,
:message => 'is the name of an already existing group.'
# groups have a n:m relation to user
has_and_belongs_to_many :users, -> { uniq }
# groups have a n:m relation to groups
has_and_belongs_to_many :roles, -> { uniq }
def self.find_by_title!(title)
find_by_title(title) or raise NotFoundError.new("Couldn't find Group '#{title}'")
end
def update_from_xml( xmlhash )
self.with_lock do
self.title = xmlhash.value('title')
if xmlhash.value('email')
self.email = xmlhash.value('email')
else
self.email = nil
end
end
self.save!
# update maintainer list
cache = Hash.new
self.group_maintainers.each do |gu|
cache[gu.user.id] = gu
end
xmlhash.elements('maintainer') do |maintainer|
next unless maintainer['userid']
user = User.find_by_login!(maintainer['userid'])
if cache.has_key? user.id
#user has already a role in this package
cache.delete(user.id)
else
GroupMaintainer.create( user: user, group: self).save
end
end
cache.each do |login_id, gu|
GroupMaintainer.delete_all(['user_id = ? AND group_id = ?', login_id, self.id])
end
# update user list
cache = Hash.new
self.groups_users.each do |gu|
cache[gu.user.id] = gu
end
persons = xmlhash.elements('person').first
if persons
persons.elements('person') do |person|
next unless person['userid']
user = User.find_by_login!(person['userid'])
if cache.has_key? user.id
#user has already a role in this package
cache.delete(user.id)
else
GroupsUser.create( user: user, group: self).save
end
end
end
#delete all users which were not listed
cache.each do |login_id, gu|
GroupsUser.delete_all(['user_id = ? AND group_id = ?', login_id, self.id])
end
end
def add_user(user)
return if self.users.find_by_id user.id # avoid double creation
gu = GroupsUser.create( user: user, group: self)
gu.save!
end
def remove_user(user)
GroupsUser.delete_all(['user_id = ? AND group_id = ?', user.id, self.id])
end
def set_email(email)
self.email = email
self.save!
end
def to_s
self.title
end
def to_param
to_s
end
def involved_projects_ids
# just for maintainer for now.
role = Role.rolecache['maintainer']
### all projects where user is maintainer
projects = Relationship.projects.where(group_id: id, role_id: role.id).pluck(:project_id)
projects.uniq
end
protected :involved_projects_ids
def involved_projects
# now filter the projects that are not visible
return Project.where(id: involved_projects_ids)
end
# lists packages maintained by this user and are not in maintained projects
def involved_packages
# just for maintainer for now.
role = Role.rolecache['maintainer']
projects = involved_projects_ids
projects << -1 if projects.empty?
# all packages where group is maintainer
packages = Relationship.where(group_id: id, role_id: role.id).joins(:package).where('packages.project_id not in (?)', projects).pluck(:package_id)
Package.where(id: packages).where.not(project_id: projects)
end
# returns the users that actually want email for this group's notifications
def email_users
User.where(id: groups_users.where(email: true).pluck(:user_id))
end
def display_name
address = Mail::Address.new self.email
address.display_name = self.title
address.format
end
end