osso 0.0.5.pre.epsilon → 0.0.5.pre.eta

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
  SHA256:
3
- metadata.gz: 82bd613a1b8d5eb4f9c549d9d855c629698a120d2ee99bf3a52f6911fa4d080a
4
- data.tar.gz: a67aec622f76bcc42cc16065d11a795c09893caa1115759b5739fa384108f6f2
3
+ metadata.gz: 914a99a42c898e69186b33f4c51069f8c6f4ceddd7c300ce4158f560cc9d7937
4
+ data.tar.gz: 75ece89829bdb5a756340e9c9ff63e414ec093f402d725783a8668459ea32665
5
5
  SHA512:
6
- metadata.gz: c2a1ba5df34d2e175ed7a3ab7e61dcb573b5eb9a636753f7159860f817e6b61515b9350b63a1ac1ffece994f27a7f17d61d2de05e5f6a0468168cfb7a268f879
7
- data.tar.gz: 475eba77f824e32701ff9eae95bef4663f2e0de8d43c9d542846f6ecaec55edb1242251cb4ed50b9cb1db627252293cf406a633cc8c0c63fb7f419e10dc95e3c
6
+ metadata.gz: 4117bbe85a6f88e7703eaf22464d2b343ac4517ec5e6d4a473a7f758ee1733a6b1f65504f13105ec9f823ae2e1f21db0129f0e9aab98ac260175decc5710aaec
7
+ data.tar.gz: 05ed7bea73e54d8ce07b8d6b494724b0cc2dc9e06cee78ba2977e249a983c3b579fe847a9ae731806b94ad94b765bf1d2d8c8b9e763245acdf6e783d40d8bbcf
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- osso (0.0.5.pre.epsilon)
4
+ osso (0.0.5.pre.eta)
5
5
  activesupport (>= 6.0.3.2)
6
6
  graphql
7
7
  jwt
@@ -18,12 +18,12 @@ PATH
18
18
  GEM
19
19
  remote: https://rubygems.org/
20
20
  specs:
21
- activemodel (6.0.3.2)
22
- activesupport (= 6.0.3.2)
23
- activerecord (6.0.3.2)
24
- activemodel (= 6.0.3.2)
25
- activesupport (= 6.0.3.2)
26
- activesupport (6.0.3.2)
21
+ activemodel (6.0.3.3)
22
+ activesupport (= 6.0.3.3)
23
+ activerecord (6.0.3.3)
24
+ activemodel (= 6.0.3.3)
25
+ activesupport (= 6.0.3.3)
26
+ activesupport (6.0.3.3)
27
27
  concurrent-ruby (~> 1.0, >= 1.0.2)
28
28
  i18n (>= 0.7, < 2)
29
29
  minitest (~> 5.1)
@@ -39,24 +39,23 @@ GEM
39
39
  attr_required (1.0.1)
40
40
  bindata (2.4.8)
41
41
  coderay (1.1.3)
42
- concurrent-ruby (1.1.6)
43
- crack (0.4.3)
44
- safe_yaml (~> 1.0.0)
42
+ concurrent-ruby (1.1.7)
43
+ crack (0.4.4)
45
44
  database_cleaner (1.8.5)
46
45
  database_cleaner-active_record (1.8.0)
47
46
  activerecord
48
47
  database_cleaner (~> 1.8.0)
49
48
  diff-lcs (1.4.4)
50
49
  docile (1.3.2)
51
- factory_bot (6.0.2)
50
+ factory_bot (6.1.0)
52
51
  activesupport (>= 5.0.0)
53
- faker (2.13.0)
52
+ faker (2.14.0)
54
53
  i18n (>= 1.6, < 2)
55
54
  graphql (1.11.4)
56
55
  hashdiff (1.0.1)
57
56
  hashie (4.1.0)
58
57
  httpclient (2.8.3)
59
- i18n (1.8.3)
58
+ i18n (1.8.5)
60
59
  concurrent-ruby (~> 1.0)
61
60
  json (2.3.1)
62
61
  json-jwt (1.13.0)
@@ -66,7 +65,7 @@ GEM
66
65
  jwt (2.2.2)
67
66
  method_source (1.0.0)
68
67
  mini_portile2 (2.4.0)
69
- minitest (5.14.1)
68
+ minitest (5.14.2)
70
69
  multi_json (1.15.0)
71
70
  mustermann (1.1.1)
72
71
  ruby2_keywords (~> 0.0.1)
@@ -87,7 +86,7 @@ GEM
87
86
  pry (0.13.1)
88
87
  coderay (~> 1.1)
89
88
  method_source (~> 1.0)
90
- public_suffix (4.0.5)
89
+ public_suffix (4.0.6)
91
90
  rack (2.2.3)
92
91
  rack-contrib (2.2.0)
93
92
  rack (~> 2.0)
@@ -103,7 +102,7 @@ GEM
103
102
  rack (>= 1.0, < 3)
104
103
  rainbow (3.0.0)
105
104
  rake (13.0.1)
106
- regexp_parser (1.7.1)
105
+ regexp_parser (1.8.0)
107
106
  rexml (3.2.4)
108
107
  rspec (3.9.0)
109
108
  rspec-core (~> 3.9.0)
@@ -118,22 +117,21 @@ GEM
118
117
  diff-lcs (>= 1.2.0, < 2.0)
119
118
  rspec-support (~> 3.9.0)
120
119
  rspec-support (3.9.3)
121
- rubocop (0.86.0)
120
+ rubocop (0.91.0)
122
121
  parallel (~> 1.10)
123
- parser (>= 2.7.0.1)
122
+ parser (>= 2.7.1.1)
124
123
  rainbow (>= 2.2.2, < 4.0)
125
124
  regexp_parser (>= 1.7)
126
125
  rexml
127
- rubocop-ast (>= 0.0.3, < 1.0)
126
+ rubocop-ast (>= 0.4.0, < 1.0)
128
127
  ruby-progressbar (~> 1.7)
129
128
  unicode-display_width (>= 1.4.0, < 2.0)
130
- rubocop-ast (0.1.0)
131
- parser (>= 2.7.0.1)
129
+ rubocop-ast (0.4.2)
130
+ parser (>= 2.7.1.4)
132
131
  ruby-progressbar (1.10.1)
133
132
  ruby-saml (1.11.0)
134
133
  nokogiri (>= 1.5.10)
135
134
  ruby2_keywords (0.0.2)
136
- safe_yaml (1.0.5)
137
135
  simplecov (0.17.0)
138
136
  docile (~> 1.1)
139
137
  json (>= 1.8, < 3)
@@ -158,11 +156,11 @@ GEM
158
156
  tzinfo (1.2.7)
159
157
  thread_safe (~> 0.1)
160
158
  unicode-display_width (1.7.0)
161
- webmock (3.8.3)
159
+ webmock (3.9.1)
162
160
  addressable (>= 2.3.6)
163
161
  crack (>= 0.3.2)
164
162
  hashdiff (>= 0.4.0, < 2.0.0)
165
- zeitwerk (2.3.1)
163
+ zeitwerk (2.4.0)
166
164
 
167
165
  PLATFORMS
168
166
  ruby
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Osso
4
+ module Error
5
+ class AccountConfigurationError < Base; end
6
+
7
+ class MissingConfiguredIdentityProvider < AccountConfigurationError
8
+ def initialize(domain: 'The requested domain')
9
+ @domain = domain
10
+ end
11
+
12
+ def message
13
+ "#{@domain} has no configured Identity Provider. " \
14
+ 'SAML configuartion must be finalized before a user ' \
15
+ 'for this domain can sign in with SSO.'
16
+ end
17
+ end
18
+ end
19
+ end
@@ -2,9 +2,15 @@
2
2
 
3
3
  module Osso
4
4
  module Error
5
+ class Base < StandardError
6
+ def docs_url
7
+ nil
8
+ end
9
+ end
5
10
  end
6
11
  end
7
12
 
13
+ require_relative 'account_configuration_error'
8
14
  require_relative 'missing_saml_attribute_error'
9
15
  require_relative 'oauth_error'
10
16
  require_relative 'saml_config_error'
@@ -2,7 +2,7 @@
2
2
 
3
3
  module Osso
4
4
  module Error
5
- class MissingSamlAttributeError < StandardError; end
5
+ class MissingSamlAttributeError < Base; end
6
6
 
7
7
  class MissingSamlEmailAttributeError < MissingSamlAttributeError
8
8
  def message
@@ -2,27 +2,41 @@
2
2
 
3
3
  module Osso
4
4
  module Error
5
- class OAuthError < StandardError; end
5
+ class OAuthError < Base
6
+ def docs_url
7
+ 'https://ossoapp.com/docs/integration/oauth-consumption'
8
+ end
9
+ end
6
10
 
7
11
  class NoAccountForOAuthClientError < OAuthError
12
+ def initialize(domain: 'the requested domain')
13
+ @domain = domain
14
+ end
15
+
8
16
  def message
9
- 'No customer account exists for the requested domain and OAuth client pair.' \
10
- "Review our OAuth documentation, and check you're using the correct OAuth client identifier"
17
+ "No customer account exists for #{@domain} and OAuth client pair. " \
18
+ "Review our OAuth documentation, and check you're using the correct OAuth client identifier. " \
19
+ 'This usually suggests an engineering issue with your ENV variables.'
11
20
  end
12
21
  end
13
22
 
14
- class InvalidOAuthClientIdentifier < MissingSamlAttributeError
23
+ class InvalidOAuthClientIdentifier < OAuthError
15
24
  def message
16
- 'No OAuth client exists for the requested OAuth client identifier.' \
17
- "Review our OAuth documentation, and check you're using the correct OAuth client identifier"
25
+ 'No OAuth client exists for the requested OAuth client identifier. ' \
26
+ "Review our OAuth documentation, and ensure you're using a valid OAuth client identifier. " \
27
+ 'OAuth credentials may have been regenerated by your team.'
18
28
  end
19
29
  end
20
30
 
21
- class InvalidRedirectUri < MissingSamlAttributeError
31
+ class InvalidRedirectUri < OAuthError
32
+ def initialize(redirect_uri:)
33
+ @redirect_uri = redirect_uri
34
+ end
35
+
22
36
  def message
23
- 'Invalid Redirect URI for the requested OAuth client identifier.' \
24
- "Review our OAuth documentation, check you're using the correct OAuth client identifier " \
25
- 'and confirm your Redirect URI allow list.'
37
+ "The requested redirect URI #{@redirect_uri} is not on the allow-list for the rquested OAuth client identifier. " \
38
+ "Review our OAuth documentation, check you're using the correct OAuth client identifier, " \
39
+ 'and confirm your Redirect URI allow-list includes the appropriate URI(s).'
26
40
  end
27
41
  end
28
42
  end
@@ -2,7 +2,11 @@
2
2
 
3
3
  module Osso
4
4
  module Error
5
- class SamlConfigError < StandardError; end
5
+ class SamlConfigError < Base
6
+ def message
7
+ 'Something went wrong with your SAML configuration.'
8
+ end
9
+ end
6
10
 
7
11
  class InvalidACSURLError < SamlConfigError
8
12
  def message
@@ -4,10 +4,10 @@ module Osso
4
4
  module GraphQL
5
5
  module Types
6
6
  class IdentityProviderStatus < BaseEnum
7
- value('Pending', value: 'PENDING')
8
- value('Configured', value: 'CONFIGURED')
9
- value('Active', value: 'ACTIVE')
10
- value('Error', value: 'ERROR')
7
+ value('Pending', value: 'pending')
8
+ value('Configured', value: 'configured')
9
+ value('Active', value: 'active')
10
+ value('Error', value: 'error')
11
11
  end
12
12
  end
13
13
  end
@@ -66,7 +66,7 @@ module Osso
66
66
  end
67
67
 
68
68
  def token
69
- request.env['admin_token'] || session['admin_token'] || request['admin_token']
69
+ session['admin_token'] || request.env['HTTP_AUTHORIZATION'] || request.params['admin_token']
70
70
  end
71
71
 
72
72
  def chomp_token
@@ -6,6 +6,7 @@ module Osso
6
6
  module RouteMap
7
7
  def self.included(klass)
8
8
  klass.class_eval do
9
+
9
10
  use Osso::Admin
10
11
  use Osso::Auth
11
12
  use Osso::Oauth
@@ -13,7 +13,7 @@ module Osso
13
13
  has_many :identity_providers
14
14
 
15
15
  def single_provider?
16
- identity_providers.one?
16
+ identity_providers.not_pending.one?
17
17
  end
18
18
 
19
19
  def provider
@@ -10,6 +10,8 @@ module Osso
10
10
  before_save :set_status
11
11
  validate :sso_cert_valid
12
12
 
13
+ enum status: { pending: "PENDING", configured: 'CONFIGURED', active: "ACTIVE", error: "ERROR"}
14
+
13
15
  PEM_HEADER = "-----BEGIN CERTIFICATE-----\n"
14
16
  PEM_FOOTER = "\n-----END CERTIFICATE-----"
15
17
 
@@ -39,17 +41,15 @@ module Osso
39
41
  alias acs_url assertion_consumer_service_url
40
42
 
41
43
  def set_status
42
- return if status != 'PENDING'
43
-
44
- self.status = 'CONFIGURED' if sso_url && sso_cert
44
+ self.status = 'configured' if sso_url && sso_cert && pending?
45
45
  end
46
46
 
47
47
  def active!
48
- update(status: 'ACTIVE')
48
+ update(status: 'active')
49
49
  end
50
50
 
51
51
  def error!
52
- update(status: 'ERROR')
52
+ update(status: 'error')
53
53
  end
54
54
 
55
55
  def root_url
@@ -13,7 +13,7 @@ module Osso
13
13
  UUID_REGEXP =
14
14
  /[0-9a-f]{8}-[0-9a-f]{3,4}-[0-9a-f]{4}-[0-9a-f]{3,4}-[0-9a-f]{12}/.
15
15
  freeze
16
-
16
+
17
17
  use OmniAuth::Builder do
18
18
  OmniAuth::MultiProvider.register(
19
19
  self,
@@ -22,8 +22,12 @@ module Osso
22
22
  path_prefix: '/auth/saml',
23
23
  callback_suffix: 'callback',
24
24
  ) do |identity_provider_id, _env|
25
- Models::IdentityProvider.find(identity_provider_id).
25
+ Models::IdentityProvider.
26
+ not_pending.
27
+ find(identity_provider_id).
26
28
  saml_options
29
+ rescue
30
+ {}
27
31
  end
28
32
  end
29
33
 
@@ -31,12 +35,26 @@ module Osso
31
35
  OmniAuth::FailureEndpoint.new(env).redirect_to_failure
32
36
  end
33
37
 
34
- error do
35
- erb :error
36
- end
37
-
38
38
  namespace '/auth' do
39
39
  get '/failure' do
40
+ # ??? invalid ticket, warden throws, ugh
41
+
42
+ # confirmed:
43
+ # - a valid but wrong cert will throw here
44
+ # (OneLogin::RubySaml::ValidationError, Fingerprint mismatch)
45
+ # but an _invalid_ cert is not caught. we do validate certs on
46
+ # configuration, so this may be ok
47
+ #
48
+ # - a valid but wrong ACS URL will throw here. the urls
49
+ # are pretty complex, but it has come up
50
+ #
51
+ # - specifying the wrong "recipient" in your IDP. Only OL so far
52
+ # (OneLogin::RubySaml::ValidationError, The response was received
53
+ # at vcardme.com instead of
54
+ # http://localhost:9292/auth/saml/e54a9a92-b4b5-4ea5-b0e3-b1423eb20b76/callback)
55
+
56
+
57
+ @error = Osso::Error::SamlConfigError.new
40
58
  erb :error
41
59
  end
42
60
  # Enterprise users are sent here after authenticating against
@@ -52,10 +70,10 @@ module Osso
52
70
  )
53
71
 
54
72
  redirect(redirect_uri)
55
- rescue Osso::Error::InvalidACSURLError => e
73
+ rescue Osso::Error::Base => e
56
74
  @error = e
57
75
  erb :error
58
- end
76
+ end
59
77
  end
60
78
  end
61
79
  end
@@ -23,10 +23,11 @@ module Osso
23
23
 
24
24
  redirect "/auth/saml/#{enterprise.provider.id}" if enterprise.single_provider?
25
25
 
26
- @providers = enterprise.identity_providers
27
- erb :multiple_providers
26
+ @providers = enterprise.identity_providers.not_pending
27
+ erb :multiple_providers if @providers.count > 1
28
28
 
29
- rescue Osso::Error::OAuthError => e
29
+ raise Osso::Error::MissingConfiguredIdentityProvider.new(domain: params[:domain])
30
+ rescue Osso::Error::Base => e
30
31
  @error = e
31
32
  erb :error
32
33
  end
@@ -64,7 +65,7 @@ module Osso
64
65
  includes(:identity_providers).
65
66
  find_by!(domain: domain, oauth_client_id: client_id)
66
67
  rescue ActiveRecord::RecordNotFound
67
- raise Osso::Error::NoAccountForOAuthClientError
68
+ raise Osso::Error::NoAccountForOAuthClientError.new(domain: params[:domain])
68
69
  end
69
70
 
70
71
  def find_client(identifier)
@@ -80,7 +81,7 @@ module Osso
80
81
  session[:osso_oauth_state] = params[:state]
81
82
  end.call(env)
82
83
  rescue Rack::OAuth2::Server::Authorize::BadRequest
83
- raise Osso::Error::InvalidRedirectUri
84
+ raise Osso::Error::InvalidRedirectUri.new(redirect_uri: params[:redirect_uri])
84
85
  end
85
86
  end
86
87
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Osso
4
- VERSION = '0.0.5-epsilon'
4
+ VERSION = '0.0.5-eta'
5
5
  end
@@ -11,7 +11,8 @@ FactoryBot.define do
11
11
  factory :enterprise_with_okta, parent: :enterprise_account do
12
12
  after :create do |enterprise|
13
13
  create(
14
- :okta_identity_provider,
14
+ :configured_identity_provider,
15
+ service: 'OKTA',
15
16
  domain: enterprise.domain,
16
17
  enterprise_account_id: enterprise.id,
17
18
  )
@@ -21,7 +22,8 @@ FactoryBot.define do
21
22
  factory :enterprise_with_azure, parent: :enterprise_account do
22
23
  after :create do |enterprise|
23
24
  create(
24
- :azure_identity_provider,
25
+ :configured_identity_provider,
26
+ service: 'AZURE',
25
27
  domain: enterprise.domain,
26
28
  enterprise_account_id: enterprise.id,
27
29
  )
@@ -31,13 +33,15 @@ FactoryBot.define do
31
33
  factory :enterprise_with_multiple_providers, parent: :enterprise_account do
32
34
  after :create do |enterprise|
33
35
  create(
34
- :okta_identity_provider,
36
+ :configured_identity_provider,
37
+ service: 'OKTA',
35
38
  domain: enterprise.domain,
36
39
  enterprise_account_id: enterprise.id,
37
40
  )
38
41
 
39
42
  create(
40
- :azure_identity_provider,
43
+ :configured_identity_provider,
44
+ service: 'AZURE',
41
45
  domain: enterprise.domain,
42
46
  enterprise_account_id: enterprise.id,
43
47
  )
@@ -8,13 +8,21 @@ describe Osso::Helpers::Auth do
8
8
  end
9
9
 
10
10
  subject(:app) do
11
- Class.new { include Osso::Helpers::Auth }
11
+ Class.new {
12
+ include Osso::Helpers::Auth
13
+ }
12
14
  end
13
15
 
14
16
  describe 'with the token as a header' do
15
17
  before do
16
18
  allow_any_instance_of(subject).to receive(:request) do
17
- double('Request', env: { 'admin_token' => token }, post?: false)
19
+ double('Request', env: { 'HTTP_AUTHORIZATION' => token }, post?: false)
20
+ end
21
+
22
+ allow_any_instance_of(subject).to receive(:session) do
23
+ {
24
+ admin_token: nil
25
+ }
18
26
  end
19
27
 
20
28
  allow_any_instance_of(subject).to receive(:redirect) do
@@ -87,6 +95,170 @@ describe Osso::Helpers::Auth do
87
95
  end
88
96
  end
89
97
 
98
+ describe 'with the token as a parameter' do
99
+ before do
100
+ allow_any_instance_of(subject).to receive(:request) do
101
+ double('Request', env: {}, params: { 'admin_token' => token }, post?: false)
102
+ end
103
+
104
+ allow_any_instance_of(subject).to receive(:session) do
105
+ {
106
+ admin_token: nil
107
+ }
108
+ end
109
+
110
+ allow_any_instance_of(subject).to receive(:redirect) do
111
+ false
112
+ end
113
+ end
114
+
115
+ describe 'with an admin token' do
116
+ let(:token) { encode({ scope: 'admin' }) }
117
+
118
+ it 'allows #token_protected! methods' do
119
+ expect(subject.new.token_protected!).to_not be(false)
120
+ end
121
+
122
+ it 'allows #enterprise_protected! methods' do
123
+ expect(subject.new.enterprise_protected!).to_not be(false)
124
+ end
125
+
126
+ it 'allows #internal_protected! methods' do
127
+ expect(subject.new.internal_protected!).to_not be(false)
128
+ end
129
+
130
+ it 'allows #admin_protected! methods' do
131
+ expect(subject.new.admin_protected!).to_not be(false)
132
+ end
133
+ end
134
+
135
+ describe 'with an internal token' do
136
+ let(:token) { encode({ scope: 'internal' }) }
137
+
138
+ it 'allows #token_protected! methods' do
139
+ expect(subject.new.token_protected!).to_not be(false)
140
+ end
141
+
142
+ it 'allows #enterprise_protected! methods' do
143
+ expect(subject.new.enterprise_protected!).to_not be(false)
144
+ end
145
+
146
+ it 'allows #internal_protected! methods' do
147
+ expect(subject.new.internal_protected!).to_not be(false)
148
+ end
149
+
150
+ it 'allows #admin_protected! methods' do
151
+ expect(subject.new.admin_protected!).to be(false)
152
+ end
153
+ end
154
+
155
+ describe 'with an end-user token' do
156
+ let(:token) { encode({ scope: 'end-user', email: 'user@example.com' }) }
157
+
158
+ it 'allows #token_protected! methods' do
159
+ expect(subject.new.token_protected!).to_not be(false)
160
+ end
161
+
162
+ it 'allows #enterprise_protected! methods for the scoped domain' do
163
+ expect(subject.new.enterprise_protected!('example.com')).to_not be(false)
164
+ end
165
+
166
+ it 'halts #enterprise_protected! methods for the wrong scoped domain' do
167
+ expect(subject.new.enterprise_protected!('foo.com')).to be(false)
168
+ end
169
+
170
+ it 'halts #internal_protected! methods' do
171
+ expect(subject.new.internal_protected!).to be(false)
172
+ end
173
+
174
+ it 'halts #admin_protected! methods' do
175
+ expect(subject.new.admin_protected!).to be(false)
176
+ end
177
+ end
178
+ end
179
+
180
+ describe 'with the token in session' do
181
+ before do
182
+ allow_any_instance_of(subject).to receive(:request) do
183
+ double('Request', env: {}, params: {}, post?: false)
184
+ end
185
+
186
+ allow_any_instance_of(subject).to receive(:redirect) do
187
+ false
188
+ end
189
+
190
+ allow_any_instance_of(subject).to receive(:session).and_return(
191
+ {admin_token: token}.with_indifferent_access
192
+ )
193
+
194
+ end
195
+
196
+ describe 'with an admin token' do
197
+ let(:token) { encode({ scope: 'admin' }) }
198
+
199
+
200
+ it 'allows #token_protected! methods' do
201
+ expect(subject.new.token_protected!).to_not be(false)
202
+ end
203
+
204
+ it 'allows #enterprise_protected! methods' do
205
+ expect(subject.new.enterprise_protected!).to_not be(false)
206
+ end
207
+
208
+ it 'allows #internal_protected! methods' do
209
+ expect(subject.new.internal_protected!).to_not be(false)
210
+ end
211
+
212
+ it 'allows #admin_protected! methods' do
213
+ expect(subject.new.admin_protected!).to_not be(false)
214
+ end
215
+ end
216
+
217
+ describe 'with an internal token' do
218
+ let(:token) { encode({ scope: 'internal' }) }
219
+
220
+ it 'allows #token_protected! methods' do
221
+ expect(subject.new.token_protected!).to_not be(false)
222
+ end
223
+
224
+ it 'allows #enterprise_protected! methods' do
225
+ expect(subject.new.enterprise_protected!).to_not be(false)
226
+ end
227
+
228
+ it 'allows #internal_protected! methods' do
229
+ expect(subject.new.internal_protected!).to_not be(false)
230
+ end
231
+
232
+ it 'allows #admin_protected! methods' do
233
+ expect(subject.new.admin_protected!).to be(false)
234
+ end
235
+ end
236
+
237
+ describe 'with an end-user token' do
238
+ let(:token) { encode({ scope: 'end-user', email: 'user@example.com' }) }
239
+
240
+ it 'allows #token_protected! methods' do
241
+ expect(subject.new.token_protected!).to_not be(false)
242
+ end
243
+
244
+ it 'allows #enterprise_protected! methods for the scoped domain' do
245
+ expect(subject.new.enterprise_protected!('example.com')).to_not be(false)
246
+ end
247
+
248
+ it 'halts #enterprise_protected! methods for the wrong scoped domain' do
249
+ expect(subject.new.enterprise_protected!('foo.com')).to be(false)
250
+ end
251
+
252
+ it 'halts #internal_protected! methods' do
253
+ expect(subject.new.internal_protected!).to be(false)
254
+ end
255
+
256
+ it 'halts #admin_protected! methods' do
257
+ expect(subject.new.admin_protected!).to be(false)
258
+ end
259
+ end
260
+ end
261
+
90
262
  def encode(payload)
91
263
  JWT.encode(
92
264
  payload,
@@ -3,6 +3,9 @@
3
3
  require 'spec_helper'
4
4
 
5
5
  describe Osso::Auth do
6
+ before do
7
+ described_class.set(:views, spec_views)
8
+ end
6
9
  describe 'get /auth/saml/:uuid' do
7
10
  describe 'for an Okta SAML provider' do
8
11
  let(:enterprise) { create(:enterprise_with_okta) }
@@ -108,7 +111,7 @@ describe Osso::Auth do
108
111
  'omniauth.auth' => OmniAuth.config.mock_auth[:saml],
109
112
  },
110
113
  )
111
- expect(okta_provider.reload.status).to eq('ACTIVE')
114
+ expect(okta_provider.reload.status).to eq('active')
112
115
  end
113
116
  end
114
117
  end
@@ -143,7 +146,7 @@ describe Osso::Auth do
143
146
  },
144
147
  )
145
148
 
146
- expect(azure_provider.reload.status).to eq('ACTIVE')
149
+ expect(azure_provider.reload.status).to eq('active')
147
150
  end
148
151
  end
149
152
 
@@ -179,29 +182,30 @@ describe Osso::Auth do
179
182
  it 'raises an error when email is missing' do
180
183
  mock_saml_omniauth(email: nil, id: SecureRandom.uuid)
181
184
 
182
- expect do
183
- post(
185
+
186
+ response = post(
184
187
  "/auth/saml/#{azure_provider.id}/callback",
185
188
  nil,
186
189
  {
187
190
  'omniauth.auth' => OmniAuth.config.mock_auth[:saml],
188
191
  },
189
192
  )
190
- end.to raise_error(Osso::Error::MissingSamlEmailAttributeError)
191
- end
193
+
194
+ expect(response.body).to eq('Osso::Error::MissingSamlEmailAttributeError')
195
+ end
192
196
 
193
197
  it 'raises an error when id is missing' do
194
198
  mock_saml_omniauth(email: Faker::Internet.email, id: nil)
195
199
 
196
- expect do
197
- post(
200
+ response = post(
198
201
  "/auth/saml/#{azure_provider.id}/callback",
199
202
  nil,
200
203
  {
201
204
  'omniauth.auth' => OmniAuth.config.mock_auth[:saml],
202
205
  },
203
206
  )
204
- end.to raise_error(Osso::Error::MissingSamlIdAttributeError)
207
+
208
+ expect(response.body).to eq('Osso::Error::MissingSamlIdAttributeError')
205
209
  end
206
210
  end
207
211
  end
@@ -0,0 +1 @@
1
+ <%= @error %>
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: osso
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.5.pre.epsilon
4
+ version: 0.0.5.pre.eta
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sam Bauch
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-09-19 00:00:00.000000000 Z
11
+ date: 2020-09-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -273,6 +273,7 @@ files:
273
273
  - lib/osso/db/migrate/20200826201852_create_app_config.rb
274
274
  - lib/osso/db/migrate/20200913154919_add_one_login_to_identity_provider_service_enum.rb
275
275
  - lib/osso/db/migrate/20200916125543_add_google_to_identity_provider_service_enum.rb
276
+ - lib/osso/error/account_configuration_error.rb
276
277
  - lib/osso/error/error.rb
277
278
  - lib/osso/error/missing_saml_attribute_error.rb
278
279
  - lib/osso/error/oauth_error.rb