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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: b6ebfa7bb437454efca0513642b2bfbf5464e5f2
4
- data.tar.gz: 59ac1d64b4f418bc48019657687edc7bb94ddc98
3
+ metadata.gz: 90b41d1da193def155770eac480a23b933f9160d
4
+ data.tar.gz: b764233babcee9bf78a7cd3b9a527807410fe04d
5
5
  SHA512:
6
- metadata.gz: 2e16f9fa978ded9c51250f5a3e2b2aee663db06cceabd22a2ae1c5068b9c2e1e667d91e1acc5879d3f8c1d319e39a1408dfbcbb2199270ef3969a827f0c73ede
7
- data.tar.gz: 6d466a2c368cd922ec36fb2d7cc6d0d8249ba5dfef681d03f211905fd1f2e387239febe9bef305e756db91e1a25a57e25255f9baaefd4bcba9c03cbf05b94cb8
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 Git Repository selected as the source, write `concerto_saml_auth` as the Gem Name, and this repository's clone URL as the Source URL.
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 using through SAML login.
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 = matching_groups.map do |single_splitted_group|
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
- Rails.logger.debug common_names
151
- # Go to array of "Broadcast engineer" (normalizing names)
152
- common_names.map do |single_common_name|
153
- single_common_name.capitalize
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).destroy
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).capitalize
199
+ (group.strip).downcase
179
200
  end
180
201
 
181
- user_groups = Membership.where(:user_id => user.id)
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
- ConcertoConfig.make_concerto_config("saml_uid_key", "uid",
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 => 4,
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("saml_member_of_filter", "OU=Access control",
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 => "Filter determining which groups are made in Concerto. At least one of the assertions provided here, separated by comma, must match a memberOf field for it to be included.")
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
- :member_of_filter => ConcertoConfig[:saml_member_of_filter],
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
@@ -1,3 +1,3 @@
1
1
  module ConcertoSamlAuth
2
- VERSION = "0.1.0"
2
+ VERSION = "1.0.0"
3
3
  end
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: 0.1.0
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-16 00:00:00.000000000 Z
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: http://www.concerto-signage.org
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.5.2
99
+ rubygems_version: 2.6.11
100
100
  signing_key:
101
101
  specification_version: 4
102
102
  summary: Provides user authentication using SAML