external_user.rb
2.09 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
require 'ostruct'
module ExternalUser
extend ActiveSupport::Concern
included do
attr_accessor :external_person_id
end
def external_person
ExternalPerson.where(id: self.external_person_id).first
end
module ClassMethods
def webfinger_lookup(login, domain, environment)
if login && domain && environment.has_federated_network?(domain)
# Ask if network at <domain> has user with login <login>
# FIXME: Make an actual request to the federated network, which should return nil if not found
{
login: login
}
else
nil
end
end
def external_login(login, password, domain)
# Call Noosfero /api/login
uri = URI.parse('http://' + domain + '/api/v1/login')
response = Net::HTTP.post_form(uri, { login: login, password: password })
if response.code == '301'
# Follow a redirection
uri = URI.parse(response.header['location'])
response = Net::HTTP.post_form(uri, { login: login, password: password })
end
response.code.to_i / 100 === 2 ? JSON.parse(response.body) : nil
end
# Authenticates a user from an external social network
def external_authenticate(username, password, environment)
login, domain = username.split('@')
webfinger = User.webfinger_lookup(login, domain, environment)
if webfinger
user = User.external_login(login, password, domain)
if user
u = User.new
u.login = login
# FIXME: Instead of the struct below, we should use the "webfinger" object returned by the webfinger_lookup method
webfinger = OpenStruct.new(
identifier: user['user']['person']['identifier'],
name: user['user']['person']['name'],
created_at: user['user']['person']['created_at'],
domain: domain,
email: user['user']['email']
)
u.external_person_id = ExternalPerson.get_or_create(webfinger).id
return u
end
end
nil
end
end
end