-
Notifications
You must be signed in to change notification settings - Fork 161
Expand file tree
/
Copy pathuser.rb
More file actions
195 lines (157 loc) · 4.98 KB
/
user.rb
File metadata and controls
195 lines (157 loc) · 4.98 KB
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
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
require 'gh'
require 'travis/model'
require 'travis/github/oauth'
class User < Travis::Model
require 'travis/model/user/oauth'
require 'travis/model/user/renaming'
has_many :tokens, dependent: :destroy
has_many :memberships, dependent: :destroy
has_many :organizations, through: :memberships
has_many :permissions, dependent: :destroy
has_many :repositories, through: :permissions
has_many :emails, dependent: :destroy
before_create :set_as_recent
after_create :create_a_token
after_create :create_svg_token
before_save :track_previous_changes
serialize :github_scopes
serialize :github_oauth_token, Travis::Model::EncryptedColumn.new
class << self
def with_permissions(permissions)
where(:permissions => permissions).includes(:permissions)
end
def find_or_create_for_oauth(payload)
Oauth.find_or_create_by(payload)
end
def with_github_token
where("github_oauth_token IS NOT NULL and github_oauth_token != ''")
end
def with_email(email_address)
Email.where(email: email_address).first.try(:user)
end
end
def token
tokens.find { |t| t.try(:purpose_symbol) == :default}.try(:token)
end
def svg_token
token = tokens.find { |t| t.try(:purpose_symbol) == :svg} || create_svg_token
token.try(:token)
end
def default_tokens
self.tokens.select { |token| token.try(:purpose_symbol) == :default }
end
def to_json
keys = %w/id login email name locale github_id gravatar_id is_syncing synced_at updated_at created_at/
{ 'user' => attributes.slice(*keys) }.to_json
end
def permission?(roles, options = {})
roles, options = nil, roles if roles.is_a?(Hash)
scope = permissions.where(options)
scope = scope.by_roles(roles) if roles
scope.any?
end
def first_sync?
synced_at.nil?
end
def syncing?
is_syncing?
end
def service_hook(options = {})
service_hooks(options).first
end
def service_hooks(options = {})
hooks = repositories
unless options[:all]
hooks = hooks.administrable
end
hooks = hooks.includes(:permissions).
select('repositories.*, permissions.admin as admin, permissions.push as push')
if options[:order] != 'none'
hooks = hooks.order('owner_name, name')
end
# TODO remove owner_name/name once we're on api everywhere
if options.key?(:id)
hooks = hooks.where(options.slice(:id))
elsif options.key?(:owner_name) || options.key?(:name)
hooks = hooks.where(options.slice(:id, :owner_name, :name))
end
hooks
end
def organization_ids
@organization_ids ||= memberships.map(&:organization_id)
end
def repository_ids
@repository_ids ||= permissions.map(&:repository_id)
end
def recently_signed_up?
!!@recently_signed_up
end
def profile_image_hash
# TODO:
# If Github always sends valid gravatar_id in oauth payload (need to check that)
# then these fallbacks (email hash and zeros) are superfluous and can be removed.
gravatar_id.presence || (email? && Digest::MD5.hexdigest(email)) || '0' * 32
end
def github_scopes
github_oauth_token && read_attribute(:github_scopes) || []
end
# avatar_url calculation here is almost the same code that's used in
# Travis::API::V3::Renderer::AvatarURL. While generally I don't
# like repetition, it seems that copying it is the best choice in
# this specific situation. We need to add this field as a bug fix
# for travis-web, so I don't think that anyone else will be using
# it, especially with V3 in place and plans to retire V2. We won't
# likely need to do any maintenance here, because we plan to
# switch to V3 for /user request soon. And lastly, with plans to
# split V2 and V3 codebases I wouldn't like to share this code between V3 and
# V2
#
GRAVATAR_URL = 'https://0.gravatar.com/avatar/%s'
private_constant :GRAVATAR_URL
def avatar_url
if read_attribute(:avatar_url)
read_attribute(:avatar_url)
elsif gravatar_id
GRAVATAR_URL % gravatar_id
else
GRAVATAR_URL % Digest::MD5.hexdigest(email)
end
end
def subscribed?
subscription.present? and subscription.active?
end
def subscription
return @subscription if instance_variable_defined?(:@subscription)
records = Subscription.where(owner_id: id, owner_type: "User")
@subscription = records.where(status: 'subscribed').last || records.last
end
def _has
self.respond_to?(field) and self.send(field).present?
end
def previous_changes
@previous_changes ||= {}
end
def reload
@previous_changes = nil
super
end
def inspect
github_oauth_token ? super.gsub(github_oauth_token, '[REDACTED]') : super
end
def create_a_token(purpose = :default)
token = self.tokens.create!
token.purpose = purpose.to_s
token.save!
token
end
def create_svg_token
create_a_token(:svg)
end
protected
def track_previous_changes
@previous_changes = changes
end
def set_as_recent
@recently_signed_up = true
end
end