concerto_saml_auth 0.1.0 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|