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.
- checksums.yaml +4 -4
- data/.rubocop.yml +2 -2
- data/.rubocop_todo.yml +11 -19
- data/.travis.yml +7 -0
- data/Gemfile +8 -0
- data/app/controllers/maestrano/api/account_controller.rb +9 -0
- data/app/controllers/maestrano/api/api_controller.rb +42 -0
- data/app/controllers/maestrano/api/concerns/account_controller.rb +61 -0
- data/app/controllers/maestrano/api/id_maps_controller.rb +6 -0
- data/app/controllers/maestrano/api/organizations_controller.rb +6 -0
- data/app/controllers/maestrano/api/synchronizations_controller.rb +6 -0
- data/app/controllers/maestrano/api/users_controller.rb +6 -0
- data/app/controllers/maestrano/synchronizations_controller.rb +3 -0
- data/app/helpers/maestrano/connector/rails/session_helper.rb +1 -1
- data/app/jobs/maestrano/connector/rails/push_to_connec_worker.rb +0 -1
- data/app/policies/maestrano/connector/rails/application_policy.rb +63 -0
- data/app/policies/maestrano/connector/rails/id_map_policy.rb +9 -0
- data/app/policies/maestrano/connector/rails/organization_policy.rb +7 -0
- data/app/policies/maestrano/connector/rails/synchronization_policy.rb +9 -0
- data/app/policies/maestrano/connector/rails/user_policy.rb +7 -0
- data/app/resources/maestrano/api/base_resource.rb +67 -0
- data/app/resources/maestrano/api/id_map_resource.rb +38 -0
- data/app/resources/maestrano/api/organization_resource.rb +43 -0
- data/app/resources/maestrano/api/synchronization_resource.rb +19 -0
- data/app/resources/maestrano/api/user_resource.rb +23 -0
- data/config/initializers/json_api.rb +59 -0
- data/config/routes.rb +11 -0
- data/lib/generators/connector/install_generator.rb +4 -1
- data/lib/generators/connector/templates/account_controller.rb +22 -0
- data/lib/maestrano/connector/rails/version.rb +1 -1
- data/lib/testing_support/shared_examples/json_api_controller.rb +16 -0
- data/lib/testing_support/shared_examples/shared_pundit_example.rb +12 -0
- data/maestrano-connector-rails.gemspec +5 -3
- metadata +73 -9
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6aacb721d865456e02851131b118f16891870268
|
4
|
+
data.tar.gz: ab5b6a2fa521f79c7e42d8028387504d0a6e5929
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 824bde6273b0f0bcecfd4a8b390c14851860cae5c5cc36ff133fbbbdd1b58105f8614244fc198dc0d1e28ba199790e2527399a3fa9764629aeac82957e135a65
|
7
|
+
data.tar.gz: 7f62f2ace833c722ee02fc37228393b054f119a6634cfdc8dbf263e9e5ec882b9f610d88c391a67222da19b8f12998c8b2df7d73123846ce907d61b4eedb8105
|
data/.rubocop.yml
CHANGED
@@ -29,7 +29,7 @@ Metrics/LineLength:
|
|
29
29
|
Metrics/MethodLength:
|
30
30
|
Max: 50
|
31
31
|
|
32
|
-
|
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
|
-
|
43
|
+
Layout/SpaceInsideHashLiteralBraces:
|
44
44
|
EnforcedStyle: no_space
|
45
45
|
|
46
46
|
# Checks for unused block arguments
|
data/.rubocop_todo.yml
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# This configuration was generated by
|
2
2
|
# `rubocop --auto-gen-config`
|
3
|
-
# on 2017-
|
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:
|
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:
|
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'
|
data/.travis.yml
ADDED
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,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
|
@@ -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)
|
@@ -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,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
|
data/config/routes.rb
CHANGED
@@ -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', '
|
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
|
@@ -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.
|
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'
|
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.
|
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-
|
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.
|
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.
|
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:
|
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:
|
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.
|
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
|