ncs_navigator_authority 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
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