ncs_navigator_authority 0.0.2

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.
Files changed (46) hide show
  1. data/.gitignore +5 -0
  2. data/.rvmrc +3 -0
  3. data/Gemfile +4 -0
  4. data/Rakefile +8 -0
  5. data/build.yaml +4 -0
  6. data/buildfile +7 -0
  7. data/lib/ncs_navigator/.DS_Store +0 -0
  8. data/lib/ncs_navigator/authorization.rb +7 -0
  9. data/lib/ncs_navigator/authorization/core.rb +3 -0
  10. data/lib/ncs_navigator/authorization/core/authority.rb +84 -0
  11. data/lib/ncs_navigator/authorization/psc.rb +3 -0
  12. data/lib/ncs_navigator/authorization/psc/authority.rb +193 -0
  13. data/lib/ncs_navigator/authorization/staff_portal.rb +6 -0
  14. data/lib/ncs_navigator/authorization/staff_portal/aker_token.rb +26 -0
  15. data/lib/ncs_navigator/authorization/staff_portal/client.rb +8 -0
  16. data/lib/ncs_navigator/authorization/staff_portal/connection.rb +33 -0
  17. data/lib/ncs_navigator/authorization/staff_portal/http_basic.rb +16 -0
  18. data/lib/ncs_navigator/authorization/version.rb +5 -0
  19. data/ncs_navigator_authority.gemspec +34 -0
  20. data/spec/fixtures/.DS_Store +0 -0
  21. data/spec/fixtures/vcr_cassettes/staff_portal/core/unknown_user.yml +32 -0
  22. data/spec/fixtures/vcr_cassettes/staff_portal/core/user.yml +32 -0
  23. data/spec/fixtures/vcr_cassettes/staff_portal/psc/all_users.yml +34 -0
  24. data/spec/fixtures/vcr_cassettes/staff_portal/psc/empty_users_by_role.yml +34 -0
  25. data/spec/fixtures/vcr_cassettes/staff_portal/psc/empty_users_by_search_criteria.yml +34 -0
  26. data/spec/fixtures/vcr_cassettes/staff_portal/psc/unknown_user.yml +32 -0
  27. data/spec/fixtures/vcr_cassettes/staff_portal/psc/user_by_numeric_id.yml +34 -0
  28. data/spec/fixtures/vcr_cassettes/staff_portal/psc/user_by_username.yml +34 -0
  29. data/spec/fixtures/vcr_cassettes/staff_portal/psc/users_by_first_name.yml +34 -0
  30. data/spec/fixtures/vcr_cassettes/staff_portal/psc/users_by_first_or_last_name.yml +34 -0
  31. data/spec/fixtures/vcr_cassettes/staff_portal/psc/users_by_first_or_last_or_user_name.yml +34 -0
  32. data/spec/fixtures/vcr_cassettes/staff_portal/psc/users_by_first_or_user_name.yml +34 -0
  33. data/spec/fixtures/vcr_cassettes/staff_portal/psc/users_by_last_name.yml +34 -0
  34. data/spec/fixtures/vcr_cassettes/staff_portal/psc/users_by_last_or_user_name.yml +34 -0
  35. data/spec/fixtures/vcr_cassettes/staff_portal/psc/users_by_role.yml +34 -0
  36. data/spec/fixtures/vcr_cassettes/staff_portal/psc/users_by_username.yml +34 -0
  37. data/spec/navigator.ini +118 -0
  38. data/spec/ncs_navigator/.DS_Store +0 -0
  39. data/spec/ncs_navigator/authorization/core/authority_spec.rb +69 -0
  40. data/spec/ncs_navigator/authorization/psc/authority_spec.rb +292 -0
  41. data/spec/ncs_navigator/authorization/psc/role_mapping_spec.rb +99 -0
  42. data/spec/ncs_navigator/authorization/staff_portal/aker_token_spec.rb +36 -0
  43. data/spec/ncs_navigator/authorization/staff_portal/http_basic_spec.rb +17 -0
  44. data/spec/spec_helper.rb +18 -0
  45. data/spec/support/vcr_setup.rb +7 -0
  46. metadata +257 -0
data/.gitignore ADDED
@@ -0,0 +1,5 @@
1
+ *.gem
2
+ .bundle
3
+ Gemfile.lock
4
+ pkg/*
5
+ target/*
data/.rvmrc ADDED
@@ -0,0 +1,3 @@
1
+ rvm ree-1.8.7-2011.03
2
+ rvm_gemset_create_on_use_flag=1
3
+ rvm gemset use ncs_navigator_authority
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in ncs_navigator_authority.gemspec
4
+ gemspec
data/Rakefile ADDED
@@ -0,0 +1,8 @@
1
+ require 'bundler/gem_tasks'
2
+
3
+ require 'rspec/core/rake_task'
4
+ require 'ci/reporter/rake/rspec'
5
+
6
+ RSpec::Core::RakeTask.new do |t|
7
+ t.pattern = "spec/**/*_spec.rb"
8
+ end
data/build.yaml ADDED
@@ -0,0 +1,4 @@
1
+ gems:
2
+ - buildr =1.4.6
3
+ - buildr-gemjar =1.1.0
4
+ jruby: 1.6.5
data/buildfile ADDED
@@ -0,0 +1,7 @@
1
+ require 'buildr/bnd'
2
+ require 'buildr-gemjar'
3
+
4
+ define 'ncs_navigator_authority_gems' do
5
+ project.version = '0.0.1.DEV'
6
+ package(:gemjar).with_gem(:file => _('ncs_navigator_authority-0.0.1.gem'))
7
+ end
Binary file
@@ -0,0 +1,7 @@
1
+ module NcsNavigator
2
+ module Authorization
3
+ autoload :Core, 'ncs_navigator/authorization/core'
4
+ autoload :StaffPortal, 'ncs_navigator/authorization/staff_portal'
5
+ autoload :Psc, 'ncs_navigator/authorization/psc'
6
+ end
7
+ end
@@ -0,0 +1,3 @@
1
+ module NcsNavigator::Authorization::Core
2
+ autoload :Authority, 'ncs_navigator/authorization/core/authority'
3
+ end
@@ -0,0 +1,84 @@
1
+ require 'ncs_navigator/configuration'
2
+ module NcsNavigator::Authorization::Core
3
+ class Authority
4
+ def initialize(ignored_config=nil)
5
+ @groups = {}
6
+ @portal = :NCSNavigator
7
+ end
8
+
9
+ def amplify!(user)
10
+ base = user(user)
11
+ return user unless base
12
+ user.merge!(base)
13
+ end
14
+
15
+ def user(user)
16
+ staff = get_staff(user)
17
+ if staff
18
+ u = Aker::User.new(user.username)
19
+ u.portals << @portal
20
+ attributes = ["first_name", "last_name", "email"]
21
+ attributes.each do |a|
22
+ setter = "#{a}="
23
+ if u.respond_to?(setter)
24
+ u.send(setter, staff[a])
25
+ end
26
+ end
27
+ u.identifiers[:staff_id] = staff["staff_id"]
28
+ groups = staff['roles'].collect do |role|
29
+ role['name']
30
+ end
31
+
32
+ if groups
33
+ u.group_memberships(@portal).concat(load_group_memberships(@portal, groups))
34
+ end
35
+ u
36
+ else
37
+ nil
38
+ end
39
+ end
40
+
41
+ private
42
+
43
+ def staff_portal_uri
44
+ NcsNavigator.configuration.staff_portal_uri
45
+ end
46
+
47
+ def get_connection(user)
48
+ connection = staff_portal_client(user).connection
49
+ end
50
+
51
+ def staff_portal_client(user)
52
+ NcsNavigator::Authorization::StaffPortal::Client.new(staff_portal_uri, :authenticator => create_authenticator(user))
53
+ end
54
+
55
+ def create_authenticator(user)
56
+ { :token => lambda { user.cas_proxy_ticket(staff_portal_uri) } }
57
+ end
58
+
59
+ def load_group_memberships(portal, group_data)
60
+ group_data.collect do |group|
61
+ Aker::GroupMembership.new(find_or_create_group(portal, group))
62
+ end
63
+ end
64
+
65
+ def find_or_create_group(portal, group_name)
66
+ existing = (@groups[portal] ||= []).collect { |top|
67
+ top.find { |g| g.name == group_name }
68
+ }.compact.first
69
+ return existing if existing
70
+ @groups[portal] << Aker::Group.new(group_name)
71
+ @groups[portal].last
72
+ end
73
+
74
+ def get_staff(user)
75
+ connection = get_connection(user)
76
+ response = connection.get '/staff/' << user.username << '.json'
77
+ if response.status == 200
78
+ response.body
79
+ else
80
+ nil
81
+ end
82
+ end
83
+ end
84
+ end
@@ -0,0 +1,3 @@
1
+ module NcsNavigator::Authorization::Psc
2
+ autoload :Authority, 'ncs_navigator/authorization/psc/authority'
3
+ end
@@ -0,0 +1,193 @@
1
+ require 'ncs_navigator/configuration'
2
+ module NcsNavigator::Authorization::Psc
3
+ class Authority
4
+ def initialize(ignored_config=nil)
5
+ @staff_portal_connection ||= staff_portal_client.connection
6
+ end
7
+
8
+ def get_user_by_username(username, role_detail_level)
9
+ user(username)
10
+ end
11
+
12
+ def get_user_by_id(id, role_detail_level)
13
+ user(id)
14
+ end
15
+
16
+ def get_users_by_role(role_name)
17
+ users_hash(get_users_collection_by_role(role_name))
18
+ end
19
+
20
+ def search_users(criteria)
21
+ users_hash(get_users_by_search_criteria(criteria))
22
+ end
23
+
24
+ def user(staff)
25
+ user_hash(get_user_by_username_or_id(staff))
26
+ end
27
+
28
+ private
29
+
30
+ def users_hash(users)
31
+ users_hash = []
32
+ users.each do |u|
33
+ users_hash << user_hash(u)
34
+ end
35
+ users_hash
36
+ end
37
+
38
+ def user_hash(staff)
39
+ return nil unless staff
40
+ {
41
+ :username => staff["username"],
42
+ :id => staff["numeric_id"],
43
+ :email_address => staff["email"],
44
+ :first_name => staff["first_name"],
45
+ :last_name => staff["last_name"],
46
+ :roles => roles_hash(staff["roles"].collect {|role| role['name']})
47
+ }
48
+ end
49
+
50
+ def roles_hash(roles)
51
+ roles_hash = {}
52
+ roles.each do |role|
53
+ roles_hash.merge!(generate_roles_hash(role))
54
+ end
55
+ roles_hash
56
+ end
57
+
58
+ def generate_roles_hash(sp_role)
59
+ roles = {}
60
+ role_mappings = RoleMapping.staff_portal_to_psc(sp_role)
61
+ role_mappings.each do |role|
62
+ roles[role] = true
63
+ end
64
+ roles
65
+ end
66
+
67
+ def staff_portal_client
68
+ NcsNavigator::Authorization::StaffPortal::Client.new(NcsNavigator.configuration.staff_portal_uri, :authenticator => create_authenticator)
69
+ end
70
+
71
+ def create_authenticator
72
+ { :basic => ["psc_application", NcsNavigator.configuration.staff_portal['psc_user_password']] }
73
+ end
74
+
75
+ def get_staff(url)
76
+ response = @staff_portal_connection.get url
77
+ if response.status == 200
78
+ response.body
79
+ else
80
+ nil
81
+ end
82
+ end
83
+
84
+ def get_user_by_username_or_id(staff)
85
+ url = '/staff/' << staff.to_s << '.json'
86
+ get_staff(url)
87
+ end
88
+
89
+ def get_users_collection_by_role(psc_role)
90
+ roles = RoleMapping.psc_to_staff_portal(psc_role)
91
+ return roles if roles.empty?
92
+ query = 'role[]='
93
+ roles.each_with_index do |r, i|
94
+ query << r
95
+ unless r == roles.last
96
+ query << '&role[]='
97
+ end
98
+ end
99
+ url = '/users.json?' << query
100
+ get_staff(url)
101
+ end
102
+
103
+ def get_users_by_search_criteria(criteria)
104
+ url = '/users.json'
105
+ unless criteria.empty?
106
+ url << "?" << construct_query(criteria)
107
+ end
108
+ get_staff(url)
109
+ end
110
+
111
+ def construct_query(criteria)
112
+ operator = "&"
113
+ if criteria.has_key?(:first_name_substring)
114
+ query = get_search_query("first_name", criteria[:first_name_substring])
115
+ if criteria.has_key?(:last_name_substring)
116
+ query << operator
117
+ query << get_search_query("last_name", criteria[:last_name_substring])
118
+ end
119
+ if criteria.has_key?(:username_substring)
120
+ query << operator
121
+ query << get_search_query("username", criteria[:username_substring])
122
+ end
123
+ elsif criteria.has_key?(:last_name_substring)
124
+ query = get_search_query("last_name", criteria[:last_name_substring])
125
+ if criteria.has_key?(:username_substring)
126
+ query << operator
127
+ query << get_search_query("username", criteria[:username_substring])
128
+ end
129
+ elsif criteria.has_key?(:username_substring)
130
+ query = get_search_query("username", criteria[:username_substring])
131
+ end
132
+ query << "&operator=OR" if criteria.size > 1
133
+ query
134
+ end
135
+
136
+ def get_search_query(key, value)
137
+ query = "#{key}=" << value
138
+ end
139
+ end
140
+
141
+ class RoleMapping
142
+ def self.psc_to_staff_portal(psc_role)
143
+ roles = [];
144
+ case psc_role
145
+ when :study_calendar_template_builder, :study_creator, :study_qa_manager, :study_site_participation_administrator, :system_administrator,
146
+ :data_importer, :business_administrator, :person_and_organization_information_manager
147
+ roles << "System Administrator"
148
+ when :user_administrator
149
+ roles << "User Administrator"
150
+ when :study_team_administrator
151
+ roles << "Staff Supervisor"
152
+ when :data_reader
153
+ roles << "Data Reader"
154
+ when :subject_manager
155
+ roles << "Field Staff"
156
+ roles << "Phone Staff"
157
+ when :study_subject_calendar_manager
158
+ roles << "Field Staff"
159
+ roles << "Phone Staff"
160
+ roles << "Biological Specimen Collector"
161
+ end
162
+ roles
163
+ end
164
+
165
+ def self.staff_portal_to_psc(sp_role)
166
+ roles = [];
167
+ case sp_role
168
+ when "System Administrator"
169
+ roles << :study_creator
170
+ roles << :study_calendar_template_builder
171
+ roles << :study_qa_manager
172
+ roles << :study_site_participation_administrator
173
+ roles << :system_administrator
174
+ roles << :data_importer
175
+ roles << :business_administrator
176
+ roles << :person_and_organization_information_manager
177
+ when "User Administrator"
178
+ roles << :user_administrator
179
+ when "Staff Supervisor"
180
+ roles << :study_team_administrator
181
+ when "Field Staff", "Phone Staff"
182
+ roles << :subject_manager
183
+ roles << :study_subject_calendar_manager
184
+ when "Biological Specimen Collector"
185
+ roles << :study_subject_calendar_manager
186
+ when "Data Reader"
187
+ roles << :data_reader
188
+ end
189
+ roles
190
+ end
191
+ end
192
+
193
+ end
@@ -0,0 +1,6 @@
1
+ module NcsNavigator::Authorization::StaffPortal
2
+ autoload :AkerToken, 'ncs_navigator/authorization/staff_portal/aker_token'
3
+ autoload :HttpBasic, 'ncs_navigator/authorization/staff_portal/http_basic'
4
+ autoload :Client, 'ncs_navigator/authorization/staff_portal/client'
5
+ autoload :Connection, 'ncs_navigator/authorization/staff_portal/connection'
6
+ end
@@ -0,0 +1,26 @@
1
+ require 'faraday'
2
+
3
+ module NcsNavigator::Authorization::StaffPortal
4
+ class AkerToken < ::Faraday::Middleware
5
+ def initialize(app, token_or_creator)
6
+ @app = app
7
+ if token_or_creator.respond_to?(:call)
8
+ @token_creator = token_or_creator
9
+ else
10
+ @token_creator = lambda { token_or_creator }
11
+ end
12
+ end
13
+
14
+
15
+ def call(env)
16
+ env[:request_headers]['Authorization'] = "CasProxy #{token}"
17
+ @app.call(env)
18
+ end
19
+
20
+ private
21
+
22
+ def token
23
+ @token_creator.call
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,8 @@
1
+ module NcsNavigator::Authorization::StaffPortal
2
+ class Client
3
+ attr_reader :connection
4
+ def initialize(url, options, &block)
5
+ @connection = NcsNavigator::Authorization::StaffPortal::Connection.new(url, options, &block)
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,33 @@
1
+ require 'faraday'
2
+ require 'faraday_stack'
3
+ module NcsNavigator::Authorization::StaffPortal
4
+ class Connection < ::Faraday::Connection
5
+ def initialize(url, options)
6
+ super do |builder|
7
+ builder.use *authentication_middleware(options[:authenticator])
8
+ builder.request :json
9
+ builder.use FaradayStack::ResponseJSON, :content_type => 'application/json'
10
+ builder.adapter :net_http
11
+ end
12
+ end
13
+
14
+ private
15
+
16
+ def authentication_middleware(authenticator)
17
+ unless authenticator
18
+ raise 'No authentication method specified. Please include the :authenticator option.'
19
+ end
20
+
21
+ kind = authenticator.keys.first
22
+
23
+ case kind
24
+ when :basic
25
+ [NcsNavigator::Authorization::StaffPortal::HttpBasic, *authenticator[kind]]
26
+ when :token
27
+ [NcsNavigator::Authorization::StaffPortal::AkerToken, authenticator[kind]]
28
+ else
29
+ raise "Unsupported authentication method #{kind.inspect}."
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,16 @@
1
+ require 'base64'
2
+
3
+ module NcsNavigator::Authorization::StaffPortal
4
+ class HttpBasic
5
+ def initialize(app, username, password)
6
+ @app = app
7
+ @header_value = "Basic #{Base64.encode64([username, password].join(':')).strip}"
8
+ end
9
+
10
+ def call(env)
11
+ env[:request_headers]['Authorization'] = @header_value
12
+
13
+ @app.call(env)
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,5 @@
1
+ module NcsNavigator
2
+ class Authorization
3
+ VERSION = '0.0.2'
4
+ end
5
+ end