maestrano-connector-rails 2.1.3 → 2.2.0

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