Skip to content

Commit

Permalink
Start adding documentation to the README
Browse files Browse the repository at this point in the history
  • Loading branch information
JonathanFrias committed Jan 2, 2024
1 parent 298423d commit a525762
Show file tree
Hide file tree
Showing 18 changed files with 299 additions and 152 deletions.
2 changes: 1 addition & 1 deletion Gemfile.lock
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
PATH
remote: .
specs:
super_auth (0.1.2)
super_auth (0.1.3)
sequel

GEM
Expand Down
171 changes: 158 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,23 +1,168 @@
# SuperAuth

TODO: Delete this and the text below, and describe your gem
Super auth is turn-key authorization gem that makes unauthorized access unrepresentable. **Stop writing tests for authorization with confidence**

Welcome to your new gem! In this directory, you'll find the files you need to be able to package up your Ruby library into a gem. Put your Ruby code in the file `lib/super_auth`. To experiment with that code, run `bin/console` for an interactive prompt.
The intent is to use with ruby applications, as well as centralize authorization for multiple applications.

## Installation

TODO: Replace `UPDATE_WITH_YOUR_GEM_NAME_PRIOR_TO_RELEASE_TO_RUBYGEMS_ORG` with your gem name right after releasing it to RubyGems.org. Please do not do it earlier due to security reasons. Alternatively, replace this section with instructions to install your gem from git if you don't plan to release to RubyGems.org.

Install the gem and add to the application's Gemfile by executing:

$ bundle add UPDATE_WITH_YOUR_GEM_NAME_PRIOR_TO_RELEASE_TO_RUBYGEMS_ORG

If bundler is not being used to manage dependencies, install the gem by executing:
## Installation

$ gem install UPDATE_WITH_YOUR_GEM_NAME_PRIOR_TO_RELEASE_TO_RUBYGEMS_ORG
gem "super_auth"

## Usage

SuperAuth is a rules engine engine that works on 5 different authorization concepts:

- Users
- Groups
- Roles
- Permissions
- Resources

The basis for how this works is that the rules engine is trying to match a user with a resource to determine access.
It is easier to see visually:

+------+ +------------+
| User |<------?------>| Resource |
+------+ +------------+

The engine determines if it can find an authorization route betewen a user and a resource. It does so by looking at users, groups, roles, permissions.

+-------+ +------+
| Group |<----->| Role |
+-------+\ / +------+
^ \ / ^
| \/ |
| /\ |
| / \ |
V / \ V
+---------------+ +------+/ \+------------+ +----------+ +-------------------+
| YourApp::User |<-->| User |<------>| Permission |<-->| Resource | <--> | YourApp::Resource |
+---------------+ +------+ +------------+ +----------+ +-------------------+
^ ^
| |
+----------------------------------+


The lines between the boxes are called [edges](https://en.wikipedia.org/wiki/Glossary_of_graph_theory#edge).
Note that `Group` and `Role` trees.

The code to run the following example is located in `spec/readme_spec.rb`.

We're going to need some users:

Users:
- Peter
- Michael
- Bethany
- Eloise
- Anna
- Dillon
- Guest (Unknown User)

Let's see an example company structure:

Groups:
- Company
- Engineering_dept
- Backend
- Frontend
- Sales Department
- Marketing Department
- Customers
- CustomerA
- CustomerB
- Vendors
- VendorA
- VendorB

We're going to define a roles:

Roles:
- Employee
- Engineering
- Señor Software Developer
- Señor Designer
- Software Developer
- Production Support
- Sales and Marketing
- Marketing Manager
- Marketing Associate
- CustomerRole

We're going to define some permissions:

Permissions:
- create
- read
- update
- delete
- invoice
- login
- reboot
- deploy
- sign_contract
- subscribe
- unsubscribe
- publish_design

Finally, we need some resources:

Resources:
- app1
- app2
- staging
- db1
- db2
- core_design_template
- customer_profile
- marketing_website
- customer_post1
- customer_post2
- customer_post3

So we have sufficient prerequisite data to do some interesting authorizations. Let's draw some edges:

Peter <-> Frontend # Peter is on the Frontend team. (via Company->Engineering_dept->Frontend)
Engineering_dept <-> Engineering # Group "Engineering_dept" has the Role "Engineering"
Engineering <-> create # Engineering role can do basic CRUD operations
Engineering <-> read # Peter can CRUD too
Engineering <-> update
Engineering <-> delete
core_design_template <-> create # Now, those CRUD permissions apply to core_design_template resource
core_design_template <-> read
core_design_template <-> update
core_design_template <-> delete

With this, the following paths are created from Peter to the core_design_template:

Peter <-> Frontend <-> Engineering_dept <-> Engineering <-> create <-> core_design_template
Peter <-> Frontend <-> Engineering_dept <-> Engineering <-> read <-> core_design_template
Peter <-> Frontend <-> Engineering_dept <-> Engineering <-> update <-> core_design_template
Peter <-> Frontend <-> Engineering_dept <-> Engineering <-> delete <-> core_design_template

Which completes the circuit using the path
user <-> group <-> group <-> role <-> permission <-> resource

In general the super_auth has 5 different pathing strategies to search for access.

1. users <-> group[s] <-> role[s] <-> permission <-> resource
2. users <-> role[s] <-> permission <-> resource
3. users <-> group[s] <-> permission <-> resource
4. users <-> permission <-> resource
5. users <-> resource

When `Group` and `Role` are used, the rules will apply to all descedants. Since Edges can be drawn
between any 2 objects, super_auth can seamlessly scale in complexity with you. For example this is valid:

Peter <-> core_design_template

With this, you can completely bypass `Group`s and `Role`s and `Permission`s if they are not needed.
So access is always allowed to a resource

When you create/delete an edge new authorizations are generated and stored in the `super_auth` database table.
Since the path is stored with the record, it trivial to audit access permissions using basic SQL.

TODO: Write usage instructions here

## Development
Expand All @@ -28,8 +173,8 @@ To install this gem onto your local machine, run `bundle exec rake install`. To

## Contributing

Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/super_auth.
Bug reports and pull requests are welcome on GitHub at https://github.com/JonathanFrias/super_auth.

## License

The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
The gem is available as open source under the terms of the [GPL](https://www.gnu.org/licenses/quick-guide-gplv3.html).
2 changes: 1 addition & 1 deletion db/migrate/1_users.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
Sequel.migration do
change do
create_table(:users) do
create_table(:super_auth_users) do
primary_key :id

String :external_id # , null: false
Expand Down
4 changes: 2 additions & 2 deletions db/migrate/2_groups.rb
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
Sequel.migration do
change do
create_table(:groups) do
create_table(:super_auth_groups) do
primary_key :id
String :name, null: false
foreign_key :parent_id, :groups, deferrable: true, type: :integer
foreign_key :parent_id, :super_auth_groups, deferrable: true, type: :integer
DateTime :created_at, null: false, default: Sequel::CURRENT_TIMESTAMP
DateTime :updated_at, null: false, default: Sequel::CURRENT_TIMESTAMP
end
Expand Down
2 changes: 1 addition & 1 deletion db/migrate/3_permissions.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
Sequel.migration do
change do
create_table(:permissions) do
create_table(:super_auth_permissions) do
primary_key :id
String :name, null: false
DateTime :created_at, null: false, default: Sequel::CURRENT_TIMESTAMP
Expand Down
4 changes: 2 additions & 2 deletions db/migrate/4_roles.rb
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
Sequel.migration do
change do
create_table(:roles) do
create_table(:super_auth_roles) do
primary_key :id
String :name, null: false
foreign_key :parent_id, :roles, deferrable: true, type: :integer
foreign_key :parent_id, :super_auth_roles, deferrable: true, type: :integer
DateTime :created_at, null: false, default: Sequel::CURRENT_TIMESTAMP
DateTime :updated_at, null: false, default: Sequel::CURRENT_TIMESTAMP
end
Expand Down
2 changes: 1 addition & 1 deletion db/migrate/5_resources.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
Sequel.migration do
change do
create_table(:resources) do
create_table(:super_auth_resources) do
primary_key :id

String :name
Expand Down
12 changes: 6 additions & 6 deletions db/migrate/6_edge.rb
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
Sequel.migration do
change do
create_table(:edges) do
create_table(:super_auth_edges) do
primary_key :id

foreign_key :user_id, :users, null: true
foreign_key :group_id, :groups, null: true
foreign_key :permission_id, :permissions, null: true
foreign_key :role_id, :roles, null: true
foreign_key :resource_id, :resources, null: true
foreign_key :user_id, :super_auth_users, null: true
foreign_key :group_id, :super_auth_groups, null: true
foreign_key :permission_id, :super_auth_permissions, null: true
foreign_key :role_id, :super_auth_roles, null: true
foreign_key :resource_id, :super_auth_resources, null: true

DateTime :created_at, null: false, default: Sequel::CURRENT_TIMESTAMP
DateTime :updated_at, null: false, default: Sequel::CURRENT_TIMESTAMP
Expand Down
Loading

0 comments on commit a525762

Please sign in to comment.