maestrano-connector-rails 2.1.3 → 2.2.0

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 (34) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +2 -2
  3. data/.rubocop_todo.yml +11 -19
  4. data/.travis.yml +7 -0
  5. data/Gemfile +8 -0
  6. data/app/controllers/maestrano/api/account_controller.rb +9 -0
  7. data/app/controllers/maestrano/api/api_controller.rb +42 -0
  8. data/app/controllers/maestrano/api/concerns/account_controller.rb +61 -0
  9. data/app/controllers/maestrano/api/id_maps_controller.rb +6 -0
  10. data/app/controllers/maestrano/api/organizations_controller.rb +6 -0
  11. data/app/controllers/maestrano/api/synchronizations_controller.rb +6 -0
  12. data/app/controllers/maestrano/api/users_controller.rb +6 -0
  13. data/app/controllers/maestrano/synchronizations_controller.rb +3 -0
  14. data/app/helpers/maestrano/connector/rails/session_helper.rb +1 -1
  15. data/app/jobs/maestrano/connector/rails/push_to_connec_worker.rb +0 -1
  16. data/app/policies/maestrano/connector/rails/application_policy.rb +63 -0
  17. data/app/policies/maestrano/connector/rails/id_map_policy.rb +9 -0
  18. data/app/policies/maestrano/connector/rails/organization_policy.rb +7 -0
  19. data/app/policies/maestrano/connector/rails/synchronization_policy.rb +9 -0
  20. data/app/policies/maestrano/connector/rails/user_policy.rb +7 -0
  21. data/app/resources/maestrano/api/base_resource.rb +67 -0
  22. data/app/resources/maestrano/api/id_map_resource.rb +38 -0
  23. data/app/resources/maestrano/api/organization_resource.rb +43 -0
  24. data/app/resources/maestrano/api/synchronization_resource.rb +19 -0
  25. data/app/resources/maestrano/api/user_resource.rb +23 -0
  26. data/config/initializers/json_api.rb +59 -0
  27. data/config/routes.rb +11 -0
  28. data/lib/generators/connector/install_generator.rb +4 -1
  29. data/lib/generators/connector/templates/account_controller.rb +22 -0
  30. data/lib/maestrano/connector/rails/version.rb +1 -1
  31. data/lib/testing_support/shared_examples/json_api_controller.rb +16 -0
  32. data/lib/testing_support/shared_examples/shared_pundit_example.rb +12 -0
  33. data/maestrano-connector-rails.gemspec +5 -3
  34. metadata +73 -9
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 7584b14f55bfa93f3c87fe25af6b3e39ef682d21
4
- data.tar.gz: 0f6fe8db8fd9b034975e302a33c0347750e8010d
3
+ metadata.gz: 6aacb721d865456e02851131b118f16891870268
4
+ data.tar.gz: ab5b6a2fa521f79c7e42d8028387504d0a6e5929
5
5
  SHA512:
6
- metadata.gz: f5cccf86f6b684398321102b4cc8adbf1fd3ff12afbf4cd036f870c8ee4338c0d44970a99ce01f0b533998b32f97b1d63271ee72a717f1746936df55f96ea714
7
- data.tar.gz: 0e24c79572f5675f261ada81e53632a1605a13a22f01f887887d7ea21054e9c502068bb898c02b8ef8445d39b6b9bc7de3e522fa7b43bd24e28d8f2a3d7b40cc
6
+ metadata.gz: 824bde6273b0f0bcecfd4a8b390c14851860cae5c5cc36ff133fbbbdd1b58105f8614244fc198dc0d1e28ba199790e2527399a3fa9764629aeac82957e135a65
7
+ data.tar.gz: 7f62f2ace833c722ee02fc37228393b054f119a6634cfdc8dbf263e9e5ec882b9f610d88c391a67222da19b8f12998c8b2df7d73123846ce907d61b4eedb8105
@@ -29,7 +29,7 @@ Metrics/LineLength:
29
29
  Metrics/MethodLength:
30
30
  Max: 50
31
31
 
32
- Style/IndentationConsistency:
32
+ Layout/IndentationConsistency:
33
33
  EnforcedStyle: rails
34
34
 
35
35
  # Missing top-level class documentation comment
@@ -40,7 +40,7 @@ Style/ClassAndModuleChildren:
40
40
  Enabled: false
41
41
 
42
42
  # Space inside braces => only for blocks (not for literal)
43
- Style/SpaceInsideHashLiteralBraces:
43
+ Layout/SpaceInsideHashLiteralBraces:
44
44
  EnforcedStyle: no_space
45
45
 
46
46
  # Checks for unused block arguments
@@ -1,6 +1,6 @@
1
1
  # This configuration was generated by
2
2
  # `rubocop --auto-gen-config`
3
- # on 2017-06-06 10:23:17 +0100 using RuboCop version 0.45.0.
3
+ # on 2017-09-19 10:17:44 +0100 using RuboCop version 0.49.1.
4
4
  # The point is for the user to remove these configuration records
5
5
  # one by one as the offenses are removed from the code base.
6
6
  # Note that changes in the inspected code, or installation of new
@@ -28,7 +28,7 @@ Metrics/CyclomaticComplexity:
28
28
  # Offense count: 3
29
29
  # Configuration parameters: CountComments.
30
30
  Metrics/ModuleLength:
31
- Max: 217
31
+ Max: 212
32
32
 
33
33
  # Offense count: 2
34
34
  # Configuration parameters: CountKeywordArgs.
@@ -46,6 +46,14 @@ Performance/FlatMap:
46
46
  Exclude:
47
47
  - 'app/models/maestrano/connector/rails/concerns/complex_entity.rb'
48
48
 
49
+ # Offense count: 1
50
+ # Cop supports --auto-correct.
51
+ # Configuration parameters: Whitelist.
52
+ # Whitelist: find_by_sql
53
+ Rails/DynamicFindBy:
54
+ Exclude:
55
+ - 'app/controllers/maestrano/api/api_controller.rb'
56
+
49
57
  # Offense count: 6
50
58
  # Configuration parameters: EnforcedStyle, SupportedStyles.
51
59
  # SupportedStyles: strict, flexible
@@ -81,15 +89,7 @@ Style/DoubleNegation:
81
89
  Exclude:
82
90
  - 'app/controllers/maestrano/auth/saml_controller.rb'
83
91
 
84
- # Offense count: 1
85
- # Cop supports --auto-correct.
86
- # Configuration parameters: EnforcedStyle, SupportedStyles.
87
- # SupportedStyles: empty_lines, empty_lines_except_namespace, no_empty_lines
88
- Style/EmptyLinesAroundModuleBody:
89
- Exclude:
90
- - 'app/jobs/maestrano/connector/rails/push_to_connec_worker.rb'
91
-
92
- # Offense count: 52
92
+ # Offense count: 56
93
93
  # Cop supports --auto-correct.
94
94
  # Configuration parameters: EnforcedStyle, SupportedStyles.
95
95
  # SupportedStyles: when_needed, always
@@ -113,11 +113,3 @@ Style/PredicateName:
113
113
  Style/RegexpLiteral:
114
114
  Exclude:
115
115
  - 'app/models/maestrano/connector/rails/concerns/entity.rb'
116
-
117
- # Offense count: 1
118
- # Cop supports --auto-correct.
119
- # Configuration parameters: EnforcedStyle, SupportedStyles.
120
- # SupportedStyles: final_newline, final_blank_line
121
- Style/TrailingBlankLines:
122
- Exclude:
123
- - 'app/helpers/maestrano/connector/rails/session_helper.rb'
@@ -0,0 +1,7 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.3
4
+ services:
5
+ - redis-server
6
+ before_install:
7
+ - gem install bundler # Update bundler version
data/Gemfile CHANGED
@@ -7,3 +7,11 @@ group :development do
7
7
  gem 'activerecord-jdbcsqlite3-adapter', platforms: :jruby
8
8
  gem 'sqlite3', platforms: :ruby
9
9
  end
10
+
11
+ group :test do
12
+ gem 'jsonapi-resources'
13
+ gem 'jsonapi-resources-matchers', require: false
14
+ gem 'pundit'
15
+ gem 'pundit-matchers'
16
+ gem 'pundit-resources'
17
+ end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Maestrano
4
+ module Api
5
+ class AccountController < ApiController
6
+ include Maestrano::Api::Concerns::AccountController
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,42 @@
1
+ module Maestrano
2
+ module Api
3
+ class ApiController < JSONAPI::ResourceController
4
+ protect_from_forgery
5
+ before_action :authenticate_client!
6
+
7
+ # Return the current API client (tenant)
8
+ attr_accessor :client
9
+
10
+ def context
11
+ {client: client, params: params, current_user: client, policy_used: -> { @policy_used = true }}
12
+ end
13
+
14
+ protected
15
+
16
+ def current_user
17
+ @client
18
+ end
19
+
20
+ def authorize(record, query = nil)
21
+ context[:policy_used]&.call
22
+ super
23
+ end
24
+
25
+ private
26
+
27
+ def authenticate_client!
28
+ authenticate_tenant || unauthorized!
29
+ end
30
+
31
+ def unauthorized!
32
+ head :unauthorized
33
+ end
34
+
35
+ def authenticate_tenant
36
+ @client = authenticate_with_http_basic do |api_key, api_secret|
37
+ Maestrano.find_by_app_id_and_app_key(api_key, api_secret)
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,61 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Maestrano
4
+ module Api
5
+ module Concerns
6
+ module AccountController
7
+ extend ActiveSupport::Concern
8
+
9
+ #==================================================================
10
+ # Included methods
11
+ #==================================================================
12
+ # 'included do' causes the included code to be evaluated in the
13
+ # context where it is included rather than being executed in the
14
+ # module's context
15
+ included do
16
+ end
17
+
18
+ #==================================================================
19
+ # Class methods
20
+ #==================================================================
21
+ module ClassMethods
22
+ end
23
+
24
+ #==================================================================
25
+ # Instance methods
26
+ #==================================================================
27
+ def setup_form
28
+ form = {
29
+ schema: {
30
+ type: 'object',
31
+ properties: {
32
+ array: {
33
+ title: 'You have not configured your schema form',
34
+ type: 'array',
35
+ items: {
36
+ type: 'string',
37
+ enum: [
38
+ "Ok I'll do it right away",
39
+ "I'll let someone else do it for me"
40
+ ]
41
+ }
42
+ }
43
+ }
44
+ }
45
+ }
46
+ render json: form.to_json
47
+ end
48
+
49
+ def link_account
50
+ render json: {error: 'Method to link account has not been implemented'}
51
+ end
52
+
53
+ def unlink_account
54
+ organization = Maestrano::Connector::Rails::Organization.find_by(uid: params[:uid])
55
+ organization.clear_omniauth
56
+ render json: {status: 'ok'}.to_json
57
+ end
58
+ end
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,6 @@
1
+ module Maestrano
2
+ module Api
3
+ class IdMapsController < ApiController
4
+ end
5
+ end
6
+ end
@@ -0,0 +1,6 @@
1
+ module Maestrano
2
+ module Api
3
+ class OrganizationsController < ApiController
4
+ end
5
+ end
6
+ end
@@ -0,0 +1,6 @@
1
+ module Maestrano
2
+ module Api
3
+ class SynchronizationsController < ApiController
4
+ end
5
+ end
6
+ end
@@ -0,0 +1,6 @@
1
+ module Maestrano
2
+ module Api
3
+ class UsersController < ApiController
4
+ end
5
+ end
6
+ end
@@ -17,6 +17,9 @@ class Maestrano::SynchronizationsController < Maestrano::Rails::WebHookControlle
17
17
  organization = Maestrano::Connector::Rails::Organization.find_by(uid: uid, tenant: tenant)
18
18
  return render json: {errors: [{message: 'Organization not found', code: 404}]}, status: :not_found unless organization
19
19
 
20
+ organization.sync_enabled = organization.synchronized_entities.values.any? { |settings| settings.values.any? { |v| v } }
21
+ organization.save if organization.sync_enabled_changed?
22
+
20
23
  status = organization_status(organization)
21
24
 
22
25
  unless %w[RUNNING ENQUEUED].include?(status)
@@ -16,4 +16,4 @@ module Maestrano::Connector::Rails
16
16
  @is_admin ||= current_user && current_organization && is_admin?(current_user, current_organization)
17
17
  end
18
18
  end
19
- end
19
+ end
@@ -1,5 +1,4 @@
1
1
  module Maestrano::Connector::Rails
2
-
3
2
  # This class process the push to Connec, it use PushToConnecJob for retrocompatibility
4
3
  # By using sidekiq-unique-jobs, it makes sure that 2 calls on the same entity, are processed in order
5
4
  class PushToConnecWorker
@@ -0,0 +1,63 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Abstract base class for all policies
4
+ # @abstract
5
+ # @!attribute [r] user
6
+ # @return [User] the current user
7
+ # @!attribute [r] record
8
+ # @return [Object] some kind of model object, whose authorization you want to check
9
+ class Maestrano::Connector::Rails::ApplicationPolicy
10
+ attr_reader :user, :record
11
+
12
+ # Returns a new instance of {BasePolicy}
13
+ # @param [User] user the current user
14
+ # @param [Object] record some kind of model object, whose authorization you want to check
15
+ # @return [ApplicationPolicy]
16
+ def initialize(user, record)
17
+ # Closed system: must be logged in to do anything
18
+ raise Pundit::NotAuthorizedError, 'must be logged in' unless user
19
+ @user = user
20
+ @record = record
21
+ end
22
+
23
+ def create?
24
+ false
25
+ end
26
+
27
+ def new?
28
+ create?
29
+ end
30
+
31
+ def update?
32
+ create?
33
+ end
34
+
35
+ def edit?
36
+ update?
37
+ end
38
+
39
+ def destroy?
40
+ false
41
+ end
42
+
43
+ def scope
44
+ Pundit.policy_scope!(user, record.class)
45
+ end
46
+
47
+ class Scope
48
+ attr_reader :user, :scope
49
+
50
+ def initialize(user, scope)
51
+ @user = user
52
+ @scope = scope
53
+ end
54
+
55
+ def resolve
56
+ scope_to_tenant
57
+ end
58
+
59
+ def scope_to_tenant
60
+ scope.where(tenant: user)
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Maestrano::Connector::Rails::IdMapPolicy < Maestrano::Connector::Rails::ApplicationPolicy
4
+ class Scope < Scope
5
+ def resolve
6
+ scope.includes(:organization).where('organizations.tenant': user)
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Maestrano::Connector::Rails::OrganizationPolicy < Maestrano::Connector::Rails::ApplicationPolicy
4
+ def create?
5
+ true
6
+ end
7
+ end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Maestrano::Connector::Rails::SynchronizationPolicy < Maestrano::Connector::Rails::ApplicationPolicy
4
+ class Scope < Scope
5
+ def resolve
6
+ scope.includes(:organization).where('organizations.tenant': user)
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Maestrano::Connector::Rails::UserPolicy < Maestrano::Connector::Rails::ApplicationPolicy
4
+ def create?
5
+ true
6
+ end
7
+ end
@@ -0,0 +1,67 @@
1
+ module Maestrano
2
+ module Api
3
+ class BaseResource < JSONAPI::Resource
4
+ abstract
5
+ include Pundit::Resource
6
+
7
+ API_SQL_OPERATOR_MAPPING = {
8
+ gt: '>',
9
+ gte: '>=',
10
+ lt: '<',
11
+ lte: '<=',
12
+ ne: '<>',
13
+ like: 'LIKE'
14
+ }.freeze
15
+
16
+ def self.all_filters
17
+ # Skipping if there is no tables as calling columns_hash in attribute_type is causing issue
18
+ return unless tables_exists?
19
+ _attributes.keys.each do |attribute|
20
+ type = attribute_type(attribute)
21
+ if type == :boolean
22
+ # https://github.com/cerebris/jsonapi-resources/issues/852
23
+ # make sure filter applied on boolean works
24
+ filter(attribute, verify: :verify_boolean_filter)
25
+ else
26
+ filter(attribute)
27
+ end
28
+ end
29
+ generate_composite_filters
30
+ end
31
+
32
+ def self.generate_composite_filters
33
+ _allowed_filters.keys.each do |key|
34
+ # iterating through all the api operator and adding them as custom filter
35
+ # name.gt, name.like etc...
36
+ next unless _model_class
37
+ field = "#{_model_class.table_name}.#{key}"
38
+
39
+ API_SQL_OPERATOR_MAPPING.each do |api_operator, sql_operator|
40
+ filter "#{key}.#{api_operator}",
41
+ apply: ->(records, value, _options) { records.where("#{field} #{sql_operator} ?", value[0]) }
42
+ end
43
+ filter "#{key}.none",
44
+ apply: ->(records, value, _options) { records.where("#{field} IS NULL") }
45
+ filter "#{key}.not",
46
+ apply: ->(records, value, _options) { value[0] ? records.where("#{field} <> ?", value[0]) : records.where("#{field} IS NOT NULL") }
47
+ filter "#{key}.nin",
48
+ apply: ->(records, value, _options) { records.where("#{field} NOT IN (?)", value) }
49
+ filter "#{key}.in",
50
+ apply: ->(records, value, _options) { records.where("#{field} IN (?)", value) }
51
+ end
52
+ end
53
+
54
+ def self.attribute_type(attribute)
55
+ _model_class.columns_hash[attribute.to_s]&.type || :string
56
+ rescue
57
+ :string
58
+ end
59
+
60
+ # If the code is loaded before table are created (during a schema:load for example) this will return false
61
+ def self.tables_exists?
62
+ @tables_exists = ActiveRecord::Base.connection.table_exists?('users') if @tables_exists.nil?
63
+ @tables_exists
64
+ end
65
+ end
66
+ end
67
+ end
@@ -0,0 +1,38 @@
1
+ module Maestrano
2
+ module Api
3
+ class IdMapResource < BaseResource
4
+ @model_class = Maestrano::Connector::Rails::IdMap
5
+
6
+ # == Attributes ===========================================================
7
+ attribute :connec_id
8
+ attribute :external_entity
9
+ attribute :external_id
10
+ attribute :name
11
+ attribute :message
12
+
13
+ all_filters
14
+
15
+ filter :uid, apply: lambda { |records, value, _options|
16
+ records.joins(:organization).where('organizations.uid = ?', value)
17
+ }
18
+ filter :external_entity
19
+
20
+ has_many :synchronizations
21
+
22
+ def account_linked?
23
+ @model.oauth_uid.present?
24
+ end
25
+
26
+ alias has_account_linked account_linked?
27
+
28
+ def account_creation_link
29
+ Maestrano::Connector::Rails::External.create_account_link(@model || nil)
30
+ end
31
+
32
+ def save
33
+ @model.tenant = context[:client]
34
+ super
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,43 @@
1
+ module Maestrano
2
+ module Api
3
+ class OrganizationResource < BaseResource
4
+ @model_class = Maestrano::Connector::Rails::Organization
5
+
6
+ # == Attributes ===========================================================
7
+ attribute :name
8
+ attribute :has_account_linked
9
+ attribute :uid
10
+ attribute :org_uid
11
+ attribute :account_creation_link
12
+ attribute :displayable_synchronized_entities
13
+ attribute :date_filtering_limit
14
+ attribute :tenant
15
+ attribute :provider
16
+ attribute :sync_enabled
17
+ attribute :entities_types
18
+
19
+ filter :uid
20
+
21
+ has_many :synchronizations
22
+
23
+ def account_linked?
24
+ @model.oauth_uid.present?
25
+ end
26
+
27
+ alias has_account_linked account_linked?
28
+
29
+ def account_creation_link
30
+ Maestrano::Connector::Rails::External.create_account_link(@model || nil)
31
+ end
32
+
33
+ def save
34
+ @model.tenant = context[:client]
35
+ super
36
+ end
37
+
38
+ def entities_types
39
+ ['All', *Maestrano::Connector::Rails::IdMap.uniq.pluck(:external_entity)]
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,19 @@
1
+ module Maestrano
2
+ module Api
3
+ class SynchronizationResource < BaseResource
4
+ @model_class = Maestrano::Connector::Rails::Synchronization
5
+
6
+ # == Attributes ===========================================================
7
+ attribute :status
8
+ attribute :message
9
+ attribute :updated_at
10
+ attribute :created_at
11
+
12
+ has_one :organization
13
+
14
+ filter :uid, apply: lambda { |records, value, _options|
15
+ records.joins(:organization).where('organizations.uid = ?', value)
16
+ }
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,23 @@
1
+ module Maestrano
2
+ module Api
3
+ class UserResource < BaseResource
4
+ @model_class = Maestrano::Connector::Rails::User
5
+
6
+ # == Attributes ===========================================================
7
+ attribute :first_name
8
+ attribute :provider
9
+ attribute :last_name
10
+ attribute :email
11
+ attribute :tenant
12
+ attribute :uid
13
+
14
+ def save
15
+ @model.tenant = context[:client]
16
+ super
17
+ return unless org_uid == context.dig(:params, :org_uid)
18
+ org = Maestrano::Connector::Rails::Organization.find_by(org_uid: org_uid)
19
+ org.add_member(@model) unless !org || org.member?(@model)
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,59 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Configuration
4
+ JSONAPI.configure do |config|
5
+ #:underscored_key, :camelized_key, :dasherized_key, or custom
6
+ config.json_key_format = :underscored_key
7
+
8
+ #:underscored_route, :camelized_route, :dasherized_route, or custom
9
+ config.route_format = :underscored_route
10
+
11
+ #:integer, :uuid, :string, or custom (provide a proc)
12
+ config.resource_key_type = :string
13
+
14
+ # optional request features
15
+ config.allow_include = true
16
+ config.allow_sort = true
17
+ config.allow_filter = true
18
+
19
+ # How to handle unsupported attributes and relationships which are provided in the request
20
+ # true => raises an error
21
+ # false => allows the request to continue. A warning is included in the response meta data indicating
22
+ # the fields which were ignored. This is useful for client libraries which send extra parameters.
23
+ config.raise_if_parameters_not_allowed = true
24
+
25
+ # :none, :offset, :paged, or a custom paginator name
26
+ config.default_paginator = :paged
27
+
28
+ # Output pagination links at top level
29
+ config.top_level_links_include_pagination = true
30
+
31
+ config.default_page_size = 30
32
+ config.maximum_page_size = 100
33
+
34
+ # Output the record count in top level meta data for find operations
35
+ config.top_level_meta_include_record_count = true
36
+ config.top_level_meta_record_count_key = :record_count
37
+
38
+ # For :paged paginators, the following are also available
39
+ config.top_level_meta_include_page_count = false
40
+ config.top_level_meta_page_count_key = :page_count
41
+
42
+ config.use_text_errors = false
43
+
44
+ # List of classes that should not be rescued by the operations processor.
45
+ # For example, if you use Pundit for authorization, you might
46
+ # raise a Pundit::NotAuthorizedError at some point during operations
47
+ # processing. If you want to use Rails' `rescue_from` macro to
48
+ # catch this error and render a 403 status code, you should add
49
+ # the `Pundit::NotAuthorizedError` to the `exception_class_whitelist`.
50
+ # Subclasses of the whitelisted classes will also be whitelisted.
51
+ config.exception_class_whitelist = []
52
+
53
+ # Resource Linkage
54
+ # Controls the serialization of resource linkage for non compound documents
55
+ # NOTE: always_include_to_many_linkage_data is not currently implemented
56
+ config.always_include_to_one_linkage_data = false
57
+
58
+ config.resource_cache = Rails.cache
59
+ end
@@ -17,5 +17,16 @@ Maestrano::Connector::Rails::Engine.routes.draw do
17
17
  end
18
18
  end
19
19
  end
20
+
21
+ namespace :api do
22
+ get 'account/setup_form'
23
+ post 'account/link_account'
24
+ post 'account/unlink_account'
25
+
26
+ jsonapi_resources :organizations
27
+ jsonapi_resources :users
28
+ jsonapi_resources :synchronizations
29
+ jsonapi_resources :id_maps
30
+ end
20
31
  end
21
32
  end
@@ -35,7 +35,7 @@ module Connector
35
35
 
36
36
  def copy_icons_and_logos
37
37
  copy_file 'logos/to_connec.png', 'app/assets/images/logos/to_connec.png'
38
- copy_file 'logos/to_external.png', 'spec/assets/images/logos/to_external.png'
38
+ copy_file 'logos/to_external.png', 'app/assets/images/logos/to_external.png'
39
39
  end
40
40
 
41
41
  def copy_controllers_and_views
@@ -53,6 +53,9 @@ module Connector
53
53
  copy_file 'shared_entities_index.haml', 'app/views/shared_entities/index.html.haml'
54
54
 
55
55
  copy_file 'layouts.haml', 'app/views/layouts/application.html.haml'
56
+
57
+ mkdir_p 'app/controllers/maestrano/api'
58
+ copy_file 'account_controller.rb', 'app/controllers/maestrano/api/account_controller.rb'
56
59
  end
57
60
 
58
61
  def copy_stylesheets
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Maestrano
4
+ module Api
5
+ class AccountController < ApiController
6
+ include Maestrano::Api::Concerns::AccountController
7
+
8
+ # def setup_form
9
+ # TODO return the json angular schema form
10
+ # that will be used for the user to link their account
11
+ # See https://github.com/json-schema-form/angular-schema-form/
12
+ # end
13
+
14
+ # def link_account
15
+ # TODO similar to oauth_controller#request, method that allows
16
+ # the user to link their account.
17
+ # Params will be the ones from the setup_form +
18
+ # 'org-uid': the channel_id (e.g: org-fbba)
19
+ # end
20
+ end
21
+ end
22
+ end
@@ -1,7 +1,7 @@
1
1
  module Maestrano
2
2
  module Connector
3
3
  module Rails
4
- VERSION = '2.1.3'.freeze
4
+ VERSION = '2.2.0'.freeze
5
5
  end
6
6
  end
7
7
  end
@@ -0,0 +1,16 @@
1
+ module JsonApiController
2
+ shared_examples 'an app IDM endpoint' do
3
+ subject { get :index }
4
+
5
+ context 'without authentication' do
6
+ it { is_expected.to have_http_status(:unauthorized), "response.code: #{response.code}" }
7
+ end
8
+
9
+ context 'with authentication' do
10
+ let(:config) { Maestrano.configs.values.first }
11
+ before { @request.env['HTTP_AUTHORIZATION'] = 'Basic ' + Base64.encode64("#{config.param('api.id')}:#{config.param('api.key')}") }
12
+
13
+ it { is_expected.to have_http_status(:ok), "response.code: #{response.code}" }
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,12 @@
1
+ module SharedPunditExample
2
+ shared_examples 'a model scoped to the tenant' do
3
+ let(:klass) { described_class.to_s.gsub('Policy', '').constantize }
4
+ let(:scope) { klass.all }
5
+
6
+ subject { described_class::Scope.new('default', scope).resolve }
7
+
8
+ context 'when scoped to the right tenant' do
9
+ it { is_expected.to eq([instance1]) }
10
+ end
11
+ end
12
+ end
@@ -24,7 +24,7 @@ Gem::Specification.new do |s|
24
24
  "README.md"
25
25
  ]
26
26
 
27
- s.add_runtime_dependency('rails', '~> 4.2.7.1')
27
+ s.add_runtime_dependency('rails', '~> 4.2.9')
28
28
  s.add_runtime_dependency('maestrano-rails', '~> 1.0.4')
29
29
  s.add_runtime_dependency('attr_encrypted', '~> 1.4.0')
30
30
  s.add_runtime_dependency('autoprefixer-rails')
@@ -32,9 +32,11 @@ Gem::Specification.new do |s|
32
32
  s.add_runtime_dependency('config')
33
33
  s.add_runtime_dependency('figaro')
34
34
  s.add_runtime_dependency('jquery-rails', '>= 4.0.4')
35
+ s.add_runtime_dependency('jsonapi-resources')
35
36
  s.add_runtime_dependency('haml-rails')
36
37
  s.add_runtime_dependency('hash_mapper', '>= 0.2.2')
37
-
38
+ s.add_runtime_dependency('pundit')
39
+ s.add_runtime_dependency('pundit-resources')
38
40
  s.add_runtime_dependency('sidekiq', '~> 4.2.9')
39
41
  s.add_runtime_dependency('sidekiq-cron')
40
42
  s.add_runtime_dependency('sidekiq-unique-jobs')
@@ -51,5 +53,5 @@ Gem::Specification.new do |s|
51
53
  s.add_development_dependency('shoulda-matchers')
52
54
  s.add_development_dependency('simplecov', '>= 0')
53
55
  s.add_development_dependency('timecop')
54
- s.add_development_dependency('webmock', '~> 1.24.1')
56
+ s.add_development_dependency('webmock')
55
57
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: maestrano-connector-rails
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.1.3
4
+ version: 2.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Maestrano
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-10-05 00:00:00.000000000 Z
11
+ date: 2017-11-23 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -16,14 +16,14 @@ dependencies:
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: 4.2.7.1
19
+ version: 4.2.9
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: 4.2.7.1
26
+ version: 4.2.9
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: maestrano-rails
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -122,6 +122,20 @@ dependencies:
122
122
  - - ">="
123
123
  - !ruby/object:Gem::Version
124
124
  version: 4.0.4
125
+ - !ruby/object:Gem::Dependency
126
+ name: jsonapi-resources
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - ">="
130
+ - !ruby/object:Gem::Version
131
+ version: '0'
132
+ type: :runtime
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - ">="
137
+ - !ruby/object:Gem::Version
138
+ version: '0'
125
139
  - !ruby/object:Gem::Dependency
126
140
  name: haml-rails
127
141
  requirement: !ruby/object:Gem::Requirement
@@ -150,6 +164,34 @@ dependencies:
150
164
  - - ">="
151
165
  - !ruby/object:Gem::Version
152
166
  version: 0.2.2
167
+ - !ruby/object:Gem::Dependency
168
+ name: pundit
169
+ requirement: !ruby/object:Gem::Requirement
170
+ requirements:
171
+ - - ">="
172
+ - !ruby/object:Gem::Version
173
+ version: '0'
174
+ type: :runtime
175
+ prerelease: false
176
+ version_requirements: !ruby/object:Gem::Requirement
177
+ requirements:
178
+ - - ">="
179
+ - !ruby/object:Gem::Version
180
+ version: '0'
181
+ - !ruby/object:Gem::Dependency
182
+ name: pundit-resources
183
+ requirement: !ruby/object:Gem::Requirement
184
+ requirements:
185
+ - - ">="
186
+ - !ruby/object:Gem::Version
187
+ version: '0'
188
+ type: :runtime
189
+ prerelease: false
190
+ version_requirements: !ruby/object:Gem::Requirement
191
+ requirements:
192
+ - - ">="
193
+ - !ruby/object:Gem::Version
194
+ version: '0'
153
195
  - !ruby/object:Gem::Dependency
154
196
  name: sidekiq
155
197
  requirement: !ruby/object:Gem::Requirement
@@ -364,16 +406,16 @@ dependencies:
364
406
  name: webmock
365
407
  requirement: !ruby/object:Gem::Requirement
366
408
  requirements:
367
- - - "~>"
409
+ - - ">="
368
410
  - !ruby/object:Gem::Version
369
- version: 1.24.1
411
+ version: '0'
370
412
  type: :development
371
413
  prerelease: false
372
414
  version_requirements: !ruby/object:Gem::Requirement
373
415
  requirements:
374
- - - "~>"
416
+ - - ">="
375
417
  - !ruby/object:Gem::Version
376
- version: 1.24.1
418
+ version: '0'
377
419
  description: Maestrano is the next generation marketplace for SME applications. See
378
420
  https://sme.maestrano.com for details.
379
421
  email: developers@maestrano.com
@@ -388,6 +430,7 @@ files:
388
430
  - ".rubocop.yml"
389
431
  - ".rubocop_todo.yml"
390
432
  - ".ruby-version"
433
+ - ".travis.yml"
391
434
  - CHANGELOG.md
392
435
  - CODESHIP.md
393
436
  - DEVELOPER.md
@@ -397,6 +440,13 @@ files:
397
440
  - Rakefile
398
441
  - app/controllers/maestrano/account/group_users_controller.rb
399
442
  - app/controllers/maestrano/account/groups_controller.rb
443
+ - app/controllers/maestrano/api/account_controller.rb
444
+ - app/controllers/maestrano/api/api_controller.rb
445
+ - app/controllers/maestrano/api/concerns/account_controller.rb
446
+ - app/controllers/maestrano/api/id_maps_controller.rb
447
+ - app/controllers/maestrano/api/organizations_controller.rb
448
+ - app/controllers/maestrano/api/synchronizations_controller.rb
449
+ - app/controllers/maestrano/api/users_controller.rb
400
450
  - app/controllers/maestrano/application_controller.rb
401
451
  - app/controllers/maestrano/auth/saml_controller.rb
402
452
  - app/controllers/maestrano/connec_controller.rb
@@ -437,6 +487,17 @@ files:
437
487
  - app/models/maestrano/connector/rails/synchronization.rb
438
488
  - app/models/maestrano/connector/rails/user.rb
439
489
  - app/models/maestrano/connector/rails/user_organization_rel.rb
490
+ - app/policies/maestrano/connector/rails/application_policy.rb
491
+ - app/policies/maestrano/connector/rails/id_map_policy.rb
492
+ - app/policies/maestrano/connector/rails/organization_policy.rb
493
+ - app/policies/maestrano/connector/rails/synchronization_policy.rb
494
+ - app/policies/maestrano/connector/rails/user_policy.rb
495
+ - app/resources/maestrano/api/base_resource.rb
496
+ - app/resources/maestrano/api/id_map_resource.rb
497
+ - app/resources/maestrano/api/organization_resource.rb
498
+ - app/resources/maestrano/api/synchronization_resource.rb
499
+ - app/resources/maestrano/api/user_resource.rb
500
+ - config/initializers/json_api.rb
440
501
  - config/routes.rb
441
502
  - db/migrate/20151122162100_create_users.rb
442
503
  - db/migrate/20151122162414_create_organizations.rb
@@ -455,6 +516,7 @@ files:
455
516
  - lib/generators/connector/USAGE
456
517
  - lib/generators/connector/complex_entity_generator.rb
457
518
  - lib/generators/connector/install_generator.rb
519
+ - lib/generators/connector/templates/account_controller.rb
458
520
  - lib/generators/connector/templates/complex_entity_example/contact.rb
459
521
  - lib/generators/connector/templates/complex_entity_example/contact_and_lead.rb
460
522
  - lib/generators/connector/templates/complex_entity_example/contact_mapper.rb
@@ -488,6 +550,8 @@ files:
488
550
  - lib/maestrano/connector/rails/version.rb
489
551
  - lib/maestrano_connector_rails.rb
490
552
  - lib/maestrano_connector_rails/factories.rb
553
+ - lib/testing_support/shared_examples/json_api_controller.rb
554
+ - lib/testing_support/shared_examples/shared_pundit_example.rb
491
555
  - maestrano-connector-rails.gemspec
492
556
  - maestrano.png
493
557
  - release_notes.md
@@ -511,7 +575,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
511
575
  version: '0'
512
576
  requirements: []
513
577
  rubyforge_project:
514
- rubygems_version: 2.5.1
578
+ rubygems_version: 2.6.14
515
579
  signing_key:
516
580
  specification_version: 4
517
581
  summary: Rails framework to build connector with Maestrano