concerto_saml_auth 0.1.0 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +2 -3
- data/app/controllers/concerto_saml_auth/application_controller.rb +47 -29
- data/config/initializers/omniauth.rb +18 -7
- data/lib/concerto_saml_auth/version.rb +1 -1
- metadata +4 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 90b41d1da193def155770eac480a23b933f9160d
|
4
|
+
data.tar.gz: b764233babcee9bf78a7cd3b9a527807410fe04d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: aa1ab6c6bebb042a75def3c578763c7a05f8b296d69fcefc4c67f7405084efc4b5e4b7d7de2e7645d26f337f93c864fb16386ec9af1c88f32b8a61dc84929e96
|
7
|
+
data.tar.gz: f37cc2db9fa584050956779fea291dc2699eea719667a584dfabf79b472571897a81af029487c810a153becbe298fa32bdc99f07e7a64606eba1964667a11e2d
|
data/README.md
CHANGED
@@ -13,10 +13,9 @@ Installing the plugin
|
|
13
13
|
1. Log in using a system admin account in your Concerto deployment. You should have set up your Concerto installation already.
|
14
14
|
2. Click on the "plugins" button on the top navigation bar under the admin section.
|
15
15
|
3. On the right side of the page, click on the "new plugin" button.
|
16
|
-
4. With
|
17
|
-
5. Click save, you will now stop your Concerto web server, run the ```bundle``` command (while in the Concerto directory), and start your web server again.
|
16
|
+
4. With Ruby Gem selected as the source, write `concerto_saml_auth` as the Gem Name.
|
18
17
|
6. Since the SAML plugin is not configured yet, you can log back into your Concerto accounts by visiting the ```your.concerto.url/users/sign_in``` route, using
|
19
|
-
any user that was not created
|
18
|
+
any user that was not created through SAML login. Or continue using the user you're logged in as.
|
20
19
|
7. If the plugin was installed successfully, you will see a new "SAML User Authentication" settings tab under the "settings" page. This page can be found by clicking the "settings" button on the top navigation bar under the admin section.
|
21
20
|
8. Configure the plugin and restart the web server, as explained below.
|
22
21
|
9. Add your Service Provider's metadata to the Identity Provider. You can find your metadata at `your.concerto.url/auth/saml/metadata`.
|
@@ -57,7 +57,7 @@ module ConcertoSamlAuth
|
|
57
57
|
end
|
58
58
|
|
59
59
|
if omniauth_config[:admin_groups].present?
|
60
|
-
synchronize_is_admin(user, omniauth_config)
|
60
|
+
synchronize_is_admin(user, saml_hash, omniauth_config)
|
61
61
|
end
|
62
62
|
|
63
63
|
user.save!
|
@@ -92,7 +92,26 @@ module ConcertoSamlAuth
|
|
92
92
|
end
|
93
93
|
|
94
94
|
def find_user_groups(saml_hash, omniauth_config)
|
95
|
+
member_of_mapping = create_member_of_mapping(omniauth_config[:member_of_mapping])
|
96
|
+
Rails.logger.debug member_of_mapping
|
97
|
+
|
98
|
+
common_names = find_cn_from_member_of(saml_hash, omniauth_config)
|
99
|
+
|
100
|
+
# Apply the mapping
|
101
|
+
concerto_groups = []
|
102
|
+
member_of_mapping.each do |concerto_group_name, ldap_group_names|
|
103
|
+
common_group_names = ldap_group_names & common_names
|
104
|
+
if common_group_names
|
105
|
+
# This user is a member of a group associated with this Concerto group.
|
106
|
+
concerto_groups.push(concerto_group_name)
|
107
|
+
end
|
108
|
+
end
|
109
|
+
concerto_groups
|
110
|
+
end
|
111
|
+
|
112
|
+
def find_cn_from_member_of(saml_hash, omniauth_config)
|
95
113
|
member_of_key = omniauth_config[:member_of_key]
|
114
|
+
|
96
115
|
member_of_lines = saml_hash[:extra][:response_object].attributes.multi(member_of_key)
|
97
116
|
if member_of_lines.nil?
|
98
117
|
Rails.logger.debug "No user groups found"
|
@@ -111,24 +130,8 @@ module ConcertoSamlAuth
|
|
111
130
|
end
|
112
131
|
Rails.logger.debug "Interpreting the memberOf field:"
|
113
132
|
Rails.logger.debug groups_splitted
|
114
|
-
# Remove elements which are not matched by the filter
|
115
|
-
if !omniauth_config[:member_of_filter].blank?
|
116
|
-
filter = omniauth_config[:member_of_filter]
|
117
|
-
filter = (filter.strip).downcase
|
118
|
-
filter_list = filter.split(",")
|
119
|
-
Rails.logger.debug filter_list
|
120
|
-
matching_groups = groups_splitted.select do |single_splitted_group|
|
121
|
-
# Check if the intersection of single_splitted_group and filter_list has elements
|
122
|
-
# (meaning that at least one element in single_splitted_group matches one element
|
123
|
-
# in filter_list)
|
124
|
-
!(single_splitted_group & filter_list).empty?
|
125
|
-
end
|
126
|
-
else
|
127
|
-
matching_groups = groups_splitted
|
128
|
-
end
|
129
|
-
Rails.logger.debug matching_groups
|
130
133
|
# Go to array of {:cn => ["broadcast engineer"], :ou => ["commission", "groups"], :dc => ["example", "com"]}
|
131
|
-
group_hashes =
|
134
|
+
group_hashes = groups_splitted.map do |single_splitted_group|
|
132
135
|
# Create a hash which returns new Arrays for missing entries
|
133
136
|
resulting_group_hash = Hash.new{|h,k| h[k] = []}
|
134
137
|
single_splitted_group.each do |single_group_attribute|
|
@@ -147,11 +150,29 @@ module ConcertoSamlAuth
|
|
147
150
|
common_names.push(group_name)
|
148
151
|
end
|
149
152
|
end
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
153
|
+
common_names
|
154
|
+
end
|
155
|
+
|
156
|
+
def create_member_of_mapping(member_of_mapping_str)
|
157
|
+
member_of_mapping_str.strip!
|
158
|
+
group_statements = member_of_mapping_str.split(';')
|
159
|
+
group_statements.map! {|s| s.strip }
|
160
|
+
mapping = {}
|
161
|
+
group_statements.each do |statement|
|
162
|
+
parts = statement.split('=')
|
163
|
+
if parts.count <= 1
|
164
|
+
return nil
|
165
|
+
end
|
166
|
+
concerto_group_name = parts[0]
|
167
|
+
|
168
|
+
ldap_groups_str = parts[1]
|
169
|
+
ldap_groups_str.downcase!
|
170
|
+
ldap_group_names = ldap_groups_str.split(',')
|
171
|
+
ldap_group_names.map! {|s| s.strip }
|
172
|
+
|
173
|
+
mapping[concerto_group_name] = ldap_group_names
|
154
174
|
end
|
175
|
+
mapping
|
155
176
|
end
|
156
177
|
|
157
178
|
def add_user_to(all_groups, user)
|
@@ -167,21 +188,18 @@ module ConcertoSamlAuth
|
|
167
188
|
def remove_user_from(all_groups, user)
|
168
189
|
all_groups.each do |group_name|
|
169
190
|
group = Group.where(:name => group_name).first!
|
170
|
-
Membership.where(:user_id => user.id, :group_id => group.id).
|
191
|
+
Membership.where(:user_id => user.id, :group_id => group.id).destroy_all
|
171
192
|
end
|
172
193
|
end
|
173
194
|
|
174
|
-
def synchronize_is_admin(user, omniauth_config)
|
195
|
+
def synchronize_is_admin(user, saml_hash, omniauth_config)
|
175
196
|
admin_group_string = omniauth_config[:admin_groups]
|
176
197
|
admin_group_names = admin_group_string.split(",")
|
177
198
|
admin_group_names.map! do |group|
|
178
|
-
(group.strip).
|
199
|
+
(group.strip).downcase
|
179
200
|
end
|
180
201
|
|
181
|
-
|
182
|
-
user_group_names = user_groups.map do |membership|
|
183
|
-
membership.group.name
|
184
|
-
end
|
202
|
+
user_group_names = find_cn_from_member_of(saml_hash, omniauth_config)
|
185
203
|
should_be_admin = admin_group_names & user_group_names
|
186
204
|
user.is_admin = !should_be_admin.empty?
|
187
205
|
end
|
@@ -16,16 +16,23 @@ if ActiveRecord::Base.connection.table_exists? 'concerto_configs'
|
|
16
16
|
:seq_no => 2,
|
17
17
|
:description => "A unique identifier used by this application to identify itself to the identity provider.")
|
18
18
|
|
19
|
-
|
19
|
+
default_saml_callback = "https://concerto.example.com/auth/saml/callback"
|
20
|
+
ConcertoConfig.make_concerto_config("saml_callback", default_saml_callback,
|
20
21
|
:value_type => "string",
|
21
22
|
:category => "SAML User Authentication",
|
22
23
|
:seq_no => 3,
|
24
|
+
:description => "This is where the identity provider should redirect the user upon authentication. The path should be /auth/saml/callback, but using this setting you can enforce HTTPS for the callback. Leave empty or as default to automatically find callback URL.")
|
25
|
+
|
26
|
+
ConcertoConfig.make_concerto_config("saml_uid_key", "uid",
|
27
|
+
:value_type => "string",
|
28
|
+
:category => "SAML User Authentication",
|
29
|
+
:seq_no => 4,
|
23
30
|
:description => "SAML field name containing user login names")
|
24
31
|
|
25
32
|
ConcertoConfig.make_concerto_config("saml_email_key", "email",
|
26
33
|
:value_type => "string",
|
27
34
|
:category => "SAML User Authentication",
|
28
|
-
:seq_no =>
|
35
|
+
:seq_no => 5,
|
29
36
|
:description => "SAML field name containing user email addresses. Leave blank if using email_suffix below")
|
30
37
|
|
31
38
|
ConcertoConfig.make_concerto_config("saml_first_name_key", "first_name",
|
@@ -46,17 +53,17 @@ if ActiveRecord::Base.connection.table_exists? 'concerto_configs'
|
|
46
53
|
:seq_no => 8,
|
47
54
|
:description => "SAML field name containing the memberOf attribute, as retrieved from LDAP")
|
48
55
|
|
49
|
-
ConcertoConfig.make_concerto_config("
|
56
|
+
ConcertoConfig.make_concerto_config("saml_member_of_mapping", "Concerto group 1 = LDAP group 1, LDAP group 2; Concerto group 2 = LDAP group 2",
|
50
57
|
:value_type => "string",
|
51
58
|
:category => "SAML User Authentication",
|
52
59
|
:seq_no => 9,
|
53
|
-
:description => "
|
60
|
+
:description => "Mapping between LDAP groups and Concerto groups. Format: GROUP NAME IN CONCERTO = GROUP NAME IN LDAP[, ANOTHER GROUP IN LDAP]…; ANOTHER GROUP NAME IN CONCERTO = (and so on)")
|
54
61
|
|
55
62
|
ConcertoConfig.make_concerto_config("saml_admin_groups", "administrator group",
|
56
63
|
:value_type => "string",
|
57
64
|
:category => "SAML User Authentication",
|
58
65
|
:seq_no => 10,
|
59
|
-
:description => "Common name of groups, separated by comma, whose members should be granted administrator permission in Concerto")
|
66
|
+
:description => "Common name of LDAP groups, separated by comma, whose members should be granted administrator permission in Concerto")
|
60
67
|
|
61
68
|
# Store omniauth config values from main application's ConcertoConfig
|
62
69
|
saml_idp_metadata = ConcertoConfig[:saml_idp_metadata]
|
@@ -74,6 +81,11 @@ if ActiveRecord::Base.connection.table_exists? 'concerto_configs'
|
|
74
81
|
Rails.logger.warn "No URL (or default URL) defined for IDP metadata, SAML authentication will not be working."
|
75
82
|
end
|
76
83
|
|
84
|
+
saml_callback = ConcertoConfig[:saml_callback]
|
85
|
+
if saml_callback.present? && saml_callback != default_saml_callback
|
86
|
+
omniauth_config[:assertion_consumer_service_url] = saml_callback
|
87
|
+
end
|
88
|
+
|
77
89
|
request_attributes = []
|
78
90
|
if ConcertoConfig[:saml_email_key].present?
|
79
91
|
request_attributes.push({:name => ConcertoConfig[:saml_email_key], :friendly_name => "Email", :is_required => true})
|
@@ -103,9 +115,8 @@ if ActiveRecord::Base.connection.table_exists? 'concerto_configs'
|
|
103
115
|
},
|
104
116
|
:request_attributes => request_attributes,
|
105
117
|
:member_of_key => ConcertoConfig[:saml_member_of_key],
|
106
|
-
:
|
118
|
+
:member_of_mapping => ConcertoConfig[:saml_member_of_mapping],
|
107
119
|
:admin_groups => ConcertoConfig[:saml_admin_groups],
|
108
|
-
# :callback_url => "/auth/saml/callback"
|
109
120
|
)
|
110
121
|
|
111
122
|
Rails.logger.debug omniauth_config
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: concerto_saml_auth
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 1.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Gabe Perez
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2017-07-
|
12
|
+
date: 2017-07-31 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rails
|
@@ -76,7 +76,7 @@ files:
|
|
76
76
|
- lib/concerto_saml_auth/engine.rb
|
77
77
|
- lib/concerto_saml_auth/version.rb
|
78
78
|
- lib/tasks/concerto_saml_auth_tasks.rake
|
79
|
-
homepage:
|
79
|
+
homepage: https://github.com/Studentmediene/concerto_saml_auth
|
80
80
|
licenses:
|
81
81
|
- Apache-2.0
|
82
82
|
metadata: {}
|
@@ -96,7 +96,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
96
96
|
version: '0'
|
97
97
|
requirements: []
|
98
98
|
rubyforge_project:
|
99
|
-
rubygems_version: 2.
|
99
|
+
rubygems_version: 2.6.11
|
100
100
|
signing_key:
|
101
101
|
specification_version: 4
|
102
102
|
summary: Provides user authentication using SAML
|