Coder Social home page Coder Social logo

lazaronixon / authentication-zero Goto Github PK

View Code? Open in Web Editor NEW
1.4K 17.0 43.0 526 KB

An authentication system generator for Rails applications.

License: MIT License

Ruby 98.10% JavaScript 1.90%
rails ruby authentication generator rails-authentication api auth security token

authentication-zero's Introduction

Hi there πŸ‘‹

authentication-zero's People

Contributors

domchristie avatar geetfun avatar gobijan avatar jbigler avatar karenling avatar kylekeesling avatar lazaronixon avatar mjankowski avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

authentication-zero's Issues

abstract `ApplicationController` logic into a concern

I'm curious what your thoughts on abstracting the logic that is currently housed directly into the ApplicationController into an Authentication concern?

This would make it easier for folks to incorporate the gem into existing projects and could even potentially allow for the DRYing up of logic between the HTML and API variants.

Skips routes, views, tests and mailers.

Hey mate,

nice project. Right now it skips the generation of the routes for the auth system when following the instructions from the readme.

Cheers Bijan

I'm using Rails 7.0.2.2 with Ruby 3.1.1.

Fresh, no-options install, can't register new user.

Hi, I followed the instructions on the Github page to add the latest gem to my project and then ran 'rails g authentification', then migrated the database. So just a generic install without options, under Rails 7.0.3.

Tried to add myself as a new user but the registrations controller keeps rejecting the signup, with the logs reporting unpermitted parameters for :authenticity_token and :commit.

Looked at my Users model but don't see anything that jumps out. If I add those missing params to the Registrations controllers' permitted params, then the next error is "Unknown Attribute Error" for :authenticity_token on the User model.

Any idea how to fix? Thanks!

Screen Shot 2023-02-17 at 3 23 26 PM

Screen Shot 2023-02-17 at 3 27 55 PM

Screen Shot 2023-02-17 at 3 44 36 PM

Allow custom model name

It would be very useful to allow choosing a model name other than User. Especially when needing to create multiple types of user-like models like User, Customer and Admin.

Should password resource be in identity namespace?

Each of email, email_verification and password_reset is a singular resource in the identity namespace; however, the password resource is in the root namespace, despite following the pattern for the identity controllers (i.e. the presence of Current.user).

Would it be more consistent for password changes to sit in the identity namespace, too?

User has many identities

Hi,
Is it possible to consider the option that a user has more accounts associated? For example, that can log in with his Facebook, Google or Apple account. There would have to be an extra table that has provider, uid, and user_id.
What do you think? Thanks!

Discussion: Post installation message

In another issue (#50), it was mentioned that because this gem could be removed that improvements to the codebase (eg. security updates) might be missed.

@gregmolnar made a fairly reasonable suggestion to add a post installation message to address this, presumably such that users who have used the gem should also keep the gem as part of the host application's Gemfile so that future post installation messages can be relayed to them.

@lazaronixon If this is something that you think might be helpful as well, I'd be happy to submit a PR for this. Thank you!

rails g authentication user --ratelimit

Implement ratelimit, I did it before....

  environment nil, env: "production" do <<~CODE
    config.middleware.use(
      Rack::Ratelimit, name: "General",
      rate:   [1000, 1.hour],
      logger: Rails.logger,
      redis:  Redis.new
    ) { |env| ActionDispatch::Request.new(env).ip }
  CODE

Inviting users

Hi,

any chance you would consider adding support for inviting new users? To keep it lean and simple i think a good implementation would be to handle things like invitation tokens, expiry and the state on an invitation (pending, accepted, expired) and return an invitation link.

This would keep the gem relatively simple and leave it up to the user how to distribute the invitation link (via mail, manually, etc)

Remove support to cancel account

It doesn't fit the authentication purpose, the user should create regular scaffolds in order to edit profile or cancel account...
users_controller, /users/id [patch] and /users/id [delete]

Separate set_current_session from authenticate?

My main navigation bar shows either a login/sign up button or a logout/edit profile button. To get that to work, the Current.session has to be set before. But if authenticate is being called and the user is not logged in, it redirects to the login page - based on the current (v2.10.0).

But in that scenario you obviously don't have to be logged in to view the start page. A redirect to login is not useful in that situation.

Possible Solution

Wouldn't it be useful to have a separate set_current_session method in the ApplicationController and extract setting the session from the authenticate method?

before_action :set_current_session
before_action :authenticate
...

def authenticate
  redirect_to sign_in_path unless Current.session.present?
end

def set_current_session
  if session = Session.find_by_id(cookies.signed[:session_token])
    Current.session = session
  end
end

With that you can continue to call skip_before_action :authenticate within all controllers that don't require an authenticated user, but the session (if available) is correctly set.

Disclaimer

I'm fairly new to Ruby and Rails. So please excuse if I miss something here. 🀐

Allow configurable model names

Currently all authentication action is allocated to a User model.

It may be helpful to allow this to be configurable to support alternative scenarios such as:

  • Domains where users have alternative names (e.g. employees)
  • Environments with multiple distinct user authentications (e.g users vs admin)

Generate authentication with api and cookie at the same time

Hi,

My Rails app has an api and html views. I make the difference using the json formats. Will it be possible to mix both authentication strategies somehow in the same controller? If the format is json return json, otherwise html, and always return the token, or otherwise return it only if the format is json. The other option would be to have a separate controller for api and html, but this doesn't sound so nice.

What do you think? Thanks!

'kredis' gem not added after generation

After running the generation with the flags --pwned --sudoable --omniauthable --two-factor

I ran into the error of missing method kredis_flag for the session model. I had to then add the kredis gem manually.
Running with rails 7.0.4.

Shouldn't this gem be added to the gemfile with code generation?

Changelog

Create 2 repos, api and html, after each version update these repos with the changes and tag them… so the user will be able to see the diffs between versions

store location and redirect after sign in

It would be nice to store a user's destination and redirect them back to it in the event that the need to login prior to visiting the page. Similarly to how users are redirected after sudo is required.

Lockable doesn't seem to work

I was testing this gem, and when I generate a sample app with the --lockable flag, it looks like the before_action to call require_lock is only added to the password reset, but it should also be added to at least to the sessions controller too I believe.
Otherwise, it gives a false sense of being safe from password brute-force attacks.

Simple password generates 'password invalid'

Fresh after installation I tried adding a user with the password "111111111111". Not the most secure password, but ought to work. Doesn't work, gives "password invalid" message. Took a while to figure out that the password validation contains a regex that looks like it might be limiting characters to upper and lower case letters and digits:

validates :password, allow_nil: true, length: { minimum: 6 }, format: { with: /(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])/ }

If that's the case it can be done with a much simpler regex, this one doesn't work! More to the point, why is this here at all? Isn't the restriction of characters in a password a feature that only some will want? Leave it behind a '#' if you want to let it be a reminder that such a thing can be done.

Identify device

For now, each new sign in sends a new email, don't send email from the same device. hey.com seems to set a cookie called device_token, and check if this device exists

Use the default Rails encrypted session cookie store?

Hi,
First off, love your excellent approach and gem!

While inspecting the generated code on how the session cookie is set I can see that you are using cookies.signed.permanent . I was wondering, wouldn't it be better to leverage the default Rails session cookie; leveraging expiration, signing etc. Could be as simple as replacing

cookies.signed.permanent[:session_token] = { value: session.id, httponly: true }

with

session[:session_token] = session.id

Or is there a some reason why you decided to roll your own cookie?

API vs API-only?

I had assumed that the --api flag was going to mean something like "in addition to the base generated auth code, also generate an API:: module and an API::BaseController and then put the relevant controllers/routes/etc in place so that JSON requests to /api/*... might be useful", or something along those lines.

What it seems like it actually do is more like "Generate an API-only app INSTEAD OF a regular html app" (at controller level), I think?

Thoughts on all/any of...

  • Rename the option to --api-only for a little clarity?
  • Add functionality to do what I thought it would -- generating a namespace-isolated API controller with relevant auth code (either a new config option, or a rename/modify of the existing)
  • Update docs a bit to make clear what the various options enable/disable

Improve README

I'm a really bad writer, I would like to have a fancy README, maybe with a video, logo, etc... but keep it simple and direct.

Form validation on incorrect signup doesn't work.

Hey, it's me again ;)
The create action in registrations controller is not using an instance variable but in error case you invoke a render that then checks @user.errors.any? in the view. So an exception is thrown (see screenshot).

It's a simple fix and pull request is on the way :)
Cheers Bijan

Screenshot 2022-02-27 at 21 13 43

PS: We should maybe create a test suite for this gem that does the generate a new application and runs default tests on it so we can see when some generator changes lead to a break of the gem. What do you think?

When ran in existing codebase generator does not interact with existing files as expected. Overwrites some, skips others.

I ran the generator in an app I had already been working on and saw that several files were overwritten, and one generated file omitted.

Files n classes overwritten, losing my existing app behavior:

  • app/controllers/application_controller.rb
  • test/test_helper.rb
  • test/system/application_system_test_case.rb

Files skipped that other auth zero behavior depended on:

  • app/models/current.rb
  • app/controllers/home_controller.rb (and related views)

Files modified in place, the behavior I would expect:

  • config/routes.rb

Setup test infrastructure.

In order to create a solid solution usable by many apps it would make sense to put regression testing in place.
Generators themselves are not easy to test but the workaround would be to create a build pipeline that runs a script that creates a new blank rails app, adds the gem, adds the controller, modifies the routes and adds the mail settings etc.
When the new barebone app is finished and authentication-zero is setup it runs a test suite on the generated app.
Not sure how to put the test suite in place (cloning from repo?, generating?).

What do you think @lazaronixon?

Passwordless Email Auth

It would be nice if I could have the option to create a email magic link authentication method. πŸ‘€

Flakiness in generated system tests

It appears that the system tests can become flakey where the test visits a url, and straight after fills in a form field.

This can, under certain circumstances, cause a timing issue where the field does not get filled in. I noticed that the page was still stuck on the page with a tip expecting the field to be filled in. I solved this for my usage by simply asserting something specific to the page that is to be loaded.

The flakiness was also very noticeable with one of the system tests failing every 3rd/4th run.

For example:

    test "sending a password reset email" do
      visit sign_in_url
      click_on "Forgot your password?"

      assert_css "h1", text: "Forgot your password?" # I added this to ensure the test is on the right page

      fill_in "Email", with: @user.email
      click_on "Send password reset email"

      assert_text "Check your email for reset instructions"
    end

Example random failure with screenshot:

Failure:
Identity::PasswordResetsTest#test_sending_a_password_reset_email [***omitted***/test/system/identity/password_resets_test.rb:19]:
expected to find text "Check your email for reset instructions" in "Forgot your password?\nEmail"

failures_test_sending_a_password_reset_email

Association for user has_many sessions can't infer the sessions model

After code generation, running version 2.1.16, rails complains about the has_many :sessions relationship with:

Rails couldn't find a valid model for session association. 
Please provide the :class_name option on the association declaration. 
If :class_name is already provided, make sure it's an ActiveRecord::Base subclass. (NameError)

Making the change in user.rb solved it for me.

--- a/app/models/user.rb
+++ b/app/models/user.rb
@@ -6,7 +6,7 @@ class User < ApplicationRecord
   has_many :email_verification_tokens, dependent: :destroy
   has_many :password_reset_tokens, dependent: :destroy

-  has_many :sessions, dependent: :destroy
+  has_many :sessions, dependent: :destroy, class_name: "Session"

The question is, why is this needed? Whats changed?
Running on Rails 7.0.4

current.rb is not modified if already present.

I ran the generator after I had already created, and added behavior to, file app/models/current.rb and auth-zero content was not added. I think it ought to have added the new behavior to the existing file if it were present.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    πŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. πŸ“ŠπŸ“ˆπŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❀️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.