rapils 0.1.0.pre.alpha1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/MIT-LICENSE +20 -0
- data/README.md +39 -0
- data/Rakefile +6 -0
- data/db/migrate/20200724222614_create_users.rb +17 -0
- data/db/migrate/20200724223120_create_access_tokens.rb +17 -0
- data/db/migrate/20200725132221_create_permissions.rb +12 -0
- data/lib/rapils.rb +4 -0
- data/lib/rapils/application.rb +46 -0
- data/lib/rapils/concerns/json_errors.rb +47 -0
- data/lib/rapils/concerns/token_auth.rb +58 -0
- data/lib/rapils/controllers/base_controller.rb +12 -0
- data/lib/rapils/controllers/permissions_controller.rb +50 -0
- data/lib/rapils/engine.rb +27 -0
- data/lib/rapils/models/access_token.rb +35 -0
- data/lib/rapils/models/base_record.rb +8 -0
- data/lib/rapils/models/permission.rb +28 -0
- data/lib/rapils/models/user.rb +31 -0
- data/lib/rapils/policies/application_policy.rb +49 -0
- data/lib/rapils/policies/permission_policy.rb +22 -0
- data/lib/rapils/serializers/base_serializer.rb +13 -0
- data/lib/rapils/serializers/permission_serializer.rb +15 -0
- data/lib/rapils/setup.rb +34 -0
- data/lib/rapils/version.rb +3 -0
- data/lib/tasks/rapils_tasks.rake +4 -0
- metadata +220 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: e6e7a6c654a9af37aaafbaf197e42d863184864481a581999651e44e8b96ce40
|
4
|
+
data.tar.gz: c944aa177efe1e7741d201b7a2ae5d445068cac8dbc11da14f000b3e18b4c100
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: d8de9a618c19f8600c46ad2aecf7b4dca1924fe6998ecff4e0865001821e449fb6e26e1349327c725cf364021113ddbcdc3b6aa18424ecb086ca61bc9ea06a78
|
7
|
+
data.tar.gz: d73f40e4e350f28fca740e1af948b4cd2cf49993dc9da59c67e6f2bbe26573b725be477aa07fb2dcdb214a3aea33e545ef685f9dc456f0e7e433a2659c695ee5
|
data/MIT-LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright 2020 Marc Qualie
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,39 @@
|
|
1
|
+
# Rapils
|
2
|
+
|
3
|
+
Opinionated out-of-the-box API + UI framework.
|
4
|
+
|
5
|
+
|
6
|
+
|
7
|
+
## Installation
|
8
|
+
|
9
|
+
Add this line to your application's Gemfile:
|
10
|
+
|
11
|
+
```ruby
|
12
|
+
gem 'rapils'
|
13
|
+
```
|
14
|
+
|
15
|
+
And then execute:
|
16
|
+
```bash
|
17
|
+
$ bundle
|
18
|
+
```
|
19
|
+
|
20
|
+
### Models
|
21
|
+
|
22
|
+
In order to use the models, you need to extend the base models inside your application:
|
23
|
+
|
24
|
+
```ruby
|
25
|
+
class User < Rapils::Models::User
|
26
|
+
end
|
27
|
+
```
|
28
|
+
|
29
|
+
|
30
|
+
|
31
|
+
## Contributing
|
32
|
+
|
33
|
+
Contribution directions go here.
|
34
|
+
|
35
|
+
|
36
|
+
|
37
|
+
## License
|
38
|
+
|
39
|
+
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
data/Rakefile
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
class CreateUsers < ActiveRecord::Migration[6.0]
|
2
|
+
def change
|
3
|
+
enable_extension 'pgcrypto'
|
4
|
+
|
5
|
+
create_table :users, id: :uuid do |t|
|
6
|
+
t.string :name
|
7
|
+
t.string :email, null: false
|
8
|
+
t.string :admin_roles, array: true, default: []
|
9
|
+
t.string :auth0_uid, null: false
|
10
|
+
t.datetime :access_granted_at
|
11
|
+
t.timestamps null: false
|
12
|
+
|
13
|
+
t.index %i[auth0_uid], name: 'index_users_on_auth0_uid', unique: true
|
14
|
+
t.index %i[email], name: 'index_users_on_email', unique: true
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
class CreateAccessTokens < ActiveRecord::Migration[6.0]
|
2
|
+
def change
|
3
|
+
create_table :access_tokens, id: :uuid do |t|
|
4
|
+
t.references :user, type: :uuid
|
5
|
+
# t.string :type, default: 'AccessToken', null: false
|
6
|
+
t.string :name, null: false
|
7
|
+
t.string :token, null: false
|
8
|
+
t.string :actions, default: [], null: false, array: true
|
9
|
+
t.datetime :last_used_at
|
10
|
+
t.datetime :expires_at
|
11
|
+
t.datetime :invalidated_at
|
12
|
+
t.timestamps null: false
|
13
|
+
|
14
|
+
t.index %i[token], name: 'index_access_tokens_on_token', unique: true
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
class CreatePermissions < ActiveRecord::Migration[6.0]
|
2
|
+
def change
|
3
|
+
create_table :permissions, id: :uuid do |t|
|
4
|
+
t.references :owner, type: :uuid, polymorphic: true
|
5
|
+
t.references :subject, type: :uuid, polymorphic: true
|
6
|
+
t.string :actions, array: true, null: false, default: []
|
7
|
+
t.boolean :recursive, default: false, null: false
|
8
|
+
t.datetime :expires_at
|
9
|
+
t.timestamps null: false
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
data/lib/rapils.rb
ADDED
@@ -0,0 +1,46 @@
|
|
1
|
+
require 'diffcrypt/rails/encrypted_configuration'
|
2
|
+
|
3
|
+
module Rapils
|
4
|
+
class Application < ::Rails::Application
|
5
|
+
config.load_defaults 6.0
|
6
|
+
|
7
|
+
# Configure generator defaults
|
8
|
+
config.generators do |g|
|
9
|
+
g.orm :active_record, primary_key_type: :uuid
|
10
|
+
|
11
|
+
# Disable things we never use
|
12
|
+
g.assets false
|
13
|
+
g.helper false
|
14
|
+
g.resource_route false
|
15
|
+
g.system_tests = nil
|
16
|
+
end
|
17
|
+
|
18
|
+
# Email
|
19
|
+
config.action_mailer.raise_delivery_errors = true
|
20
|
+
config.action_mailer.perform_deliveries = true
|
21
|
+
config.action_mailer.delivery_method = :smtp
|
22
|
+
config.action_mailer.smtp_settings = {
|
23
|
+
address: ENV['SMTP_HOST'] || 'localhost',
|
24
|
+
port: ENV['SMTP_PORT'] || 1025,
|
25
|
+
domain: ENV['SMTP_DOMAIN'] || 'localhozt',
|
26
|
+
user_name: ENV['SMTP_USERNAME'],
|
27
|
+
password: ENV['SMTP_PASSWORD'],
|
28
|
+
authentication: ENV['SMTP_AUTHENTICATION'] || 'plain',
|
29
|
+
enable_starttls_auto: true,
|
30
|
+
}
|
31
|
+
config.action_mailer.default_url_options = {
|
32
|
+
scheme: 'https',
|
33
|
+
host: ENV['WWW_HOST'] || 'localhost',
|
34
|
+
}
|
35
|
+
|
36
|
+
# Override encryption with diffcrypt
|
37
|
+
def encrypted(path, key_path: 'config/master.key', env_key: 'RAILS_MASTER_KEY')
|
38
|
+
Diffcrypt::Rails::EncryptedConfiguration.new(
|
39
|
+
config_path: Rails.root.join(path),
|
40
|
+
key_path: Rails.root.join(key_path),
|
41
|
+
env_key: env_key,
|
42
|
+
raise_if_missing_key: config.require_master_key,
|
43
|
+
)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
require 'pundit'
|
2
|
+
|
3
|
+
module Rapils
|
4
|
+
module Concerns
|
5
|
+
module JsonErrors
|
6
|
+
extend ActiveSupport::Concern
|
7
|
+
|
8
|
+
included do
|
9
|
+
rescue_from ActiveRecord::RecordNotFound, with: :render_json_notfound_errors
|
10
|
+
rescue_from ActiveRecord::RecordInvalid, with: :render_json_validation_errors
|
11
|
+
rescue_from Pundit::NotAuthorizedError, with: :render_json_notfound_errors
|
12
|
+
end
|
13
|
+
|
14
|
+
def json_error(title:, details: nil, status: 422)
|
15
|
+
{
|
16
|
+
status: status,
|
17
|
+
details: details,
|
18
|
+
title: title,
|
19
|
+
}.compact
|
20
|
+
end
|
21
|
+
|
22
|
+
def render_json_error(title:, details: nil, status: 422)
|
23
|
+
errors = [
|
24
|
+
json_error(title: title, details: details, status: status),
|
25
|
+
]
|
26
|
+
|
27
|
+
render json: { errors: errors }, status: status
|
28
|
+
end
|
29
|
+
|
30
|
+
def render_json_resource_error(resource, status: 422)
|
31
|
+
render_json_error(title: resource.errors.full_messages.join(', '), status: status)
|
32
|
+
end
|
33
|
+
|
34
|
+
def render_json_validation_errors(error)
|
35
|
+
if @resource
|
36
|
+
render_json_error(title: @resource.errors.full_messages.join(', '), status: 422)
|
37
|
+
else
|
38
|
+
render_json_error(title: error.message, status: 422)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def render_json_notfound_errors(error)
|
43
|
+
render_json_error(title: error.message, status: 404)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
module Rapils
|
2
|
+
module Concerns
|
3
|
+
module TokenAuth
|
4
|
+
extend ActiveSupport::Concern
|
5
|
+
|
6
|
+
included do
|
7
|
+
before_action :authenticate_api_user!
|
8
|
+
before_action :update_access_token_used_at!
|
9
|
+
end
|
10
|
+
|
11
|
+
def access_token
|
12
|
+
@access_token ||= begin
|
13
|
+
token = session[:access_token] || request.headers['Authorization']&.gsub(/bearer\s*/i, '')
|
14
|
+
return unless token
|
15
|
+
|
16
|
+
access_token ||= ::AccessToken.eager_load(:user).find_by(token: token)
|
17
|
+
return if access_token.nil? || access_token.expired? || access_token.invalidated?
|
18
|
+
|
19
|
+
access_token
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def current_user
|
24
|
+
return unless access_token
|
25
|
+
|
26
|
+
@current_user ||= access_token.user
|
27
|
+
end
|
28
|
+
|
29
|
+
def authenticate_api_user!
|
30
|
+
return true if current_user
|
31
|
+
|
32
|
+
errors = [
|
33
|
+
{
|
34
|
+
'title' => 'Not Authorized',
|
35
|
+
},
|
36
|
+
]
|
37
|
+
render json: { errors: errors }, status: 401
|
38
|
+
end
|
39
|
+
|
40
|
+
def ensure_current_user_is_admin!
|
41
|
+
return true if current_user&.admin_roles == ['*']
|
42
|
+
|
43
|
+
errors = [
|
44
|
+
{
|
45
|
+
'title' => 'Not Authorized',
|
46
|
+
},
|
47
|
+
]
|
48
|
+
render json: { errors: errors }, status: 401
|
49
|
+
end
|
50
|
+
|
51
|
+
def update_access_token_used_at!
|
52
|
+
return unless access_token
|
53
|
+
|
54
|
+
access_token.update_columns(last_used_at: DateTime.now)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
require 'rapils/concerns/json_errors'
|
2
|
+
require 'rapils/concerns/token_auth'
|
3
|
+
|
4
|
+
module Rapils
|
5
|
+
module Controllers
|
6
|
+
class BaseController < ActionController::API
|
7
|
+
include Concerns::JsonErrors
|
8
|
+
include Concerns::TokenAuth
|
9
|
+
include Pundit
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
require 'rapils/policies/permission_policy'
|
2
|
+
|
3
|
+
# Handles management of permissions via REST interface
|
4
|
+
module Rapils
|
5
|
+
module Controllers
|
6
|
+
class PermissionsController < BaseController
|
7
|
+
def create
|
8
|
+
@resource = Permission.new(
|
9
|
+
subject_type: params[:subject_type],
|
10
|
+
subject_id: params[:subject_id],
|
11
|
+
)
|
12
|
+
|
13
|
+
manual_authorize @resource
|
14
|
+
|
15
|
+
user = User.find_by!(email: params[:email])
|
16
|
+
@resource.update!(
|
17
|
+
owner: user,
|
18
|
+
actions: params[:actions],
|
19
|
+
)
|
20
|
+
|
21
|
+
render json: ::PermissionSerializer.new(@resource).serialized_json, status: 201
|
22
|
+
end
|
23
|
+
|
24
|
+
def index
|
25
|
+
@resources = Permission.where(subject_type: params[:subject_type], subject_id: params[:subject_id])
|
26
|
+
|
27
|
+
render json: ::PermissionSerializer.new(@resources).serialized_json
|
28
|
+
end
|
29
|
+
|
30
|
+
def destroy
|
31
|
+
@resource = Permission.find(params[:id])
|
32
|
+
authorize @resource, policy_class: Rapils::Policies::PermissionPolicy
|
33
|
+
@resource.destroy!
|
34
|
+
|
35
|
+
head 204
|
36
|
+
end
|
37
|
+
|
38
|
+
protected
|
39
|
+
|
40
|
+
def manual_authorize(resource)
|
41
|
+
subject = resource.subject
|
42
|
+
permission = current_user.permissions.find_by(subject: subject)
|
43
|
+
|
44
|
+
message = "Not allowed to manage #{subject.class.name.downcase.pluralize}"
|
45
|
+
raise(Pundit::NotAuthorizedError, message) unless permission
|
46
|
+
raise(Pundit::NotAuthorizedError, message) unless permission.actions.include?('all') || permission.actions.include?('manage')
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# Load all controllers
|
2
|
+
require 'rapils/controllers/base_controller'
|
3
|
+
Dir["#{__dir__}/controllers/**/*.rb"].sort.each { |f| require f }
|
4
|
+
|
5
|
+
# Load all models
|
6
|
+
require_relative './models/base_record'
|
7
|
+
Dir["#{__dir__}/models/**/*.rb"].sort.each { |f| require f }
|
8
|
+
|
9
|
+
# Load all serializers
|
10
|
+
require_relative './serializers/base_serializer'
|
11
|
+
Dir["#{__dir__}/serializers/**/*.rb"].sort.each { |f| require f }
|
12
|
+
|
13
|
+
module Rapils
|
14
|
+
class Engine < Rails::Engine
|
15
|
+
isolate_namespace Rapils
|
16
|
+
|
17
|
+
# Generators for use within the engine itself, not the consuming rails app
|
18
|
+
config.generators do |g|
|
19
|
+
g.orm :active_record, primary_key_type: :uuid
|
20
|
+
|
21
|
+
# Disable things we never use
|
22
|
+
g.assets false
|
23
|
+
g.helper false
|
24
|
+
g.resource_route false
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
module Rapils
|
2
|
+
module Models
|
3
|
+
class AccessToken < BaseRecord
|
4
|
+
self.abstract_class = true
|
5
|
+
|
6
|
+
belongs_to :user, class_name: '::User'
|
7
|
+
|
8
|
+
before_validation :generate_token
|
9
|
+
|
10
|
+
validates :name, presence: true, length: { minimum: 4, maximum: 100 }
|
11
|
+
|
12
|
+
scope :active, -> { where('(expires_at > ? OR expires_at IS NULL) AND invalidated_at IS NULL', DateTime.now) }
|
13
|
+
|
14
|
+
def invalidate!
|
15
|
+
update!(invalidated_at: DateTime.now)
|
16
|
+
end
|
17
|
+
|
18
|
+
def expired?
|
19
|
+
return false if expires_at.nil?
|
20
|
+
|
21
|
+
expires_at <= DateTime.now
|
22
|
+
end
|
23
|
+
|
24
|
+
def invalidated?
|
25
|
+
!invalidated_at.nil?
|
26
|
+
end
|
27
|
+
|
28
|
+
protected
|
29
|
+
|
30
|
+
def generate_token
|
31
|
+
self.token ||= SecureRandom.hex(16)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module Rapils
|
2
|
+
module Models
|
3
|
+
class Permission < BaseRecord
|
4
|
+
self.abstract_class = true
|
5
|
+
|
6
|
+
ACTIONS = %w[
|
7
|
+
all
|
8
|
+
manage
|
9
|
+
view
|
10
|
+
edit
|
11
|
+
delete
|
12
|
+
].freeze
|
13
|
+
|
14
|
+
belongs_to :owner, polymorphic: true
|
15
|
+
belongs_to :subject, polymorphic: true
|
16
|
+
|
17
|
+
validates :owner_id, uniqueness: { scope: %i[owner_type subject_type subject_id], message: '+ Subject combination already assigned' }
|
18
|
+
|
19
|
+
def owner_email
|
20
|
+
owner&.email
|
21
|
+
end
|
22
|
+
|
23
|
+
def owner_avatar_url
|
24
|
+
owner&.avatar_url
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module Rapils
|
2
|
+
module Models
|
3
|
+
class User < BaseRecord
|
4
|
+
self.abstract_class = true
|
5
|
+
|
6
|
+
has_many :access_tokens, class_name: '::AccessToken'
|
7
|
+
has_many :permissions, class_name: '::Permission', as: :owner
|
8
|
+
|
9
|
+
def admin?
|
10
|
+
admin_roles == ['*']
|
11
|
+
end
|
12
|
+
|
13
|
+
def access_granted?
|
14
|
+
access_granted_at && access_granted_at < DateTime.now ? true : false
|
15
|
+
end
|
16
|
+
|
17
|
+
def grant_access!
|
18
|
+
self.access_granted_at ||= DateTime.now
|
19
|
+
save! if changed?
|
20
|
+
end
|
21
|
+
|
22
|
+
def avatar_url
|
23
|
+
"https://www.gravatar.com/avatar/#{gravatar_hash}?s=160&d=identicon"
|
24
|
+
end
|
25
|
+
|
26
|
+
def gravatar_hash
|
27
|
+
Digest::MD5.hexdigest email.strip.downcase
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
class ApplicationPolicy
|
2
|
+
attr_reader :user, :record
|
3
|
+
|
4
|
+
def initialize(user, record)
|
5
|
+
@user = user
|
6
|
+
@record = record
|
7
|
+
end
|
8
|
+
|
9
|
+
def index?
|
10
|
+
false
|
11
|
+
end
|
12
|
+
|
13
|
+
def show?
|
14
|
+
false
|
15
|
+
end
|
16
|
+
|
17
|
+
def create?
|
18
|
+
false
|
19
|
+
end
|
20
|
+
|
21
|
+
def new?
|
22
|
+
create?
|
23
|
+
end
|
24
|
+
|
25
|
+
def update?
|
26
|
+
false
|
27
|
+
end
|
28
|
+
|
29
|
+
def edit?
|
30
|
+
update?
|
31
|
+
end
|
32
|
+
|
33
|
+
def destroy?
|
34
|
+
false
|
35
|
+
end
|
36
|
+
|
37
|
+
class Scope
|
38
|
+
attr_reader :user, :scope
|
39
|
+
|
40
|
+
def initialize(user, scope)
|
41
|
+
@user = user
|
42
|
+
@scope = scope
|
43
|
+
end
|
44
|
+
|
45
|
+
def resolve
|
46
|
+
scope.all
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require_relative './application_policy'
|
2
|
+
|
3
|
+
module Rapils
|
4
|
+
module Policies
|
5
|
+
class PermissionPolicy < ApplicationPolicy
|
6
|
+
def create?
|
7
|
+
false
|
8
|
+
end
|
9
|
+
|
10
|
+
def destroy?
|
11
|
+
return true if record.owner == user
|
12
|
+
|
13
|
+
# If user does not own this permission, we need to see if thay
|
14
|
+
# can manage permissions on the parent subject
|
15
|
+
permission = Permission.find_by(owner: user, subject: record.subject)
|
16
|
+
return false unless permission
|
17
|
+
|
18
|
+
permission.actions.include?('all') || permission.actions.include?('manage')
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module Rapils
|
2
|
+
module Serializers
|
3
|
+
class PermissionSerializer < BaseSerializer
|
4
|
+
attribute :subject_id
|
5
|
+
attribute :subject_type
|
6
|
+
attribute :owner_id
|
7
|
+
attribute :owner_type
|
8
|
+
attribute :owner_email
|
9
|
+
attribute :owner_avatar_url
|
10
|
+
attribute :actions
|
11
|
+
attribute :created_at
|
12
|
+
attribute :updated_at
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
data/lib/rapils/setup.rb
ADDED
@@ -0,0 +1,34 @@
|
|
1
|
+
module Rapils
|
2
|
+
DEFAULT_DEPENDENCIES = [
|
3
|
+
'active_model/railtie',
|
4
|
+
# 'active_job/railtie',
|
5
|
+
'active_record/railtie',
|
6
|
+
# 'active_storage/engine',
|
7
|
+
'action_controller/railtie',
|
8
|
+
'action_mailer/railtie',
|
9
|
+
# 'action_mailbox/engine',
|
10
|
+
# 'action_text/engine',
|
11
|
+
'action_view/railtie',
|
12
|
+
# 'action_cable/engine',
|
13
|
+
# 'sprockets/railtie',
|
14
|
+
# 'rails/test_unit/railtie',
|
15
|
+
].freeze
|
16
|
+
|
17
|
+
def self.setup(dependencies = DEFAULT_DEPENDENCIES)
|
18
|
+
# Require core libraries that would usually be in app Gemfile
|
19
|
+
require 'diffcrypt'
|
20
|
+
require 'pg'
|
21
|
+
|
22
|
+
# Load core rails dependencies
|
23
|
+
require 'rails'
|
24
|
+
dependencies.each { |dependency| require dependency }
|
25
|
+
|
26
|
+
# Require the gems listed in Gemfile, including any gems
|
27
|
+
# you've limited to :test, :development, or :production.
|
28
|
+
Bundler.require(*Rails.groups)
|
29
|
+
|
30
|
+
# Now we load the whole Rapils framework to hook into rails environment
|
31
|
+
require 'rapils/engine'
|
32
|
+
require 'rapils/application'
|
33
|
+
end
|
34
|
+
end
|
metadata
ADDED
@@ -0,0 +1,220 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: rapils
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0.pre.alpha1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Marc Qualie
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2020-07-25 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: diffcrypt
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0.3'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0.3'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: fast_jsonapi
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '1.5'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '1.5'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: pg
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0.18'
|
48
|
+
- - "<"
|
49
|
+
- !ruby/object:Gem::Version
|
50
|
+
version: '2.0'
|
51
|
+
type: :runtime
|
52
|
+
prerelease: false
|
53
|
+
version_requirements: !ruby/object:Gem::Requirement
|
54
|
+
requirements:
|
55
|
+
- - ">="
|
56
|
+
- !ruby/object:Gem::Version
|
57
|
+
version: '0.18'
|
58
|
+
- - "<"
|
59
|
+
- !ruby/object:Gem::Version
|
60
|
+
version: '2.0'
|
61
|
+
- !ruby/object:Gem::Dependency
|
62
|
+
name: pundit
|
63
|
+
requirement: !ruby/object:Gem::Requirement
|
64
|
+
requirements:
|
65
|
+
- - "~>"
|
66
|
+
- !ruby/object:Gem::Version
|
67
|
+
version: '2.1'
|
68
|
+
type: :runtime
|
69
|
+
prerelease: false
|
70
|
+
version_requirements: !ruby/object:Gem::Requirement
|
71
|
+
requirements:
|
72
|
+
- - "~>"
|
73
|
+
- !ruby/object:Gem::Version
|
74
|
+
version: '2.1'
|
75
|
+
- !ruby/object:Gem::Dependency
|
76
|
+
name: rails
|
77
|
+
requirement: !ruby/object:Gem::Requirement
|
78
|
+
requirements:
|
79
|
+
- - "~>"
|
80
|
+
- !ruby/object:Gem::Version
|
81
|
+
version: 6.0.3
|
82
|
+
- - ">="
|
83
|
+
- !ruby/object:Gem::Version
|
84
|
+
version: 6.0.3.1
|
85
|
+
type: :runtime
|
86
|
+
prerelease: false
|
87
|
+
version_requirements: !ruby/object:Gem::Requirement
|
88
|
+
requirements:
|
89
|
+
- - "~>"
|
90
|
+
- !ruby/object:Gem::Version
|
91
|
+
version: 6.0.3
|
92
|
+
- - ">="
|
93
|
+
- !ruby/object:Gem::Version
|
94
|
+
version: 6.0.3.1
|
95
|
+
- !ruby/object:Gem::Dependency
|
96
|
+
name: factory_bot_rails
|
97
|
+
requirement: !ruby/object:Gem::Requirement
|
98
|
+
requirements:
|
99
|
+
- - "~>"
|
100
|
+
- !ruby/object:Gem::Version
|
101
|
+
version: 6.1.0
|
102
|
+
type: :development
|
103
|
+
prerelease: false
|
104
|
+
version_requirements: !ruby/object:Gem::Requirement
|
105
|
+
requirements:
|
106
|
+
- - "~>"
|
107
|
+
- !ruby/object:Gem::Version
|
108
|
+
version: 6.1.0
|
109
|
+
- !ruby/object:Gem::Dependency
|
110
|
+
name: rspec-rails
|
111
|
+
requirement: !ruby/object:Gem::Requirement
|
112
|
+
requirements:
|
113
|
+
- - "~>"
|
114
|
+
- !ruby/object:Gem::Version
|
115
|
+
version: 4.0.1
|
116
|
+
type: :development
|
117
|
+
prerelease: false
|
118
|
+
version_requirements: !ruby/object:Gem::Requirement
|
119
|
+
requirements:
|
120
|
+
- - "~>"
|
121
|
+
- !ruby/object:Gem::Version
|
122
|
+
version: 4.0.1
|
123
|
+
- !ruby/object:Gem::Dependency
|
124
|
+
name: rubocop
|
125
|
+
requirement: !ruby/object:Gem::Requirement
|
126
|
+
requirements:
|
127
|
+
- - "~>"
|
128
|
+
- !ruby/object:Gem::Version
|
129
|
+
version: '0.88'
|
130
|
+
type: :development
|
131
|
+
prerelease: false
|
132
|
+
version_requirements: !ruby/object:Gem::Requirement
|
133
|
+
requirements:
|
134
|
+
- - "~>"
|
135
|
+
- !ruby/object:Gem::Version
|
136
|
+
version: '0.88'
|
137
|
+
- !ruby/object:Gem::Dependency
|
138
|
+
name: simplecov
|
139
|
+
requirement: !ruby/object:Gem::Requirement
|
140
|
+
requirements:
|
141
|
+
- - "~>"
|
142
|
+
- !ruby/object:Gem::Version
|
143
|
+
version: 0.17.0
|
144
|
+
type: :development
|
145
|
+
prerelease: false
|
146
|
+
version_requirements: !ruby/object:Gem::Requirement
|
147
|
+
requirements:
|
148
|
+
- - "~>"
|
149
|
+
- !ruby/object:Gem::Version
|
150
|
+
version: 0.17.0
|
151
|
+
- !ruby/object:Gem::Dependency
|
152
|
+
name: simplecov-lcov
|
153
|
+
requirement: !ruby/object:Gem::Requirement
|
154
|
+
requirements:
|
155
|
+
- - "<"
|
156
|
+
- !ruby/object:Gem::Version
|
157
|
+
version: '0.8'
|
158
|
+
type: :development
|
159
|
+
prerelease: false
|
160
|
+
version_requirements: !ruby/object:Gem::Requirement
|
161
|
+
requirements:
|
162
|
+
- - "<"
|
163
|
+
- !ruby/object:Gem::Version
|
164
|
+
version: '0.8'
|
165
|
+
description: Opinionated out-of-the-box Rails API framework designed to simplify Rails
|
166
|
+
configuration
|
167
|
+
email:
|
168
|
+
- marc@marcqualie.com
|
169
|
+
executables: []
|
170
|
+
extensions: []
|
171
|
+
extra_rdoc_files: []
|
172
|
+
files:
|
173
|
+
- MIT-LICENSE
|
174
|
+
- README.md
|
175
|
+
- Rakefile
|
176
|
+
- db/migrate/20200724222614_create_users.rb
|
177
|
+
- db/migrate/20200724223120_create_access_tokens.rb
|
178
|
+
- db/migrate/20200725132221_create_permissions.rb
|
179
|
+
- lib/rapils.rb
|
180
|
+
- lib/rapils/application.rb
|
181
|
+
- lib/rapils/concerns/json_errors.rb
|
182
|
+
- lib/rapils/concerns/token_auth.rb
|
183
|
+
- lib/rapils/controllers/base_controller.rb
|
184
|
+
- lib/rapils/controllers/permissions_controller.rb
|
185
|
+
- lib/rapils/engine.rb
|
186
|
+
- lib/rapils/models/access_token.rb
|
187
|
+
- lib/rapils/models/base_record.rb
|
188
|
+
- lib/rapils/models/permission.rb
|
189
|
+
- lib/rapils/models/user.rb
|
190
|
+
- lib/rapils/policies/application_policy.rb
|
191
|
+
- lib/rapils/policies/permission_policy.rb
|
192
|
+
- lib/rapils/serializers/base_serializer.rb
|
193
|
+
- lib/rapils/serializers/permission_serializer.rb
|
194
|
+
- lib/rapils/setup.rb
|
195
|
+
- lib/rapils/version.rb
|
196
|
+
- lib/tasks/rapils_tasks.rake
|
197
|
+
homepage: https://github.com/marcqualie/rapils
|
198
|
+
licenses:
|
199
|
+
- MIT
|
200
|
+
metadata: {}
|
201
|
+
post_install_message:
|
202
|
+
rdoc_options: []
|
203
|
+
require_paths:
|
204
|
+
- lib
|
205
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
206
|
+
requirements:
|
207
|
+
- - ">="
|
208
|
+
- !ruby/object:Gem::Version
|
209
|
+
version: '0'
|
210
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
211
|
+
requirements:
|
212
|
+
- - ">"
|
213
|
+
- !ruby/object:Gem::Version
|
214
|
+
version: 1.3.1
|
215
|
+
requirements: []
|
216
|
+
rubygems_version: 3.1.4
|
217
|
+
signing_key:
|
218
|
+
specification_version: 4
|
219
|
+
summary: Opinionated out-of-the-box Rails API framework
|
220
|
+
test_files: []
|