osso 0.0.3.26 → 0.0.3.27

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: cb9f3d69563582f827ee2bca6484354ef751f2f4a47078227756a866b5bf59b0
4
- data.tar.gz: da7fa02b67baf9c336d380bb3798874375b8580d6e414cc29193143ab7b33bb0
3
+ metadata.gz: 61667cd9c9821cbbd903bd5ea753dfb67338a801e442b5e7ce21d77e06e2ada6
4
+ data.tar.gz: ef180637bd4da14905549a161e153e4a7b6b1dc9b9079d0e98952f7730e6d6ba
5
5
  SHA512:
6
- metadata.gz: 2e4eff9a9f7c39460bd0691e6c5f67464e2350e36477d90f10ac1cc47277347f17c1a2a20ec61aff2194a630dc651a1d5f7ebaa3855af09829aaa4f5021a4fb6
7
- data.tar.gz: 2f990d6ced375400d60a06200e3f14758c6574657cfd16509e6239511f0f4622bad5106ed1a819089dbf356b9e3612952682b1a52bdd7b450a0f6b8d26f00d56
6
+ metadata.gz: 59dde627b70d7f46a680dbf00ae260cd98613a679daaf14a2a08e7ce6aef7ab627ecf8b1ba8a459438b518f85e24b2db1e63375814c526f12733284fbbdc5a78
7
+ data.tar.gz: '09a8f59725b4a61aad3a92e8a676377d798049da26951882903c40a8ab7e2945e153097d4e94d896dc601d1d1fc01f518d05adc58af141ce56bc4a12697f40ab'
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- osso (0.0.3.26)
4
+ osso (0.0.3.27)
5
5
  activesupport (>= 6.0.3.2)
6
6
  graphql
7
7
  jwt
@@ -11,8 +11,23 @@ module Osso
11
11
  data.merge(errors: [])
12
12
  end
13
13
 
14
- def response_error(error)
15
- error.merge(data: nil)
14
+ def response_error(errors)
15
+ raise ::GraphQL::ExecutionError.new(
16
+ 'Mutation error',
17
+ extensions: {
18
+ 'errors' => field_errors(errors),
19
+ }
20
+ )
21
+ end
22
+
23
+ def field_errors(errors)
24
+ errors.map do |attribute, messages|
25
+ attribute = attribute.to_s.camelize(:lower)
26
+ {
27
+ attribute: attribute,
28
+ message: messages,
29
+ }
30
+ end
16
31
  end
17
32
 
18
33
  def ready?(**args)
@@ -10,15 +10,14 @@ module Osso
10
10
  argument :sso_url, String, required: false
11
11
  argument :sso_cert, String, required: false
12
12
 
13
- field :identity_provider, Types::IdentityProvider, null: false
14
- field :errors, [String], null: false
13
+ field :identity_provider, Types::IdentityProvider, null: true
15
14
 
16
15
  def resolve(**args)
17
16
  provider = identity_provider(**args)
18
17
 
19
18
  return response_data(identity_provider: provider) if provider.update(args)
20
-
21
- response_error(errors: provider.errors.messages)
19
+
20
+ response_error(provider.errors)
22
21
  end
23
22
 
24
23
  def domain(**args)
@@ -19,7 +19,7 @@ module Osso
19
19
 
20
20
  return response_data(enterprise_account: enterprise_account) if enterprise_account.save
21
21
 
22
- response_error(errors: enterprise_account.errors.full_messages)
22
+ response_error(enterprise_account.errors)
23
23
  end
24
24
 
25
25
  def find_client_db_id(oauth_client_identifier)
@@ -23,7 +23,7 @@ module Osso
23
23
 
24
24
  return response_data(identity_provider: identity_provider) if identity_provider.save
25
25
 
26
- response_error(errors: identity_provider.errors.full_messages)
26
+ response_error(identity_provider.errors)
27
27
  end
28
28
 
29
29
  def domain(**args)
@@ -16,7 +16,7 @@ module Osso
16
16
 
17
17
  return response_data(oauth_client: oauth_client) if oauth_client.save
18
18
 
19
- response_error(errors: oauth_client.errors.full_messages)
19
+ response_error(oauth_client.errors)
20
20
  end
21
21
 
22
22
  def ready?(*)
@@ -20,7 +20,7 @@ module Osso
20
20
 
21
21
  return response_data(enterprise_account: nil) if customer.destroy
22
22
 
23
- response_error(errors: customer.errors.full_messages)
23
+ response_error(customer.errors)
24
24
  end
25
25
 
26
26
  def domain(**args)
@@ -16,7 +16,7 @@ module Osso
16
16
 
17
17
  return response_data(oauth_client: nil) if oauth_client.destroy
18
18
 
19
- response_error(errors: oauth_client.errors.full_messages)
19
+ response_error(oauth_client.errors)
20
20
  end
21
21
 
22
22
  def ready?(*)
@@ -17,7 +17,7 @@ module Osso
17
17
 
18
18
  return response_data(oauth_client: oauth_client) if oauth_client.save
19
19
 
20
- response_error(errors: oauth_client.errors.full_messages)
20
+ response_error(oauth_client.errors)
21
21
  end
22
22
 
23
23
  def ready?(*)
@@ -20,7 +20,7 @@ module Osso
20
20
 
21
21
  response_data(oauth_client: oauth_client.reload)
22
22
  rescue StandardError => e
23
- response_error(errors: e)
23
+ response_error(e)
24
24
  end
25
25
 
26
26
  def ready?(*)
@@ -33,17 +33,17 @@ module Osso
33
33
 
34
34
  if updating_index
35
35
  updating = redirect_uris.delete_at(updating_index)
36
- redirect.update(updating.to_h)
36
+ redirect.update!(updating.to_h)
37
37
  next
38
38
  end
39
39
 
40
- redirect.destroy
40
+ redirect.destroy!
41
41
  end
42
42
  end
43
43
 
44
44
  def create_new(oauth_client, redirect_uris)
45
45
  redirect_uris.map do |uri|
46
- oauth_client.redirect_uris.create(uri.to_h.without(:id))
46
+ oauth_client.redirect_uris.create!(uri.to_h.without(:id))
47
47
  end
48
48
  end
49
49
  end
@@ -17,7 +17,7 @@ module Osso
17
17
  app_config = Osso::Models::AppConfig.find
18
18
  return response_data(app_config: app_config) if app_config.update(**args)
19
19
 
20
- response_error(errors: e)
20
+ response_error(app_config.errors)
21
21
  end
22
22
 
23
23
  def ready?(*)
@@ -11,6 +11,7 @@ require_relative 'types/base_enum'
11
11
  require_relative 'types/base_input_object'
12
12
  require_relative 'types/admin_user'
13
13
  require_relative 'types/app_config'
14
+ require_relative 'types/error'
14
15
  require_relative 'types/identity_provider_service'
15
16
  require_relative 'types/identity_provider_status'
16
17
  require_relative 'types/identity_provider'
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'graphql'
4
+
5
+ module Osso
6
+ module GraphQL
7
+ module Types
8
+ class Error < Types::BaseObject
9
+ description 'A mutation error'
10
+
11
+ field :attribute, String, null: false
12
+ field :message, String, null: false
13
+
14
+ def self.authorized?(_object, _context)
15
+ true
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
@@ -8,6 +8,10 @@ module Osso
8
8
  belongs_to :oauth_client
9
9
  has_many :users
10
10
  before_save :set_status
11
+ validate :sso_cert_valid
12
+
13
+ PEM_HEADER = "-----BEGIN CERTIFICATE-----\n"
14
+ PEM_FOOTER = "\n-----END CERTIFICATE-----"
11
15
 
12
16
  def name
13
17
  service.titlecase
@@ -53,6 +57,22 @@ module Osso
53
57
 
54
58
  ENV.fetch('BASE_URL')
55
59
  end
60
+
61
+ def sso_cert_valid
62
+ return if sso_cert.blank?
63
+
64
+ has_header_and_footer = sso_cert.match(/#{PEM_HEADER}(?<cert>.*)#{PEM_FOOTER}/m)
65
+
66
+ if has_header_and_footer
67
+ OpenSSL::X509::Certificate.new(sso_cert)
68
+ self.sso_cert = has_header_and_footer[:cert]
69
+ else
70
+ OpenSSL::X509::Certificate.new([PEM_HEADER, sso_cert, PEM_FOOTER].join)
71
+ end
72
+
73
+ rescue OpenSSL::X509::CertificateError
74
+ errors.add(:sso_cert, 'x509 Certificate is malformed')
75
+ end
56
76
  end
57
77
  end
58
78
  end
@@ -41,6 +41,7 @@ module Osso
41
41
  provider = Models::IdentityProvider.find(params[:id])
42
42
  @oauth_client = provider.oauth_client
43
43
 
44
+ # TODO: PORC for validating attributes
44
45
  attributes = env['omniauth.auth']&.
45
46
  extra&.
46
47
  response_object&.
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Osso
4
- VERSION = '0.0.3.26'
4
+ VERSION = '0.0.3.27'
5
5
  end
@@ -12,7 +12,7 @@ describe Osso::GraphQL::Schema do
12
12
  id: identity_provider.id,
13
13
  service: 'OKTA',
14
14
  ssoUrl: 'https://example.com',
15
- ssoCert: 'BEGIN_CERTIFICATE',
15
+ ssoCert: valid_x509_pem,
16
16
  },
17
17
  }
18
18
  end
@@ -35,4 +35,25 @@ describe Osso::Models::IdentityProvider do
35
35
  )
36
36
  end
37
37
  end
38
+
39
+ describe '#validate_sso_cert' do
40
+ it 'rejects an invalid cert' do
41
+ subject.update(sso_cert: 'bad-cert')
42
+
43
+ expect(subject.errors.full_messages.first).to include('x509 Certificate is malformed')
44
+ end
45
+
46
+ it 'massages a cert with header and footer' do
47
+ subject.update(sso_cert: valid_x509_pem)
48
+
49
+ expect(subject.errors).to be_empty
50
+ expect(subject.sso_cert).to_not include('BEGIN CERTIFICATE')
51
+ end
52
+
53
+ it 'accepts a cert without header and footer' do
54
+ subject.update(sso_cert: raw_x509_string)
55
+
56
+ expect(subject.errors).to be_empty
57
+ end
58
+ end
38
59
  end
@@ -21,6 +21,9 @@ require File.expand_path '../lib/osso.rb', __dir__
21
21
  require File.expand_path 'support/spec_app', __dir__
22
22
 
23
23
  module RSpecMixin
24
+ PEM_HEADER = "-----BEGIN CERTIFICATE-----\n"
25
+ PEM_FOOTER = "\n-----END CERTIFICATE-----"
26
+
24
27
  include Rack::Test::Methods
25
28
 
26
29
  def app
@@ -46,6 +49,16 @@ module RSpecMixin
46
49
  def spec_views
47
50
  File.dirname(__FILE__) + '/support/views'
48
51
  end
52
+
53
+ def valid_x509_pem
54
+ raw = File.read(File.dirname(__FILE__) + '/support/fixtures/test.pem')
55
+ OpenSSL::X509::Certificate.new(raw).to_pem
56
+ end
57
+
58
+ def raw_x509_string
59
+ raw = valid_x509_pem.match(/#{PEM_HEADER}(?<cert>.*)#{PEM_FOOTER}/m)
60
+ raw[:cert]
61
+ end
49
62
  end
50
63
 
51
64
  RSpec.configure do |config|
@@ -0,0 +1,30 @@
1
+ -----BEGIN PRIVATE KEY-----
2
+ MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBANDYf/XXreldztPH
3
+ 0IJSkvgeQVZCu1ie+D2Ij9nEzJAuM10bD4p2IjI8EQUKUTn1OBbX4ykhn5Ovw9SU
4
+ D8qEllQCzq7zuX54BEm8cHX3IXTpMLM90T2zJayS+3hQqXHzGXeX3fuP1KhNrrkL
5
+ HAlDEtVD/vwIci/TS2Mep7weytOjAgMBAAECgYA23kpwCmQUhaLLHRn4wzz9luVP
6
+ hmS2Gb3aXMB+VCfyUVEJSwzAMd02GXXXPyir83Ly/XEe40iLgogOl3+2kzLzEegI
7
+ 1wx9mydlar0kBIDKJkYdnikbvy0IKFNXRxqHl0Oecy9lArDKmBmadYsse8hsZLX2
8
+ eZUmB8G50TeDyz/4gQJBAO1OM4dT/Uo/zTaTDMs7A+td1C4gvjpI7aKPwHdwmvoc
9
+ dQN9BKoAV0EMoUcXvAeVreWEYGZrMwXQB6xT7aydyUMCQQDhTFffVlvsqOmQYhzf
10
+ lbKS8orI0SZZHz8F5dnj1zwb4Xp+hl6tIAkxcZ1DxP4emfc1htd4GswzNqSVfFJv
11
+ JXYhAkEAsmdWSekUxVtN9jd7KNbHTY2O1Nb87GijbtFPyvu3J015kxPMC9qRvm+2
12
+ V/I6BCG9SI3Kw3TYOQh6nE3Eoz9EbQJBAKvzm4F+pOwsQw8KguT2mPNkoB4C2xTc
13
+ LzquIi2t4VeaMOaOYYYa1EljYFcP66+pbS7yOlOViFJyGw1odHYWDmECQCBGi7f5
14
+ qT4Bs3DoaIyD0w9F3LY/ny7+Pa7WGUqQvQWygUDObBtwojXhg/A9BGckUrQ2jmu/
15
+ bhqnqQJs3f05ETA=
16
+ -----END PRIVATE KEY-----
17
+ -----BEGIN CERTIFICATE-----
18
+ MIICDTCCAXYCCQCm0tqsG7zO2TANBgkqhkiG9w0BAQsFADBLMQswCQYDVQQGEwJV
19
+ UzERMA8GA1UECAwITmV3IFlvcmsxETAPBgNVBAcMCEJyb29rbHluMRYwFAYDVQQK
20
+ DA1FbnRlcnByaXNlT1NTMB4XDTIwMDkwMjE0MTEyMVoXDTIxMDkwMjE0MTEyMVow
21
+ SzELMAkGA1UEBhMCVVMxETAPBgNVBAgMCE5ldyBZb3JrMREwDwYDVQQHDAhCcm9v
22
+ a2x5bjEWMBQGA1UECgwNRW50ZXJwcmlzZU9TUzCBnzANBgkqhkiG9w0BAQEFAAOB
23
+ jQAwgYkCgYEA0Nh/9det6V3O08fQglKS+B5BVkK7WJ74PYiP2cTMkC4zXRsPinYi
24
+ MjwRBQpROfU4FtfjKSGfk6/D1JQPyoSWVALOrvO5fngESbxwdfchdOkwsz3RPbMl
25
+ rJL7eFCpcfMZd5fd+4/UqE2uuQscCUMS1UP+/AhyL9NLYx6nvB7K06MCAwEAATAN
26
+ BgkqhkiG9w0BAQsFAAOBgQDGze/POq+GSwOIYftr83+YkNTIQAg+bl8hiFMtJ3OV
27
+ buFsI/oUGaKloXOrDLbygk+lvimFbj36k3IhwRI7iXJDCwZGxtVCC4+8VNqqT1Yj
28
+ uZT9xHGYVszzGc8nz4wcaQ8M/W4mCuXet1qDwAi0Zo9yLBnyEdc6pluDdJuz0cg6
29
+ xQ==
30
+ -----END CERTIFICATE-----
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.3.26
4
+ version: 0.0.3.27
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-01 00:00:00.000000000 Z
11
+ date: 2020-09-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -231,7 +231,6 @@ executables:
231
231
  extensions: []
232
232
  extra_rdoc_files: []
233
233
  files:
234
- - ".DS_Store"
235
234
  - ".buildkite/hooks/environment"
236
235
  - ".buildkite/hooks/pre-command"
237
236
  - ".buildkite/pipeline.yml"
@@ -299,6 +298,7 @@ files:
299
298
  - lib/osso/graphql/types/base_input_object.rb
300
299
  - lib/osso/graphql/types/base_object.rb
301
300
  - lib/osso/graphql/types/enterprise_account.rb
301
+ - lib/osso/graphql/types/error.rb
302
302
  - lib/osso/graphql/types/identity_provider.rb
303
303
  - lib/osso/graphql/types/identity_provider_service.rb
304
304
  - lib/osso/graphql/types/identity_provider_status.rb
@@ -346,14 +346,13 @@ files:
346
346
  - spec/graphql/query/identity_provider_spec.rb
347
347
  - spec/graphql/query/oauth_clients_spec.rb
348
348
  - spec/helpers/auth_spec.rb
349
- - spec/models/azure_saml_provider_spec.rb
350
349
  - spec/models/identity_provider_spec.rb
351
- - spec/models/okta_saml_provider_spec.rb
352
350
  - spec/routes/admin_spec.rb
353
351
  - spec/routes/app_spec.rb
354
352
  - spec/routes/auth_spec.rb
355
353
  - spec/routes/oauth_spec.rb
356
354
  - spec/spec_helper.rb
355
+ - spec/support/fixtures/test.pem
357
356
  - spec/support/spec_app.rb
358
357
  - spec/support/views/admin.erb
359
358
  - spec/support/views/error.erb
@@ -1,19 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'spec_helper'
4
-
5
- # describe Osso::Models::AzureSamlProvider do
6
- # subject { create(:azure_identity_provider) }
7
-
8
- # describe '#saml_options' do
9
- # it 'returns the required args' do
10
- # expect(subject.saml_options).
11
- # to match(
12
- # domain: subject.domain,
13
- # idp_cert: subject.idp_cert,
14
- # idp_sso_target_url: subject.idp_sso_target_url,
15
- # issuer: "id:#{subject.id}",
16
- # )
17
- # end
18
- # end
19
- # end
@@ -1,20 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'spec_helper'
4
-
5
- # describe Osso::Models::OktaSamlProvider do
6
- # subject { create(:okta_identity_provider) }
7
-
8
- # describe '#saml_options' do
9
- # it 'returns the required args' do
10
- # expect(subject.saml_options).
11
- # to match(
12
- # domain: subject.domain,
13
- # idp_cert: subject.idp_cert,
14
- # idp_sso_target_url: subject.idp_sso_target_url,
15
- # issuer: subject.id,
16
- # name_identifier_format: described_class::NAME_FORMAT,
17
- # )
18
- # end
19
- # end
20
- # end