clerk-rails 0.1.2

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.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 8a7fdb8c57b025d5d0f123c73a89229562f25707d4db95131607f8d2a829001a
4
+ data.tar.gz: 3d9d1f1bfc333e8097c94e730ba6abd7ed94b3fc697ce9f616c0bc40a017d7cf
5
+ SHA512:
6
+ metadata.gz: df4a42eccb6c30f65d354b94141e38c3235879526b4f81ed097d5919487a34d349d1824cbaa8f552af73a9d76fab52ab0a9781f0902ab6a289cbb88a1fb46d26
7
+ data.tar.gz: c5c25f85ea49646387a75c23b2b02eb26dad51d205847b2753a89415a5ec963cdebf69ed577b885b067d34ebda5b4dcad9f475dcda0f456be2f3c88ced6db624
@@ -0,0 +1,20 @@
1
+ Copyright 2018 Colin Sidoti
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.
@@ -0,0 +1,28 @@
1
+ # Clerk
2
+ Short description and motivation.
3
+
4
+ ## Usage
5
+ How to use my plugin.
6
+
7
+ ## Installation
8
+ Add this line to your application's Gemfile:
9
+
10
+ ```ruby
11
+ gem 'clerk'
12
+ ```
13
+
14
+ And then execute:
15
+ ```bash
16
+ $ bundle
17
+ ```
18
+
19
+ Or install it yourself as:
20
+ ```bash
21
+ $ gem install clerk
22
+ ```
23
+
24
+ ## Contributing
25
+ Contribution directions go here.
26
+
27
+ ## License
28
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
@@ -0,0 +1,32 @@
1
+ begin
2
+ require 'bundler/setup'
3
+ rescue LoadError
4
+ puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
5
+ end
6
+
7
+ require 'rdoc/task'
8
+
9
+ RDoc::Task.new(:rdoc) do |rdoc|
10
+ rdoc.rdoc_dir = 'rdoc'
11
+ rdoc.title = 'Clerk'
12
+ rdoc.options << '--line-numbers'
13
+ rdoc.rdoc_files.include('README.md')
14
+ rdoc.rdoc_files.include('lib/**/*.rb')
15
+ end
16
+
17
+ APP_RAKEFILE = File.expand_path("test/dummy/Rakefile", __dir__)
18
+ load 'rails/tasks/engine.rake'
19
+
20
+ load 'rails/tasks/statistics.rake'
21
+
22
+ require 'bundler/gem_tasks'
23
+
24
+ require 'rake/testtask'
25
+
26
+ Rake::TestTask.new(:test) do |t|
27
+ t.libs << 'test'
28
+ t.pattern = 'test/**/*_test.rb'
29
+ t.verbose = false
30
+ end
31
+
32
+ task default: :test
@@ -0,0 +1,2 @@
1
+ //= link_directory ../javascripts/clerk .js
2
+ //= link_directory ../stylesheets/clerk .css
@@ -0,0 +1,15 @@
1
+ // This is a manifest file that'll be compiled into application.js, which will include all the files
2
+ // listed below.
3
+ //
4
+ // Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts,
5
+ // or any plugin's vendor/assets/javascripts directory can be referenced here using a relative path.
6
+ //
7
+ // It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
8
+ // compiled file. JavaScript code in this file should be added after the last require_* statement.
9
+ //
10
+ // Read Sprockets README (https://github.com/rails/sprockets#sprockets-directives) for details
11
+ // about supported directives.
12
+ //
13
+ //= require rails-ujs
14
+ //= require activestorage
15
+ //= require_tree .
@@ -0,0 +1,15 @@
1
+ /*
2
+ * This is a manifest file that'll be compiled into application.css, which will include all the files
3
+ * listed below.
4
+ *
5
+ * Any CSS and SCSS file within this directory, lib/assets/stylesheets, vendor/assets/stylesheets,
6
+ * or any plugin's vendor/assets/stylesheets directory can be referenced here using a relative path.
7
+ *
8
+ * You're free to add application-wide styles to this file and they'll appear at the bottom of the
9
+ * compiled file so the styles you add here take precedence over styles defined in any other CSS/SCSS
10
+ * files in this directory. Styles in this file should be added after the last require_* statement.
11
+ * It is generally better to create a new file per style scope.
12
+ *
13
+ *= require_tree .
14
+ *= require_self
15
+ */
@@ -0,0 +1,15 @@
1
+ module Clerk
2
+ class ApplicationController < ActionController::Base
3
+ def remote_cookie_accessor
4
+ # TODO: Only drop cookie if signature verifies
5
+ # TODO: Hide route entirely if client doesn't use remote cookies
6
+ cookie_domain = (request.host.include?(".") ? ".#{request.host}" : nil)
7
+ if params[:value].blank?
8
+ cookies.delete :clerk_session, domain: cookie_domain
9
+ else
10
+ cookies[:clerk_session] = {value: params[:value], domain: cookie_domain, expires: 20.years}
11
+ end
12
+ redirect_to params[:redirect]
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,47 @@
1
+ module Clerk
2
+ module ApplicationHelper
3
+ def current_account
4
+ return @clerk_current_account if defined?(@clerk_current_account)
5
+ @clerk_current_account ||= begin
6
+ if Clerk.config.session_mode==:database_session
7
+ raise "TODO"
8
+ elsif Clerk.config.session_mode==:cookie_session
9
+ Clerk::Account.find_by(id: current_account_id)
10
+ end
11
+ rescue => e
12
+ nil
13
+ end
14
+ end
15
+
16
+ def current_account_id
17
+ return @clerk_current_account_id if defined?(@clerk_current_account_id)
18
+ @clerk_current_account_id ||= begin
19
+ if Clerk.config.session_mode==:database_session
20
+ current_account.id
21
+ elsif Clerk.config.session_mode==:cookie_session
22
+ session_cookie = JSON.parse(cookies[:clerk_session])
23
+ nil if session_cookie.nil?
24
+ JSON.parse(session_cookie["d"])["k"]
25
+ end
26
+ rescue => e
27
+ nil
28
+ end
29
+ end
30
+
31
+ def clerk_sign_out_path
32
+ "#{Clerk.config.accounts_url}/sign_out"
33
+ end
34
+
35
+ def clerk_sign_in_path
36
+ "#{Clerk.config.accounts_url}"
37
+ end
38
+
39
+ def clerk_sign_up_path
40
+ "#{Clerk.config.accounts_url}/sign_up"
41
+ end
42
+
43
+ def clerk_add_card_path(account_id:, redirect_path:)
44
+ "#{Clerk.config.accounts_url}/add_card?account_id=#{account_id}&redirect_path=#{redirect_path}"
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,4 @@
1
+ module Clerk
2
+ class ApplicationJob < ActiveJob::Base
3
+ end
4
+ end
@@ -0,0 +1,6 @@
1
+ module Clerk
2
+ class ApplicationMailer < ActionMailer::Base
3
+ default from: 'from@example.com'
4
+ layout 'mailer'
5
+ end
6
+ end
@@ -0,0 +1,107 @@
1
+ module Clerk
2
+ class Account < Clerk::ApplicationRecord
3
+ self.table_name = self.clerk_table_name("accounts")
4
+ self.primary_key = 'id'
5
+
6
+ has_many :roles, class_name: "Clerk::Role"
7
+
8
+ def add_clerk_role(role_type_symbol, instance = nil)
9
+ json = { }
10
+ json[:name] = role_type_symbol.to_s
11
+ json[:account_id] = self.id
12
+
13
+ if not instance.nil?
14
+ json[:scope_class] = instance.class.name
15
+ json[:scope_id] = instance.id
16
+ end
17
+
18
+ server_url = "#{ENV['CLERK_ACCOUNTS_URL']}/roles"
19
+ HTTP.auth("Bearer #{ENV['CLERK_SECRET_KEY']}").post(server_url, :json => json)
20
+ end
21
+
22
+ def has_role?(role, scope)
23
+ roles.where(name: role, scope_class: scope.class.name, scope_id: scope.id).exists?
24
+ end
25
+
26
+ def roles_for(scope)
27
+ roles.where(scope_class: scope.class.name, scope_id: scope.id).pluck(:name).map(&:to_sym)
28
+ end
29
+
30
+ def has_permission?(permission, scope)
31
+ has_role?(scope.class.roles_with_permission(permission), scope)
32
+ end
33
+
34
+ def permissions_for(scope)
35
+ permissions = Set.new
36
+
37
+ roles = roles_for(scope)
38
+ roles.each do |role|
39
+ role_permissions = scope.class.clerk_permissions_map[role]
40
+
41
+ unless role_permissions.nil?
42
+ permissions.merge(role_permissions)
43
+ end
44
+ end
45
+
46
+ return permissions.to_a
47
+ end
48
+
49
+ private
50
+
51
+ def method_missing(method_name, *args, &block)
52
+ # Rails lazy loads modules. If an object hasn't been loaded yet, any inverse association
53
+ # will not be here yet. Just in case, load the constant here and re-call the method to
54
+ # before raising an error
55
+ @miss_test ||= {}
56
+ if @miss_test.has_key? method_name.to_sym
57
+ super
58
+ else
59
+ @miss_test[method_name.to_sym] = true
60
+ scope_class = method_name.to_s.classify.constantize
61
+ send(method_name, *args, &block)
62
+ end
63
+ rescue => e
64
+ super
65
+ end
66
+
67
+ class RolesWrapper
68
+ def initialize(instance, target)
69
+ @instance = instance
70
+ @target_class = target.to_s.classify.constantize
71
+ end
72
+
73
+ def with(role: nil, permission: nil)
74
+ if (role.nil? and permission.nil?) or (not role.nil? and not permission.nil?)
75
+ raise ArgumentError.new("Invalid argument, must supply either a role or permission")
76
+ end
77
+
78
+ if not role.nil?
79
+ return @target_class.where(
80
+ id: @instance.roles.where(scope_class: @target_class.name, name: role).pluck(:scope_id)
81
+ )
82
+ end
83
+
84
+ if not permission.nil?
85
+ roles = @target_class.roles_with_permission(permission)
86
+ return @target_class.where(
87
+ id: @instance.roles.where(scope_class: @target_class.name, name: roles).pluck(:scope_id)
88
+ )
89
+ end
90
+ end
91
+
92
+ def no_with
93
+ @target_class.where(
94
+ id: @instance.roles.where(scope_class: @target_class.name).pluck(:scope_id)
95
+ )
96
+ end
97
+
98
+ def method_missing(m, *args, &block)
99
+ no_with.send(m, *args, &block)
100
+ end
101
+
102
+ def inspect
103
+ no_with.inspect
104
+ end
105
+ end
106
+ end
107
+ end
@@ -0,0 +1,15 @@
1
+ module Clerk
2
+ class ApplicationRecord < ActiveRecord::Base
3
+ self.abstract_class = true
4
+ establish_connection Clerk.database_connection_url
5
+ def self.clerk_table_name(table_name)
6
+ version = Clerk::VERSION.split(".").map{|x| x.rjust(2, '0')}.join
7
+ "client.#{table_name}_#{version}_#{Clerk.config.secret_key}"
8
+ end
9
+
10
+ def self.clerk_table_name_nc(table_name)
11
+ version = Clerk::VERSION.split(".").map{|x| x.rjust(2, '0')}.join
12
+ "#{table_name}_#{version}_#{Clerk.config.secret_key}"
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,6 @@
1
+ module Clerk
2
+ class Client < Clerk::ApplicationRecord
3
+ self.table_name = self.clerk_table_name("clients")
4
+ self.primary_key = 'id'
5
+ end
6
+ end
@@ -0,0 +1,6 @@
1
+ module Clerk
2
+ class Plan < Clerk::ApplicationRecord
3
+ self.table_name = self.clerk_table_name("plans")
4
+ self.primary_key = 'id'
5
+ end
6
+ end
@@ -0,0 +1,83 @@
1
+ module Clerk
2
+ class Role < Clerk::ApplicationRecord
3
+ self.table_name = self.clerk_table_name("roles")
4
+ self.primary_key = 'id'
5
+
6
+ belongs_to :account, class_name: "Clerk::Account"
7
+
8
+ def self._insert_record(values)
9
+ server_url = "#{ENV['CLERK_ACCOUNTS_URL']}/roles"
10
+ begin
11
+ response = HTTP.auth("Bearer #{ENV['CLERK_SECRET_KEY']}").post(server_url, :json => values)
12
+ id = JSON.parse(response.body)["id"]
13
+ rescue
14
+ raise Clerk::Errors::ClerkServerError.new("Failed to save the role", self)
15
+ end
16
+
17
+ if response.status.code != 200 or id.nil?
18
+ raise Clerk::Errors::ClerkServerError.new("Failed to save the role", self)
19
+ end
20
+
21
+ return id
22
+ end
23
+
24
+ def self._update_record(values, constraints)
25
+ update_id = constraints["id"]
26
+ if update_id.nil?
27
+ raise ActiveRecord::RecordNotFound.new("Must pass an id to update a role", self)
28
+ end
29
+
30
+ server_url = "#{ENV['CLERK_ACCOUNTS_URL']}/roles/#{update_id}"
31
+ begin
32
+ response = HTTP.auth("Bearer #{ENV['CLERK_SECRET_KEY']}").patch(server_url, :json => values.merge!(constraints))
33
+ rescue
34
+ raise Clerk::Errors::ClerkServerError.new("Failed to update the role", self)
35
+ end
36
+
37
+ if response.status.code != 200
38
+ raise Clerk::Errors::ClerkServerError.new("Failed to update the role", self)
39
+ end
40
+
41
+ # overriden function returns the number of rows affected
42
+ return 1
43
+ end
44
+
45
+ def self._delete_record(constraints)
46
+ delete_id = constraints["id"]
47
+ if delete_id.nil?
48
+ raise ActiveRecord::RecordNotFound.new("Must pass an id to delete a role", self)
49
+ end
50
+
51
+ server_url = "#{ENV['CLERK_ACCOUNTS_URL']}/roles/#{delete_id}"
52
+
53
+ begin
54
+ response = HTTP.auth("Bearer #{ENV['CLERK_SECRET_KEY']}").delete(server_url)
55
+ rescue
56
+ raise Clerk::Errors::ClerkServerError.new("Failed to delete the role", self)
57
+ end
58
+
59
+
60
+ if response.status.code != 200
61
+ raise Clerk::Errors::ClerkServerError.new("Failed to delete the role", self)
62
+ end
63
+
64
+ # overriden function returns the number of rows affected
65
+ return 1
66
+ end
67
+
68
+
69
+ # disable bulk calls
70
+ def self.update_all(updates)
71
+ raise Clerk::Errors::MethodDisabled.new("update_all is disabled for Clerk::Role")
72
+ end
73
+
74
+ def self.delete_all
75
+ raise Clerk::Errors::MethodDisabled.new("delete_all is disabled for Clerk::Role")
76
+ end
77
+
78
+ def self.destroy_all
79
+ raise Clerk::Errors::MethodDisabled.new("destroy_all is disabled for Clerk::Role")
80
+ end
81
+ end
82
+ end
83
+
@@ -0,0 +1,66 @@
1
+ module Clerk
2
+ module Clerked
3
+ extend ActiveSupport::Concern
4
+
5
+ included do
6
+ @@clerk_permissions_map = {}
7
+ @@clerk_roles_map = {}
8
+
9
+ has_many :clerk_roles, clerk_roles_scope, class_name: "Clerk::Role", foreign_key: :scope_id
10
+
11
+ has_many :accounts, through: :clerk_roles, source: :account do
12
+
13
+ def with(role: nil, permission: nil)
14
+ if (role.nil? and permission.nil?) or (not role.nil? and not permission.nil?)
15
+ raise ArgumentError.new("Invalid argument, must supply either a role or permission")
16
+ end
17
+
18
+ if not role.nil?
19
+ return where(Clerk::Role.table_name=>{name: role})
20
+ elsif not permission.nil?
21
+ all_roles = self.proxy_association.owner.class.roles_with_permission(permission)
22
+ return where(Clerk::Role.table_name=>{name: all_roles})
23
+ end
24
+ end
25
+
26
+ end
27
+ end
28
+
29
+ def has_role?(role, account)
30
+ account.has_role?(role, self)
31
+ end
32
+
33
+ def roles_for(account)
34
+ account.roles_for(self)
35
+ end
36
+
37
+ class_methods do
38
+ def clerk_permissions_map
39
+ @@clerk_permissions_map
40
+ end
41
+
42
+ def clerk_roles_map
43
+ @@clerk_roles_map
44
+ end
45
+
46
+ def roles_with_permission(permission)
47
+ @@clerk_roles_map[permission] ||= begin
48
+ roles_with_permission = []
49
+
50
+ clerk_permissions_map.keys.each do |key|
51
+ if clerk_permissions_map[key].include?(permission)
52
+ roles_with_permission << key
53
+ end
54
+ end
55
+
56
+ roles_with_permission
57
+ end
58
+ end
59
+
60
+ def clerk_roles_scope
61
+ class_name = self.name
62
+ ->{ where(scope_class: class_name) }
63
+ end
64
+ end
65
+ end
66
+ end
@@ -0,0 +1,18 @@
1
+ module Clerk
2
+ module Errors
3
+ class ClerkError < StandardError; end
4
+
5
+ class ClerkServerError < ClerkError
6
+ def initialize(message = nil, model = nil)
7
+ @model = model
8
+ super(message)
9
+ end
10
+ end
11
+
12
+ class MethodDisabled < ClerkError
13
+ def initialize(message = nil)
14
+ super(message)
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,16 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title>Clerk</title>
5
+ <%= csrf_meta_tags %>
6
+ <%= csp_meta_tag %>
7
+
8
+ <%= stylesheet_link_tag "clerk/application", media: "all" %>
9
+ <%= javascript_include_tag "clerk/application" %>
10
+ </head>
11
+ <body>
12
+
13
+ <%= yield %>
14
+
15
+ </body>
16
+ </html>
@@ -0,0 +1,3 @@
1
+ Clerk::Engine.routes.draw do
2
+ get 'remote_cookie_accessor', to: 'clerk/application#remote_cookie_accessor'
3
+ end
@@ -0,0 +1,30 @@
1
+ require "clerk/engine"
2
+
3
+ module Clerk
4
+ class << self
5
+ attr_reader :config
6
+
7
+ def configure
8
+ @config = Configuration.new
9
+ yield config
10
+ if Rails.env.development?
11
+ config.environment = :development
12
+ config.session_mode = :cookie_session
13
+ config.cookie_host = nil
14
+ else
15
+ client = Clerk::Client.first
16
+ config.environment = client.environment.to_sym
17
+ config.session_mode = client.session_mode.to_sym
18
+ config.cookie_host = client.cookie_host
19
+ end
20
+ end
21
+
22
+ def database_connection_url
23
+ @database_connection_url ||= "#{Clerk.config.database_url.dup.insert(11,"#{Clerk.config.secret_key}@")}/clerk?prepared_statements=false"
24
+ end
25
+ end
26
+
27
+ class Configuration
28
+ attr_accessor :accounts_url, :database_url, :secret_key, :public_key, :environment, :session_mode, :last_account, :cookie_host
29
+ end
30
+ end
@@ -0,0 +1,60 @@
1
+ module Clerk
2
+ class Engine < ::Rails::Engine
3
+ initializer "clerk.load_helpers" do |app|
4
+ ::ActionController::Base.send :include, Clerk::ApplicationHelper
5
+ ::ActiveRecord::Base.class_eval do
6
+
7
+ def self.clerk(association_name, permissions: [])
8
+ plural_role = association_name.to_s.pluralize.to_sym
9
+ singular_role = association_name.to_s.singularize.to_sym
10
+
11
+ roles_association = :"clerk_roles_#{association_name}"
12
+
13
+ remote_class = self.name
14
+
15
+ unless self.respond_to? :clerk_roles
16
+ self.class_eval do
17
+ include Clerk::Clerked
18
+ end
19
+ end
20
+
21
+ has_many roles_association,
22
+ ->{ where(scope_class: remote_class, name: singular_role) },
23
+ class_name: "Clerk::Role",
24
+ foreign_key: :scope_id
25
+
26
+ plural_role = association_name.to_s.pluralize.to_sym
27
+ singular_role = association_name.to_s.singularize.to_sym
28
+
29
+ account_accessor = self.name.underscore.pluralize.to_sym
30
+
31
+ # Add clerk permissions to `self` the associated class
32
+ self.clerk_permissions_map[singular_role] = permissions
33
+
34
+ # Add magic methods to Clerk::Acount
35
+ Clerk::Account.class_eval do
36
+ define_method account_accessor do
37
+ self.class::RolesWrapper.new(self, account_accessor)
38
+ end
39
+
40
+ define_method :"is_#{singular_role}?" do |*args|
41
+ has_role?(singular_role, *args)
42
+ end
43
+
44
+ permissions.each do |permission|
45
+ define_method :"can_#{permission}?" do |*args|
46
+ has_permission?(permission, *args)
47
+ end
48
+ end
49
+ end
50
+
51
+ [
52
+ association_name.to_sym,
53
+ through: roles_association,
54
+ source: :account
55
+ ]
56
+ end
57
+ end
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,3 @@
1
+ module Clerk
2
+ VERSION = '0.1.2'
3
+ end
@@ -0,0 +1,4 @@
1
+ # desc "Explaining what the task does"
2
+ # task :clerk do
3
+ # # Task goes here
4
+ # end
metadata ADDED
@@ -0,0 +1,95 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: clerk-rails
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.2
5
+ platform: ruby
6
+ authors:
7
+ - Clerk
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2018-12-09 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rails
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: 5.2.0
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: 5.2.0
27
+ - !ruby/object:Gem::Dependency
28
+ name: pg
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ description: Clerk is the easiest way to manage accounts.
42
+ email:
43
+ - bsidoti@gmail.com
44
+ executables: []
45
+ extensions: []
46
+ extra_rdoc_files: []
47
+ files:
48
+ - MIT-LICENSE
49
+ - README.md
50
+ - Rakefile
51
+ - app/assets/config/clerk_manifest.js
52
+ - app/assets/javascripts/clerk/application.js
53
+ - app/assets/stylesheets/clerk/application.css
54
+ - app/controllers/clerk/application_controller.rb
55
+ - app/helpers/clerk/application_helper.rb
56
+ - app/jobs/clerk/application_job.rb
57
+ - app/mailers/clerk/application_mailer.rb
58
+ - app/models/clerk/account.rb
59
+ - app/models/clerk/application_record.rb
60
+ - app/models/clerk/client.rb
61
+ - app/models/clerk/plan.rb
62
+ - app/models/clerk/role.rb
63
+ - app/models/concerns/clerk/clerked.rb
64
+ - app/models/concerns/clerk/errors.rb
65
+ - app/views/layouts/clerk/application.html.erb
66
+ - config/routes.rb
67
+ - lib/clerk-rails.rb
68
+ - lib/clerk/engine.rb
69
+ - lib/clerk/version.rb
70
+ - lib/tasks/clerk_tasks.rake
71
+ homepage:
72
+ licenses:
73
+ - MIT
74
+ metadata: {}
75
+ post_install_message:
76
+ rdoc_options: []
77
+ require_paths:
78
+ - lib
79
+ required_ruby_version: !ruby/object:Gem::Requirement
80
+ requirements:
81
+ - - ">="
82
+ - !ruby/object:Gem::Version
83
+ version: '0'
84
+ required_rubygems_version: !ruby/object:Gem::Requirement
85
+ requirements:
86
+ - - ">="
87
+ - !ruby/object:Gem::Version
88
+ version: '0'
89
+ requirements: []
90
+ rubyforge_project:
91
+ rubygems_version: 2.7.8
92
+ signing_key:
93
+ specification_version: 4
94
+ summary: Rails Engine for Clerk
95
+ test_files: []