-
-
Notifications
You must be signed in to change notification settings - Fork 95
/
Copy pathuser.rb
147 lines (118 loc) · 4.48 KB
/
user.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
# frozen_string_literal: true
class User < ApplicationRecord # rubocop:disable Metrics/ClassLength
include Slug
extend ApiHandling
slugged_by(:nickname)
expose_api :id, :nickname, :name, :image, :url, :github, :twitter, :freelancer, :available
validates :nickname, :name, :image, presence: true
validates :nickname, uniqueness: true
validates :twitter, :github, uniqueness: true, allow_blank: true
validates :twitter, :github, format: { with: /\A(\w|-)+\z/, allow_blank: true }
has_many :authorizations, dependent: :destroy
has_many :participants, -> { order('created_at DESC') }, dependent: :destroy
has_many :materials, -> { order('created_at DESC') }, dependent: :destroy
has_many :topics, -> { order('created_at DESC') }, dependent: :destroy
has_many :likes, -> { order('created_at DESC') }, dependent: :destroy
has_many :participations, through: :participants, source: :event
has_many :liked_topics, through: :likes, source: :topic
has_many :events, -> { order('created_at DESC') }, dependent: :nullify
scope :organizers, -> { where(nickname: Whitelabel[:organizers]) }
scope :ordered, -> { order('updated_at DESC') }
scope :peers, -> { ordered.joins(participants: :event).where('events.label' => Whitelabel[:label_id]).distinct }
scope :main, -> { where(nickname: Whitelabel[:twitter]) }
scope :random, -> { self }
def participates?(event)
participants.any? { |participant| participant.event_id == event.id }
end
def participation(event)
participants.where(event_id: event.id).first
end
def url
return unless url = self[:url]
url =~ %r{\Ahttps?://.+} ? url : "http://#{url}"
end
def salt
authorizations.first.uid
end
def organizer?
self.class.organizers.include? self
end
def update_from_auth!(hash)
send :"handle_#{hash['provider']}_attributes", hash
save! if changed?
self
end
def handle_twitter_attributes(hash)
self.nickname = hash['info']['nickname'] unless nickname
self.twitter = hash['info']['nickname']
self.name = hash['info']['name']
self.image = hash['info']['image']
self.url = hash['info']['urls']['Website'] unless url
self.description = hash['info']['description'] unless description
self.location = hash['info']['location']
end
def handle_github_attributes(hash)
self.nickname = hash['info']['nickname'] unless nickname
self.github = hash['info']['nickname']
self.email = hash['info']['email'] unless email
self.name = hash['info']['name'].presence || hash['info']['nickname']
self.image = hash['info']['image']
self.url = hash['info']['urls']['Blog'] || hash['info']['urls']['GitHub'] unless url
self.description = hash['extra']['raw_info']['bio'] unless description
self.location = hash['extra']['raw_info']['location']
end
def handle_google_oauth2_attributes(hash)
Rails.logger.info(hash)
Rails.logger.info(hash['info'])
self.nickname = hash['info']['name'] unless nickname
self.email = hash['info']['email'] unless email
self.name = hash['info']['name']
self.image = hash['info']['image']
end
def handle_email_attributes(hash)
received_email = hash['info']['email']
self.nickname = nickname_from_email(received_email) unless nickname
self.name = name_from_email(received_email) unless name
self.image = image_from_email(received_email) unless image
self.email = received_email
end
def hash_for_email(email)
Digest::SHA256.new.hexdigest(email)
end
def nickname_from_email(email)
hash_for_email(email)
end
def hide_nickname?
nickname == nickname_from_email(email)
end
EMPTY_NAME = '********'
def name_from_email(_email)
EMPTY_NAME
end
def image_from_email(email)
"https://www.gravatar.com/avatar/#{hash_for_email(email)}"
end
def with_provider?(provider)
authorizations.map(&:provider).include?(provider)
end
def missing_name?
name == EMPTY_NAME
end
class DuplicateNickname < StandardError
attr_reader :nickname
def initialize(nickname)
@nickname = nickname
end
end
class << self
def create_from_hash!(hash)
nickname = hash['info']['nickname']
raise DuplicateNickname, nickname if find_by(nickname:)
User.new.update_from_auth! hash
end
def authenticated_with_token(id, stored_salt)
user = find_by(id:)
user && user.salt == stored_salt ? user : nil
end
end
end