{"id":13463338,"url":"https://github.com/halogenandtoast/oath","last_synced_at":"2025-03-25T06:31:50.838Z","repository":{"id":6834108,"uuid":"8082482","full_name":"halogenandtoast/oath","owner":"halogenandtoast","description":"Oath is rails authentication made simple. Previously known as Monban","archived":true,"fork":false,"pushed_at":"2020-03-08T08:22:08.000Z","size":241,"stargazers_count":372,"open_issues_count":4,"forks_count":21,"subscribers_count":10,"default_branch":"master","last_synced_at":"2024-10-29T13:50:53.098Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Ruby","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/halogenandtoast.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2013-02-07T21:52:34.000Z","updated_at":"2023-12-18T08:45:51.000Z","dependencies_parsed_at":"2022-09-15T14:40:19.690Z","dependency_job_id":null,"html_url":"https://github.com/halogenandtoast/oath","commit_stats":null,"previous_names":["halogenandtoast/monban"],"tags_count":24,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/halogenandtoast%2Foath","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/halogenandtoast%2Foath/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/halogenandtoast%2Foath/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/halogenandtoast%2Foath/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/halogenandtoast","download_url":"https://codeload.github.com/halogenandtoast/oath/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":245414186,"owners_count":20611357,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-07-31T13:00:51.359Z","updated_at":"2025-03-25T06:31:50.353Z","avatar_url":"https://github.com/halogenandtoast.png","language":"Ruby","funding_links":[],"categories":["Security","Authentication and OAuth"],"sub_categories":["Rails Authentication"],"readme":"# NOTICE\n\nMonban is currently in the process of being renamed Oath: https://github.com/halogenandtoast/oath\n\n\n# Oath\n\n[![Build Status](https://travis-ci.org/halogenandtoast/oath.png?branch=master)](https://travis-ci.org/halogenandtoast/oath)\n[![Code Climate](https://codeclimate.com/github/halogenandtoast/oath.png)](https://codeclimate.com/github/halogenandtoast/oath)\n\nOath is designed to be a very simple and extensible user authentication\nlibrary for rails. Its goal is to give all the power to the developer instead\nof forcing them to make Oath work with their system.\n\n## Why use Oath?\n\nOath makes authentication simple:\n\n- Easy to use in tests with dependency injection\n- Provides convenient controller helpers\n- Very customizable\n\nOath doesn't do the following:\n\n- Doesn't automatically add routes to your application\n- Doesn't force you to use engine based controllers or views\n- Doesn't require you to make changes to your user model\n\n## Documentation\n\nYou can read the full documentation at [rubydoc](http://rubydoc.info/github/halogenandtoast/oath)\n\n## Installation\n\nOath was designed to work with Rails \u003e 4.0. Add this line to your Gemfile:\n\n    gem 'oath'\n\nThen inside of your ApplicationController add the following:\n\n    include Oath::ControllerHelpers\n\nAnd you're ready to start designing your authentication system.\n\n## Generators\n\nIf you'd like a good starting point for building an app using Oath, it is suggested to use the [oath generators]\n\n## Usage\n\nOath does currently have some out-of-the-box expectations, but you can\nconfigure and change any of these:\n\n- By default the model should be called `User`\n- Oath expects your user model to respond to `create`, `id`, and `find_by`\n- You should have an `email` and `password_digest` column on your `User`\n- Passwords will be handled with BCrypt\n\n### Suggestions\n\n#### Console Usage\n\nIf you're trying to sign up a User in a console you won't be able to call User#new or User#create because the User model does not know how to encrypt passwords.\nYou should instead use the sign up service in order to create the user:\n\n```ruby\nOath.config.sign_up_service.new(email: \"foo@example.com\", password: \"password\").perform\n```\n\n#### Validations\n\nOath doesn't add validations to your user model unless you're using [oath generators] so it's suggested to add the following validations:\n\n```ruby\nvalidates :email, presence: true, uniqueness: true\nvalidates :password_digest, presence: true\n```\n\nIn addition to that you'll want to add the following to your `config/locale/en.yml`:\n\n```yaml\nen:\n  activerecord:\n    attributes:\n      user:\n        password_digest: \"Password\"\n```\n\nWhich will generate the error message `Password can't be blank` instead of `Password digest can't be blank`.\n\n#### Layout changes\n\nIt is suggested you add something like this to your application layout:\n\n```erb\n\u003c% if signed_in? %\u003e\n  \u003c%= link_to \"Sign out\", session_path, method: :delete %\u003e\n\u003c% else %\u003e\n  \u003c%= link_to \"Sign in\", new_session_path %\u003e\n  \u003c%= link_to \"Sign up\", new_user_path %\u003e\n\u003c% end %\u003e\n```\n\n#### Guest user\n\nIf you want to introduce a Guest object when a user is not signed in, you can override Oath's `current_user` method in your `ApplicationController`:\n\n```ruby\ndef current_user\n  super || Guest.new\nend\n```\n\nIn `app/models/`, define a `Guest` class:\n\n```ruby\nclass Guest\n  def name\n    \"Guest\"\n  end\nend\n```\n\nThis article on the [Null Object Pattern](http://robots.thoughtbot.com/handling-associations-on-null-objects) provides a good explanation of why you might want to do this.\n\n#### Using I18n for sign in notice\n\nIf you want to use I18n for the notice instructing users to sign in when they try to access an unauthorized page you can do so with the following configuration:\n\n```ruby\nOath.configure do |config|\n  config.sign_in_notice = -\u003e { I18n.t(\"sign_in_notice\") }\nend\n```\n\nIt is suggested to store this file at `config/initializers/oath.rb`\n\n### Controller Additions\n\nOath provides the following controller methods:\n\n- `sign_in(user)`\n- `sign_out`\n- `sign_up(user_params)`\n- `authenticate(user, password)`\n- `authenticate_session(session_params)`\n- `reset_password(user, password)`\n\nThese helpers:\n\n- `current_user`\n- `signed_in?`\n\nAnd this filter:\n\n- `require_login`\n\n### Routing Constraints\n\nTo authorize users in `config/routes.rb`:\n\n```ruby\nrequire \"oath/constraints/signed_in\"\nrequire \"oath/constraints/signed_out\"\n\nBlog::Application.routes.draw do\n  constraints Oath::Constraints::SignedIn.new do\n    root \"dashboards#show\", as: :dashboard\n  end\n\n  constraints Oath::Constraints::SignedOut.new do\n    root \"landings#show\"\n  end\nend\n```\n\n## Usage in Tests\n\n### Test mode\n\nOath provides the following:\n\n```ruby\nOath.test_mode!\n```\n\nWhich will change password hashing method to provide plaintext responses instead of using BCrypt. This will allow you to write factories using the password_digest field:\n\n```ruby\nFactoryBot.define do\n  factory :user do\n    sequence(:email) { |n| \"user#{n}@example.com\" }\n    password_digest 'password'\n  end\nend\n```\n\n### Spec helpers\n\nA couple of convenience methods are available in your tests. In order to set this up you'll want to add the following to `rails_helper.rb` or if that doesn't exist `spec_helper.rb`\n\n```ruby\nOath.test_mode!\n\nRSpec.configure do |config|\n  config.include Oath::Test::Helpers, type: :feature\n  config.after :each do\n    Oath.test_reset!\n  end\nend\n```\n\nThen you can use any of the [test helpers] in your scenarios\n\n```ruby\nfeature \"A feature spec\" do\n  scenario \"that requires login\" do\n    user = create(:user)\n    sign_in(user)\n    # do something\n    sign_out\n    # do something else\n  end\nend\n```\n\n### Oath Backdoor\n\nSimilar to clearance's backdoor you can visit a path and sign in quickly via\n\n```ruby\nuser = create(:user)\nvisit dashboard_path(as: user)\n```\n\nTo enable this functionality you'll want to add the following to `config/environments/test.rb`:\n\n```ruby\nconfig.middleware.insert_after Warden::Manager, Oath::BackDoor\n```\n\nIf you'd like to find your User model by a field other than `id`, insert the\nmiddleware with a block that accepts the `as` query parameter and returns an\ninstance of your User model:\n\n```ruby\nconfig.middleware.insert_after Warden::Manager, Oath::BackDoor do |user_param|\n  User.find_by(username: user_param)\nend\n```\n\n### Controller Specs\n\nIf you are going to write controller tests, helpers are provided for those as well:\n\n```ruby\nOath.test_mode!\n\nRSpec.configure do |config|\n  config.include Oath::Test::ControllerHelpers, type: :controller\n  config.after :each do\n    Oath.test_reset!\n  end\nend\n```\n\n```ruby\nrequire 'spec_helper'\n\ndescribe ProtectedController do\n\n  describe \"GET 'index'\" do\n    it \"returns http success when signed in\" do\n      user = create(:user)\n      sign_in(user)\n      get 'index'\n      response.should be_success\n    end\n\n    it \"redirects when not signed in\" do\n      get 'index'\n      response.should be_redirect\n    end\n  end\nend\n```\n\n## Advanced Functionality\n\n### Authentication with username instead of email\n\nIf you want to sign in with username instead of email just change the configuration option\n\n```ruby\n# config/initializers/oath.rb\nOath.configure do |config|\n  config.user_lookup_field = :username\nend\n```\n\nIf you used the oath:scaffold generator from [oath generators] you'll have to change the following four references to email.\n\n* In SessionsController#session_params\n* In UsersController#user_params\n* The email form field on sessions#new\n* The email form field on users#new\n\n### Using multiple lookup fields\n\nYou may perform a look up on a user using multiple fields by doing something like the following:\n\n```ruby\nclass SessionsController \u003c ApplicationController\n  def create\n    user = authenticate_session(session_params, email_or_username: [:email, :username])\n\n    if sign_in(user)\n      redirect_to(root_path)\n    else\n      render :new\n    end\n  end\n\n  private\n\n  def session_params\n    params.require(:session).permit(:email_or_username, :password)\n  end\n\nend\n```\n\nThis will allow the user to enter either their username or email to login\n\n## Configuration\n\nOath::Configuration has lots of options for changing how oath works. Currently the options you can change are as follows:\n\n### User values\n\n* **user_lookup_field**: (default `:email`) Field in the database to lookup a user by.\n* **user_token_field**: (default `:password`) Field the form submits containing the undigested password.\n* **user_token_store_field**: (default: `:password_digest`) Field in the database that stores the user's digested password.\n* **user_class**: (default: `'User'`) The user class.\n\n### Services\n\n* **sign_in_notice**: (default: `You must be signed in`) Rails flash message to set when user signs in.\n* **sign_in_service**: (default: `Oath::Services::SignIn`) Service for signing a user in.\n* **sign_up_service**: (default: `Oath::Services::SignUp`) Service for signing a user up.\n* **sign_out_service**: (default: `Oath::Services::SignOut`) Service for signing a user out.\n* **authentication_service**: (default: `Oath::Services::Authentication`) Service for authenticated a user.\n* **password_reset_service**: (default: `Oath::Services::PasswordReset`) Service for resetting a user's password.\n\n### Rails values\n\n* **no_login_handler**: A before_action for rails that handles when a user is not signed in.\n* **no_login_redirect**: Used by the no_login_handler to redirect the user\n\n### Methods\n\n* **hashing_method**: Method to hash an undigested password.\n* **token_comparison**: Method to compare a digested and undigested password.\n* **creation_method**: Method for creating a user.\n* **find_method**: Method for finding a user.\n\n### Warden Settings\n\n* **failure_app**: Necessary for warden to work. A rack app that handles failures in authentication.\n\n## Limitations\n\nHere are a few of the current limitations of oath:\n\n- Oath assumes you only have one user model.\n\n## Contributing\n\n1. [Fork it](https://github.com/halogenandtoast/oath/fork)\n2. Create your feature branch (`git checkout -b my-new-feature`)\n3. Commit your changes (`git commit -am 'Add some feature'`)\n4. Push to the branch (`git push origin my-new-feature`)\n5. Create new Pull Request\n\n[oath generators]: https://github.com/halogenandtoast/oath-generators\n[test helpers]: https://github.com/halogenandtoast/oath/blob/master/lib/oath/test/helpers.rb\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhalogenandtoast%2Foath","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fhalogenandtoast%2Foath","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhalogenandtoast%2Foath/lists"}