rapils 0.1.0.pre.alpha1
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 +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: []
|