authegy 0.0.1

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.
Files changed (34) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +5 -0
  3. data/README.md +70 -0
  4. data/app/assets/config/authegy_manifest.js +2 -0
  5. data/app/assets/javascripts/authegy/application.js +15 -0
  6. data/app/assets/stylesheets/authegy/application.css +15 -0
  7. data/app/controllers/authegy/application_controller.rb +5 -0
  8. data/app/helpers/authegy/application_helper.rb +4 -0
  9. data/app/jobs/authegy/application_job.rb +4 -0
  10. data/app/mailers/authegy/application_mailer.rb +6 -0
  11. data/app/models/authegy/application_record.rb +5 -0
  12. data/app/views/layouts/authegy/application.html.erb +16 -0
  13. data/lib/authegy.rb +27 -0
  14. data/lib/authegy/authorizable.rb +57 -0
  15. data/lib/authegy/controller_helpers.rb +62 -0
  16. data/lib/authegy/engine.rb +5 -0
  17. data/lib/authegy/models/person.rb +24 -0
  18. data/lib/authegy/models/role.rb +18 -0
  19. data/lib/authegy/models/role_assignment.rb +16 -0
  20. data/lib/authegy/models/user.rb +24 -0
  21. data/lib/authegy/version.rb +3 -0
  22. data/lib/devise/models/database_authenticatable_with_person_email.rb +30 -0
  23. data/lib/devise/models/validatable_with_person_email.rb +41 -0
  24. data/lib/generators/authegy/USAGE +8 -0
  25. data/lib/generators/authegy/install_generator.rb +29 -0
  26. data/lib/generators/authegy/models_generator.rb +46 -0
  27. data/lib/generators/authegy/orm_helpers.rb +39 -0
  28. data/lib/generators/authegy/templates/models_migration.erb +83 -0
  29. data/lib/generators/authegy/templates/person_model.rb +9 -0
  30. data/lib/generators/authegy/templates/role_assignment_model.rb +6 -0
  31. data/lib/generators/authegy/templates/role_model.rb +6 -0
  32. data/lib/generators/authegy/templates/user_model.rb +15 -0
  33. data/lib/tasks/authegy_tasks.rake +4 -0
  34. metadata +183 -0
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: d07d7606ab2766ec64bdec8b4755b033c697bc5d6eccda20f39d8fc308c2489d
4
+ data.tar.gz: 51685f9e90d411e8514d14c795ef5a6a2b57a0e9234f339ebf591c0ebe03718e
5
+ SHA512:
6
+ metadata.gz: 05a858a671eab9e43fc0c7bf49d77e8abe1ddf81f92c7f60ee71041d0c33e3e4ac0b12abb34ee6282192f16717b196858139583519f4ed1be06abd30dc129403
7
+ data.tar.gz: cc880a11cbaff90d3e037f6058e215f5cfbdf9880df258df0d0db6d0c1ffc1703bf86207e0a42fbdfc2f278e9aeab52ade142d0966b0c6d4d72575ea8f76fdc0
@@ -0,0 +1,5 @@
1
+ # Authegy Changelog
2
+
3
+ ## Version 0.0.1
4
+
5
+ - Initial Implementation
@@ -0,0 +1,70 @@
1
+ # Authegy
2
+
3
+ The Authegy gem is a library that combines several useful ruby libraries to
4
+ provide an opinionated authentication and role-based authorization models for
5
+ your rails apps.
6
+
7
+ ## Installation
8
+
9
+ Add this line to your application's Gemfile:
10
+
11
+ ```ruby
12
+ gem 'authegy'
13
+ ```
14
+
15
+ And then execute:
16
+
17
+ $ bundle
18
+
19
+ Or install it yourself as:
20
+
21
+ $ gem install authegy
22
+
23
+ ## Usage
24
+
25
+ ### Basic Use Case: The User & Role models
26
+
27
+ - Use only a single "User" class, with several roles associated to it - instead
28
+ of having multiple "user" classes, which tend to have duplicated code &
29
+ functionality between them.
30
+ - Roles can also be optionally associated to different "Resource" models, so we
31
+ can limit the authorization to certain objects. Examples:
32
+ - "User 2" is an "Administrator" of "Website 2" (so he/she can change the
33
+ Website 2's URL)
34
+ - "User 3" is a "Procurement Manager" of "Company 4" (so he/she can place
35
+ orders on behalf of the Company 4)
36
+
37
+ ![Base Use Case](docs/use-cases/base-use-case.svg)
38
+
39
+
40
+
41
+
42
+ ## Development
43
+
44
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run
45
+ `rake spec` to run the tests. You can also run `bin/console` for an interactive
46
+ prompt that will allow you to experiment.
47
+
48
+ To install this gem onto your local machine, run `bundle exec rake install`. To
49
+ release a new version, update the version number in `version.rb`, and then run
50
+ `bundle exec rake release`, which will create a git tag for the version, push
51
+ git commits and tags, and push the `.gem` file to
52
+ [rubygems.org](https://rubygems.org).
53
+
54
+ ## Contributing
55
+
56
+ Bug reports and pull requests are welcome on GitHub at
57
+ https://github.com/vovimayhem/authegy. This project is intended to be a safe,
58
+ welcoming space for collaboration, and contributors are expected to adhere to
59
+ the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
60
+
61
+ ## License
62
+
63
+ The gem is available as open source under the terms of the
64
+ [MIT License](https://opensource.org/licenses/MIT).
65
+
66
+ ## Code of Conduct
67
+
68
+ Everyone interacting in the A2 project’s codebases, issue trackers, chat rooms
69
+ and mailing lists is expected to follow the
70
+ [Code of Conduct](https://github.com/vovimayhem/authegy/blob/master/CODE_OF_CONDUCT.md).
@@ -0,0 +1,2 @@
1
+ //= link_directory ../javascripts/authegy .js
2
+ //= link_directory ../stylesheets/authegy .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,5 @@
1
+ module Authegy
2
+ class ApplicationController < ActionController::Base
3
+ protect_from_forgery with: :exception
4
+ end
5
+ end
@@ -0,0 +1,4 @@
1
+ module Authegy
2
+ module ApplicationHelper
3
+ end
4
+ end
@@ -0,0 +1,4 @@
1
+ module Authegy
2
+ class ApplicationJob < ActiveJob::Base
3
+ end
4
+ end
@@ -0,0 +1,6 @@
1
+ module Authegy
2
+ class ApplicationMailer < ActionMailer::Base
3
+ default from: 'from@example.com'
4
+ layout 'mailer'
5
+ end
6
+ end
@@ -0,0 +1,5 @@
1
+ module Authegy
2
+ class ApplicationRecord < ActiveRecord::Base
3
+ self.abstract_class = true
4
+ end
5
+ end
@@ -0,0 +1,16 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title>Authegy</title>
5
+ <%= csrf_meta_tags %>
6
+ <%= csp_meta_tag %>
7
+
8
+ <%= stylesheet_link_tag "authegy/application", media: "all" %>
9
+ <%= javascript_include_tag "authegy/application" %>
10
+ </head>
11
+ <body>
12
+
13
+ <%= yield %>
14
+
15
+ </body>
16
+ </html>
@@ -0,0 +1,27 @@
1
+ require 'active_support/dependencies'
2
+ require 'devise'
3
+ require 'authegy/engine'
4
+
5
+ module Authegy
6
+ autoload :Authorizable, 'authegy/authorizable'
7
+
8
+ autoload :Person, 'authegy/models/person'
9
+ autoload :RoleAssignment, 'authegy/models/role_assignment'
10
+ autoload :Role, 'authegy/models/role'
11
+ autoload :User, 'authegy/models/user'
12
+
13
+ autoload :ControllerHelpers, 'authegy/controller_helpers'
14
+
15
+ def self.extract_resource_attributes(resource_type_or_instance)
16
+ return { resource_type: resource_type_or_instance } \
17
+ if resource_type_or_instance.is_a? String
18
+
19
+ return { resource_type: resource_type_or_instance.name } \
20
+ if resource_type_or_instance.is_a? Class
21
+
22
+ return {
23
+ resource_type: resource_type_or_instance.class.name,
24
+ resource_id: resource_type_or_instance.id
25
+ } if resource_type_or_instance.respond_to? :id
26
+ end
27
+ end
@@ -0,0 +1,57 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Authegy
4
+ module Authorizable
5
+ extend ActiveSupport::Concern
6
+
7
+ included do
8
+ has_many :role_assignments,
9
+ class_name: '::RoleAssignment',
10
+ inverse_of: :actor,
11
+ foreign_key: :actor_id
12
+
13
+ has_many :assigned_roles,
14
+ -> { distinct },
15
+ through: :role_assignments,
16
+ source: :role
17
+ end
18
+
19
+ def assign_role(role_name, resource_type_or_instance = nil)
20
+ assignment_attributes = {
21
+ role: ::Role.find_or_create_by(name: role_name)
22
+ }
23
+
24
+ if resource_type_or_instance.present?
25
+ assignment_attributes.merge! Authegy
26
+ .extract_resource_attributes(resource_type_or_instance)
27
+ end
28
+
29
+ role_assignments.find_or_create_by assignment_attributes
30
+ end
31
+
32
+ def has_role?(role_name, resource_type_or_instance = nil)
33
+ matching_attributes = { role: role_name.to_s }
34
+
35
+ return role_assignment_list.select do |assignment|
36
+ assignment[:role] == matching_attributes[:role]
37
+ end.any? if resource_type_or_instance.blank?
38
+
39
+ matching_attributes.merge! Authegy
40
+ .extract_resource_attributes(resource_type_or_instance)
41
+
42
+ role_assignment_list.select do |assignment|
43
+ assignment == matching_attributes
44
+ end.any?
45
+ end
46
+
47
+ private
48
+
49
+ def role_assignment_list
50
+ @role_assignment_list ||= role_assignments.includes(:role).map do |assgn|
51
+ assgn.attributes.slice('resource_type', 'resource_id').merge!(
52
+ role: assgn.role.name
53
+ ).symbolize_keys!
54
+ end
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,62 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Authegy
4
+ # = AuthorizationHelper
5
+ #
6
+ # Methods that deal with defining access to resources by user roles
7
+ module ControllerHelpers
8
+ # authorize_action!
9
+ # Usage:
10
+ # ```
11
+ # class ThingsController < ApplicationController
12
+ # before_action do
13
+ # authorize_action! to: 'thing.owner'
14
+ # authorize_action! :administrator, :manager, of: 'thing.other_thing'
15
+ # authorize_action! :anyone, from: 'thing.company'
16
+ # end, only: [:index, :show]
17
+ # end
18
+ # ```
19
+ def authorize_action!(*given_roles)
20
+ given_roles, options = AuthorizationHelper.parse_given_roles(given_roles)
21
+ auth_request_env['match_roles_on'] = options[:match_roles_on] if options.key?(:match_roles_on)
22
+
23
+ return auth_request_env['authorized_roles'] = Role.all if super_admin_user?
24
+ auth_request_env['authorized_roles'] = current_user_roles.where(name: given_roles)
25
+
26
+ # error if only general manager, plant managers can create
27
+
28
+ raise ActionErrors::Forbidden if authorized_roles.map(&:name).count == 1 && current_user_roles.first.name == 'manager' && current_user_roles.where(name: 'manager').where.not(target_id: nil).empty?
29
+ raise ActionErrors::Forbidden unless authorized_roles.any?
30
+ end
31
+
32
+ def authorize_action(*given_roles)
33
+ authorize_action!(*given_roles)
34
+ rescue
35
+ false
36
+ end
37
+
38
+ def super_admin_user?
39
+ auth_request_env['super_admin_user'] ||= current_user_roles
40
+ .where(name: :administrator, target_id: nil)
41
+ .any?
42
+ end
43
+
44
+ # :nodoc:
45
+ # Reek complains about multiple calls to `request.env` and/or not refering to object state...
46
+ define_method(:auth_request_env) { request.env }
47
+
48
+ define_method(:current_user_roles) { current_user.roles }
49
+ define_method(:authorized_roles) { auth_request_env['authorized_roles'] }
50
+ #
51
+ # def match_roles_on
52
+ # auth_request_env['match_roles_on']
53
+ # end
54
+
55
+ def self.parse_given_roles(given_roles = [])
56
+ given_roles = [:administrator] unless given_roles.any?
57
+ options = given_roles.last.is_a?(Hash) ? given_roles.pop.with_indifferent_access : {}
58
+ [given_roles, options]
59
+ end
60
+ end
61
+
62
+ end
@@ -0,0 +1,5 @@
1
+ module Authegy
2
+ class Engine < ::Rails::Engine
3
+ isolate_namespace Authegy
4
+ end
5
+ end
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Authegy
4
+ # Person holds the "Profile" for a given User, but we can also have just
5
+ # Person profiles without a user, as is the case for "Board Members"
6
+ class Person < ApplicationRecord
7
+ include Authegy::Authorizable
8
+
9
+ self.table_name = :people
10
+ self.abstract_class = true
11
+
12
+ # Validations from 'validatable':
13
+ validates_uniqueness_of :email,
14
+ allow_blank: true,
15
+ if: :will_save_change_to_email?
16
+
17
+ validates_format_of :email,
18
+ with: Devise.email_regexp,
19
+ allow_blank: true,
20
+ if: :will_save_change_to_email?
21
+
22
+ has_one :user, class_name: '::User', inverse_of: :person, foreign_key: :id
23
+ end
24
+ end
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Authegy
4
+ #= Authegy::Role
5
+ # A `Role`
6
+ class Role < ApplicationRecord
7
+ self.table_name = :roles
8
+ self.abstract_class = true
9
+
10
+ validates :name, format: {
11
+ with: /\A[a-z_]+\z/,
12
+ message: 'only allows letters and underscores'
13
+ }
14
+
15
+ has_many :assignments, class_name: '::RoleAssignment', inverse_of: :role
16
+ has_many :actors, -> { distinct }, through: :assignments, source: :actor
17
+ end
18
+ end
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Authegy
4
+ # A `RoleAssignment` associates a `Person` to an optional "resource", and
5
+ # assigns a particular roleholds the "Profile" for a given User, but we can
6
+ # also have just Person profiles without a user, as is the case for
7
+ # "Board Members"
8
+ class RoleAssignment < ApplicationRecord
9
+ self.table_name = :role_assignments
10
+ self.abstract_class = true
11
+
12
+ belongs_to :actor, class_name: '::Person', foreign_key: :actor_id
13
+ belongs_to :role
14
+ belongs_to :resource, optional: true, polymorphic: true
15
+ end
16
+ end
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'devise/models/validatable_with_person_email'
4
+ require 'devise/models/database_authenticatable_with_person_email'
5
+
6
+ module Authegy
7
+ #= User
8
+ #
9
+ # Represents a person which is able to sign-in to the application.
10
+ # Users are intended for authentification, the actual profile sits in Person.
11
+ class User < ApplicationRecord
12
+ self.table_name = :users
13
+ self.abstract_class = true
14
+
15
+ devise :database_authenticatable_with_person_email,
16
+ :validatable_with_person_email
17
+
18
+ belongs_to :person, inverse_of: :user, foreign_key: :id
19
+ delegate :email, :email=, :name, to: :person, allow_nil: true
20
+
21
+ delegate :assigned_roles, :assign_role, :has_role?, :has_any_role?,
22
+ :remove_role, :role_assignments, to: :person
23
+ end
24
+ end
@@ -0,0 +1,3 @@
1
+ module Authegy
2
+ VERSION = '0.0.1'.freeze
3
+ end
@@ -0,0 +1,30 @@
1
+ module Devise
2
+ module Models
3
+ #= DatabaseAuthenticatableWithPersonEmail
4
+ #
5
+ # Overrides Devise::Models::DatabaseAuthenticatable, so but instead of
6
+ # expecting the `email` field to be in the authenticatable model, is located
7
+ # instead in the associated `Person` model
8
+ module DatabaseAuthenticatableWithPersonEmail
9
+ extend ActiveSupport::Concern
10
+
11
+ included do
12
+ # Include the original module:
13
+ devise :database_authenticatable
14
+ end
15
+
16
+ module ClassMethods
17
+ Devise::Models.config self
18
+
19
+ # Override of
20
+ # Devise::Models::Authenticatable.find_first_by_auth_conditions:
21
+ def find_first_by_auth_conditions(tainted_conditions, opts={})
22
+ filter = devise_parameter_filter.filter(tainted_conditions).merge opts
23
+ person_filter = filter.extract! :email
24
+ matching_person_scope = Person.where person_filter
25
+ User.where(filter).joins(:person).merge(matching_person_scope).first
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,41 @@
1
+ module Devise
2
+ module Models
3
+ #= ValidatableWithPersonEmail
4
+ #
5
+ # A re-implementation of Devise::Models::Validatable, but instead of
6
+ # expecting the `email` field to be in the authenticatable model, is located
7
+ # instead in the `Person` associated model
8
+ module ValidatableWithPersonEmail
9
+ extend ActiveSupport::Concern
10
+
11
+ included do
12
+ validates_presence_of :password, if: :password_required?
13
+ validates_confirmation_of :password, if: :password_required?
14
+
15
+ validates_length_of :password,
16
+ within: password_length,
17
+ allow_blank: true
18
+
19
+ validate :person_email_must_be_present
20
+ end
21
+
22
+ module ClassMethods
23
+ Devise::Models.config self, :email_regexp, :password_length
24
+ end
25
+
26
+ protected
27
+
28
+ # Checks whether a password is needed or not. For validations only.
29
+ # Passwords are always required if it's a new record, or if the password
30
+ # or confirmation are being set somewhere.
31
+ def password_required?
32
+ !persisted? || !password.nil? || !password_confirmation.nil?
33
+ end
34
+
35
+ def person_email_must_be_present
36
+ return if person&.email.present?
37
+ errors.add :base, 'Person email must be present'
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,8 @@
1
+ Description:
2
+ Explain the generator
3
+
4
+ Example:
5
+ rails generate authegy Thing
6
+
7
+ This will create:
8
+ what/will/it/create
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rails/generators/base'
4
+
5
+ class InstallGenerator < Rails::Generators::Base
6
+ namespace 'authegy:install'
7
+ source_root File.expand_path('templates', __dir__)
8
+
9
+
10
+ def generate_customized_devise_install
11
+ generate 'devise:install'
12
+
13
+ gsub_file 'config/initializers/devise.rb',
14
+ 'config.sign_out_via = :delete',
15
+ 'config.sign_out_via = %i[get delete]'
16
+ end
17
+
18
+ def generate_authegy_install
19
+ generate 'authegy:models People'
20
+ end
21
+
22
+ def add_devise_routes
23
+ route <<~STRING
24
+ devise_for :users,
25
+ path: '/',
26
+ path_names: { sign_in: 'sign-in', sign_out: 'sign-out' }
27
+ STRING
28
+ end
29
+ end
@@ -0,0 +1,46 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rails/generators/active_record'
4
+ require 'generators/authegy/orm_helpers'
5
+
6
+ class ModelsGenerator < ActiveRecord::Generators::Base
7
+ namespace 'authegy:models'
8
+ include Authegy::Generators::OrmHelpers
9
+ source_root File.expand_path('templates', __dir__)
10
+
11
+ argument :attributes,
12
+ type: :array,
13
+ default: [],
14
+ banner: 'field:type field:type'
15
+
16
+ # class_option :primary_key_type, type: :string, desc: 'The type for primary key'
17
+
18
+ def copy_authegy_migration
19
+ # if (behavior == :invoke && model_exists?) || (behavior == :revoke && migration_exists?(table_name))
20
+ # migration_template "migration_existing.rb", "#{migration_path}/add_devise_to_#{table_name}.rb", migration_version: migration_version
21
+ # else
22
+ migration_template(
23
+ 'models_migration.erb',
24
+ "#{migration_path}/create_authegy_model_tables.rb",
25
+ migration_version: migration_version
26
+ )
27
+ # end
28
+ end
29
+
30
+ def generate_app_models
31
+ copy_file 'person_model.rb', 'app/models/person.rb'
32
+ copy_file 'role_model.rb', 'app/models/role.rb'
33
+ copy_file 'user_model.rb', 'app/models/user.rb'
34
+ copy_file 'role_assignment_model.rb', 'app/models/role_assignment.rb'
35
+ end
36
+
37
+ def rails5_and_up?
38
+ Rails::VERSION::MAJOR >= 5
39
+ end
40
+
41
+ def migration_version
42
+ if rails5_and_up?
43
+ "[#{Rails::VERSION::MAJOR}.#{Rails::VERSION::MINOR}]"
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,39 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Authegy
4
+ module Generators
5
+ module OrmHelpers
6
+ def model_contents
7
+ buffer = <<-CONTENT
8
+ # Include default devise modules. Others available are:
9
+ # :confirmable, :lockable, :timeoutable, :trackable and :omniauthable
10
+ devise :database_authenticatable, :registerable,
11
+ :recoverable, :rememberable, :validatable
12
+ CONTENT
13
+ buffer
14
+ end
15
+
16
+ private
17
+
18
+ def model_exists?
19
+ File.exist?(File.join(destination_root, model_path))
20
+ end
21
+
22
+ def migration_exists?(table_name)
23
+ Dir.glob("#{File.join(destination_root, migration_path)}/[0-9]*_*.rb").grep(/\d+_add_devise_to_#{table_name}.rb$/).first
24
+ end
25
+
26
+ def migration_path
27
+ if Rails.version >= '5.0.3'
28
+ db_migrate_path
29
+ else
30
+ @migration_path ||= File.join("db", "migrate")
31
+ end
32
+ end
33
+
34
+ def model_path
35
+ @model_path ||= File.join("app", "models", "#{file_path}.rb")
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,83 @@
1
+ # frozen_string_literal: true
2
+
3
+ class CreateAuthegyModelTables < ActiveRecord::Migration<%= migration_version %>
4
+ def change
5
+ create_people_table
6
+ create_users_table
7
+ create_roles_table
8
+ create_role_assignments_table
9
+ end
10
+
11
+ def create_people_table
12
+ create_table :people do |t|
13
+ t.string :first_name, null: false
14
+ t.string :last_name, null: false
15
+ t.string :email, index: { unique: true }
16
+
17
+ # Feel free to add additional fields, such as 'nickname', etc:
18
+ # t.string :phone
19
+
20
+ t.timestamps null: false
21
+ end
22
+ end
23
+
24
+ def create_users_table
25
+ create_table :users do |t|
26
+ ## Database authenticatable
27
+ t.string :encrypted_password, null: false, default: ''
28
+
29
+ ## Recoverable
30
+ t.string :reset_password_token, index: { unique: true }
31
+ t.datetime :reset_password_sent_at
32
+
33
+ ## Rememberable
34
+ t.datetime :remember_created_at
35
+
36
+ ## Trackable
37
+ # t.integer :sign_in_count, default: 0, null: false
38
+ # t.datetime :current_sign_in_at
39
+ # t.datetime :last_sign_in_at
40
+ # t.inet :current_sign_in_ip
41
+ # t.inet :last_sign_in_ip
42
+
43
+ ## Confirmable
44
+ # t.string :confirmation_token, index: { unique: true }
45
+ # t.datetime :confirmed_at
46
+ # t.datetime :confirmation_sent_at
47
+ # t.string :unconfirmed_email # Only if using reconfirmable
48
+
49
+ ## Lockable
50
+ # # Only if lock strategy is :failed_attempts:
51
+ # t.integer :failed_attempts, default: 0, null: false
52
+ # # Only if unlock strategy is :email or :both:
53
+ # t.string :unlock_token, index: { unique: true }
54
+ # t.datetime :locked_at
55
+
56
+ t.timestamps null: false
57
+ end
58
+
59
+ # The `users.id` column is actually a foreign key to the `people` table:
60
+ add_foreign_key :users, :people, column: :id
61
+ end
62
+
63
+ def create_roles_table
64
+ create_table :roles do |t|
65
+ t.string :name, null: false, comment: 'Name of the role'
66
+ t.text :description, comment: 'Description of the role'
67
+
68
+ t.timestamps null: false
69
+ end
70
+ end
71
+
72
+ def create_role_assignments_table
73
+ create_table :role_assignments do |t|
74
+ t.references :actor, foreign_key: { to_table: :people }
75
+
76
+ t.references :role,
77
+ foreign_key: { to_table: :roles },
78
+ comment: 'The role assigned to the actor'
79
+
80
+ t.references :resource, polymorphic: true
81
+ end
82
+ end
83
+ end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Person holds the "Profile" for a given User, but we can also have just Person
4
+ # profiles without a user, as is the case for "Board Members"
5
+ class Person < Authegy::Person
6
+ # Authegy::Person already includes validations for the email field, and
7
+ # associations for :user, :role_assignments, :assigned_roles, and methods
8
+ # for authorization, such as :assign_role, :has_role?, etc.
9
+ end
@@ -0,0 +1,6 @@
1
+ # frozen_string_literal: true
2
+
3
+ class RoleAssignment < Authegy::RoleAssignment
4
+ # Authegy::RoleAssignment already defines associations to :actor, :role and
5
+ # :resource
6
+ end
@@ -0,0 +1,6 @@
1
+ # frozen_string_literal: true
2
+
3
+ #= Role
4
+ class Role < Authegy::Role
5
+ # Authegy::Role already defines associations to :assignments and :actors
6
+ end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ #= User
4
+ #
5
+ # Represents a person which is able to sign-in to the application.
6
+ # Users are intended for authentification, the actual profile sits in Person.
7
+ class User < Authegy::User
8
+ # Authegy::User class already includes associations to :person,
9
+ # and delegations to :person such as :email, :has_role?, etc.
10
+
11
+ # Include devise modules. Others available are:
12
+ # :confirmable, :lockable, :timeoutable, :trackable and :omniauthable
13
+ devise :database_authenticatable_with_person_email, :registerable,
14
+ :recoverable, :rememberable, :validatable_with_person_email
15
+ end
@@ -0,0 +1,4 @@
1
+ # desc "Explaining what the task does"
2
+ # task :authegy do
3
+ # # Task goes here
4
+ # end
metadata ADDED
@@ -0,0 +1,183 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: authegy
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Roberto Quintanilla
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2019-03-02 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'
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'
27
+ - !ruby/object:Gem::Dependency
28
+ name: devise
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '4.6'
34
+ - - ">="
35
+ - !ruby/object:Gem::Version
36
+ version: 4.6.1
37
+ type: :runtime
38
+ prerelease: false
39
+ version_requirements: !ruby/object:Gem::Requirement
40
+ requirements:
41
+ - - "~>"
42
+ - !ruby/object:Gem::Version
43
+ version: '4.6'
44
+ - - ">="
45
+ - !ruby/object:Gem::Version
46
+ version: 4.6.1
47
+ - !ruby/object:Gem::Dependency
48
+ name: sqlite3
49
+ requirement: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - "~>"
52
+ - !ruby/object:Gem::Version
53
+ version: 1.3.6
54
+ type: :development
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - "~>"
59
+ - !ruby/object:Gem::Version
60
+ version: 1.3.6
61
+ - !ruby/object:Gem::Dependency
62
+ name: bundler
63
+ requirement: !ruby/object:Gem::Requirement
64
+ requirements:
65
+ - - "~>"
66
+ - !ruby/object:Gem::Version
67
+ version: '1.17'
68
+ type: :development
69
+ prerelease: false
70
+ version_requirements: !ruby/object:Gem::Requirement
71
+ requirements:
72
+ - - "~>"
73
+ - !ruby/object:Gem::Version
74
+ version: '1.17'
75
+ - !ruby/object:Gem::Dependency
76
+ name: rake
77
+ requirement: !ruby/object:Gem::Requirement
78
+ requirements:
79
+ - - "~>"
80
+ - !ruby/object:Gem::Version
81
+ version: '10.0'
82
+ type: :development
83
+ prerelease: false
84
+ version_requirements: !ruby/object:Gem::Requirement
85
+ requirements:
86
+ - - "~>"
87
+ - !ruby/object:Gem::Version
88
+ version: '10.0'
89
+ - !ruby/object:Gem::Dependency
90
+ name: rspec
91
+ requirement: !ruby/object:Gem::Requirement
92
+ requirements:
93
+ - - "~>"
94
+ - !ruby/object:Gem::Version
95
+ version: '3.0'
96
+ type: :development
97
+ prerelease: false
98
+ version_requirements: !ruby/object:Gem::Requirement
99
+ requirements:
100
+ - - "~>"
101
+ - !ruby/object:Gem::Version
102
+ version: '3.0'
103
+ - !ruby/object:Gem::Dependency
104
+ name: rspec-rails
105
+ requirement: !ruby/object:Gem::Requirement
106
+ requirements:
107
+ - - ">="
108
+ - !ruby/object:Gem::Version
109
+ version: '0'
110
+ type: :development
111
+ prerelease: false
112
+ version_requirements: !ruby/object:Gem::Requirement
113
+ requirements:
114
+ - - ">="
115
+ - !ruby/object:Gem::Version
116
+ version: '0'
117
+ description: Opinionated app strategy used for authentication & role-based authorization.
118
+ email:
119
+ - vov@icalialabs.com
120
+ executables: []
121
+ extensions: []
122
+ extra_rdoc_files: []
123
+ files:
124
+ - CHANGELOG.md
125
+ - README.md
126
+ - app/assets/config/authegy_manifest.js
127
+ - app/assets/javascripts/authegy/application.js
128
+ - app/assets/stylesheets/authegy/application.css
129
+ - app/controllers/authegy/application_controller.rb
130
+ - app/helpers/authegy/application_helper.rb
131
+ - app/jobs/authegy/application_job.rb
132
+ - app/mailers/authegy/application_mailer.rb
133
+ - app/models/authegy/application_record.rb
134
+ - app/views/layouts/authegy/application.html.erb
135
+ - lib/authegy.rb
136
+ - lib/authegy/authorizable.rb
137
+ - lib/authegy/controller_helpers.rb
138
+ - lib/authegy/engine.rb
139
+ - lib/authegy/models/person.rb
140
+ - lib/authegy/models/role.rb
141
+ - lib/authegy/models/role_assignment.rb
142
+ - lib/authegy/models/user.rb
143
+ - lib/authegy/version.rb
144
+ - lib/devise/models/database_authenticatable_with_person_email.rb
145
+ - lib/devise/models/validatable_with_person_email.rb
146
+ - lib/generators/authegy/USAGE
147
+ - lib/generators/authegy/install_generator.rb
148
+ - lib/generators/authegy/models_generator.rb
149
+ - lib/generators/authegy/orm_helpers.rb
150
+ - lib/generators/authegy/templates/models_migration.erb
151
+ - lib/generators/authegy/templates/person_model.rb
152
+ - lib/generators/authegy/templates/role_assignment_model.rb
153
+ - lib/generators/authegy/templates/role_model.rb
154
+ - lib/generators/authegy/templates/user_model.rb
155
+ - lib/tasks/authegy_tasks.rake
156
+ homepage: https://github.com/vovimayhem/authegy-gem
157
+ licenses:
158
+ - MIT
159
+ metadata:
160
+ allowed_push_host: https://rubygems.org
161
+ homepage_uri: https://github.com/vovimayhem/authegy-gem
162
+ source_code_uri: https://github.com/vovimayhem/authegy
163
+ changelog_uri: https://github.com/vovimayhem/authegy/blob/master/CHANGELOG.md
164
+ post_install_message:
165
+ rdoc_options: []
166
+ require_paths:
167
+ - lib
168
+ required_ruby_version: !ruby/object:Gem::Requirement
169
+ requirements:
170
+ - - ">="
171
+ - !ruby/object:Gem::Version
172
+ version: '0'
173
+ required_rubygems_version: !ruby/object:Gem::Requirement
174
+ requirements:
175
+ - - ">="
176
+ - !ruby/object:Gem::Version
177
+ version: '0'
178
+ requirements: []
179
+ rubygems_version: 3.0.1
180
+ signing_key:
181
+ specification_version: 4
182
+ summary: Opinionated app strategy used for authentication & role-based authorization.
183
+ test_files: []