This repository has been archived by the owner on Dec 18, 2019. It is now read-only.
forked from paviliondev/discourse-wikimedia-auth
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathplugin.rb
121 lines (97 loc) · 3.78 KB
/
plugin.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
# name: discourse-wikimedia-auth
# about: Enable Login via Wikimedia
# version: 0.0.1
# authors: Angus McLeod
# url: https://github.com/paviliondev/discourse-wikimedia-auth
gem 'omniauth-mediawiki'
enabled_site_setting :wikimedia_auth_enabled
register_asset 'stylesheets/common/wikimedia.scss'
class WikimediaAuthenticator < ::Auth::ManagedAuthenticator
def name
'mediawiki'
end
def primary_email_verified?(auth_token)
auth_token[:extra]['confirmed_email'].present? ?
auth_token[:extra]['confirmed_email'] :
false
end
def can_revoke?
false
end
def can_connect_existing_user?
false
end
def after_authenticate(auth_token, existing_account: nil)
raw_info = auth_token[:extra]['raw_info']
auth_token[:extra] = raw_info || {}
## Deny entry if either:
# 1) the user's Wikimedia email is not verified; or
# 2) a user has previously authenticated with the same email under a different Wikimedia account
##
if !primary_email_verified?(auth_token) ||
(existing_associated_account = ::UserAssociatedAccount.where(
"info::json->>'email' = '#{raw_info['email']}' AND
provider_uid != '#{raw_info['sub']}'").exists?)
error_result = Auth::Result.new
error_result.failed = true
error_result.failed_reason = existing_associated_account ?
I18n.t("login.authenticator_existing_account", { email: raw_info['email']}) :
I18n.t("login.authenticator_email_not_verified")
error_result
else
auth_token[:info][:nickname] = raw_info['username'] if raw_info['username']
auth_result = super(auth_token, existing_account: existing_account)
auth_result.omit_username = true
auth_result
end
end
def register_middleware(omniauth)
omniauth.provider :mediawiki,
name: name,
setup: lambda { |env|
strategy = env['omniauth.strategy']
options = strategy.options
options[:consumer_key] = SiteSetting.wikimedia_consumer_key
options[:consumer_secret] = SiteSetting.wikimedia_consumer_secret
options[:client_options][:site] = SiteSetting.wikimedia_auth_site
options[:client_options][:authorize_path] = SiteSetting.wikimedia_auth_path
options[:client_options][:access_token_path] = SiteSetting.wikimedia_token_path
options[:client_options][:request_token_path] = SiteSetting.wikimedia_request_path
def strategy.callback_url
SiteSetting.wikimedia_callback_url
end
}
end
def enabled?
SiteSetting.wikimedia_auth_enabled
end
end
auth_provider authenticator: WikimediaAuthenticator.new
after_initialize do
module UsersControllerExtension
def create
## Ensure that username sent by the client is the same as suggester's version of the Wikimedia username
## Note that email is ensured by the email validation process
wikimedia_username = session[:authentication][:username]&.unicode_normalize
suggested_username = UserNameSuggester.suggest(wikimedia_username)
if suggested_username != params[:username]
return fail_with("login.non_wikimedia_username")
end
super
end
end
require_dependency 'users_controller'
class ::UsersController
prepend UsersControllerExtension
end
module GuardianWikimediaExtension
def can_edit_username?(user)
return false if !is_admin? && SiteSetting.wikimedia_auth_enabled
super(user)
end
end
require_dependency 'guardian'
class ::Guardian
prepend GuardianWikimediaExtension
end
end