Skip to content

Commit

Permalink
Updated readme
Browse files Browse the repository at this point in the history
  • Loading branch information
kobaltz committed Jan 14, 2024
1 parent 4625b71 commit f18c4f0
Show file tree
Hide file tree
Showing 20 changed files with 353 additions and 5 deletions.
63 changes: 59 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ they can add a Passkey to their account. The Passkey could be an iCloud Keychain
key like a Yubikey, or a mobile device. If enabled and configured, the user will be prompted to use
their Passkey after they log in.
### Configuration
#### Configuration
The migrations are already copied over to your application when you run
`bin/rails action_auth:install:migrations`. There are only two steps that you have to take to enable
Expand All @@ -160,13 +160,13 @@ The reason why you need to add the gem is because it's not added to the gemspec
intentional as not all users will want to add this functionality. This will help minimize
the number of gems that your application relies on unless if they are features that you want to use.

#### Add the gem
##### Add the gem

```
bundle add webauthn
```
### Configure the WebAuthn settings
#### Configure the WebAuthn settings
**Note:** that the origin name does not have a trailing / or a port number.
Expand All @@ -179,12 +179,67 @@ ActionAuth.configure do |config|
end
```
### Demo
#### Demo
Here's a view of the experience with WebAuthn
![action_auth](https://github.com/kobaltz/action_auth/assets/635114/fa88d83c-5af5-471b-a094-ec9785ea2f87)
### Within Your Application
It can be cumbersome to have to reference ActionAuth::User within the application as well as in the
relationships between models. Luckily, we can use ActiveSupport::CurrentAttributes to make this
process easier as well as inheritance of our models.
#### Setting up the User model
```ruby
# app/models/user.rb
class User < ActionAuth::User
has_many :posts, dependent: :destroy
end
```

#### Setting up the Current model

```ruby
# app/models/current.rb
class Current < ActiveSupport::CurrentAttributes
def user
User.find_by(id: ActionAuth::Current.user&.id)
end
end
```

#### Generating an association

There's one little gotcha when generating the associations. We are using `user:belongs_to` instead of
`action_auth_user:belongs_to`. However, when the foreign key is generated, it will look for the users table
instead of the action_auth_users table. To get around this, we'll need to modify the migration.

```bash
bin/rails g scaffold posts user:belongs_to title
```

We can update the `foreign_key` from `true` to `{ to_table: :action_auth_users }` to get around this.

```ruby
# db/migrate/XXXXXXXXXXX_create_posts.rb
class CreatePosts < ActiveRecord::Migration[7.1]
def change
create_table :posts do |t|
t.belongs_to :user, null: false, foreign_key: { to_table: :action_auth_users }
t.string :title

t.timestamps
end
end
end
```

#### Using the Current model

Now, you'll be able to do things like `Current.user` and `Current.user.posts` within your application.

## License
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
Expand Down
58 changes: 58 additions & 0 deletions test/dummy/app/controllers/posts_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
class PostsController < ApplicationController
before_action :set_post, only: %i[ show edit update destroy ]

# GET /posts
def index
@posts = Post.all
end

# GET /posts/1
def show
end

# GET /posts/new
def new
@post = Post.new
end

# GET /posts/1/edit
def edit
end

# POST /posts
def create
@post = Post.new(post_params)

if @post.save
redirect_to @post, notice: "Post was successfully created."
else
render :new, status: :unprocessable_entity
end
end

# PATCH/PUT /posts/1
def update
if @post.update(post_params)
redirect_to @post, notice: "Post was successfully updated.", status: :see_other
else
render :edit, status: :unprocessable_entity
end
end

# DELETE /posts/1
def destroy
@post.destroy!
redirect_to posts_url, notice: "Post was successfully destroyed.", status: :see_other
end

private
# Use callbacks to share common setup or constraints between actions.
def set_post
@post = Post.find(params[:id])
end

# Only allow a list of trusted parameters through.
def post_params
params.require(:post).permit(:user_id, :title)
end
end
2 changes: 2 additions & 0 deletions test/dummy/app/helpers/posts_helper.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
module PostsHelper
end
5 changes: 5 additions & 0 deletions test/dummy/app/models/current.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
class Current < ActiveSupport::CurrentAttributes
def user
User.find_by(id: ActionAuth::Current.user&.id)
end
end
3 changes: 3 additions & 0 deletions test/dummy/app/models/post.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
class Post < ApplicationRecord
belongs_to :user
end
3 changes: 3 additions & 0 deletions test/dummy/app/models/user.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
class User < ActionAuth::User
has_many :posts, dependent: :destroy
end
27 changes: 27 additions & 0 deletions test/dummy/app/views/posts/_form.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<%= form_with(model: post) do |form| %>
<% if post.errors.any? %>
<div style="color: red">
<h2><%= pluralize(post.errors.count, "error") %> prohibited this post from being saved:</h2>

<ul>
<% post.errors.each do |error| %>
<li><%= error.full_message %></li>
<% end %>
</ul>
</div>
<% end %>

<div>
<%= form.label :user_id, style: "display: block" %>
<%= form.text_field :user_id %>
</div>

<div>
<%= form.label :title, style: "display: block" %>
<%= form.text_field :title %>
</div>

<div>
<%= form.submit %>
</div>
<% end %>
12 changes: 12 additions & 0 deletions test/dummy/app/views/posts/_post.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<div id="<%= dom_id post %>">
<p>
<strong>User:</strong>
<%= post.user_id %>
</p>

<p>
<strong>Title:</strong>
<%= post.title %>
</p>

</div>
10 changes: 10 additions & 0 deletions test/dummy/app/views/posts/edit.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<h1>Editing post</h1>

<%= render "form", post: @post %>

<br>

<div>
<%= link_to "Show this post", @post %> |
<%= link_to "Back to posts", posts_path %>
</div>
14 changes: 14 additions & 0 deletions test/dummy/app/views/posts/index.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<p style="color: green"><%= notice %></p>

<h1>Posts</h1>

<div id="posts">
<% @posts.each do |post| %>
<%= render post %>
<p>
<%= link_to "Show this post", post %>
</p>
<% end %>
</div>

<%= link_to "New post", new_post_path %>
9 changes: 9 additions & 0 deletions test/dummy/app/views/posts/new.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<h1>New post</h1>

<%= render "form", post: @post %>

<br>

<div>
<%= link_to "Back to posts", posts_path %>
</div>
10 changes: 10 additions & 0 deletions test/dummy/app/views/posts/show.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<p style="color: green"><%= notice %></p>

<%= render @post %>

<div>
<%= link_to "Edit this post", edit_post_path(@post) %> |
<%= link_to "Back to posts", posts_path %>
<%= button_to "Destroy this post", @post, method: :delete %>
</div>
13 changes: 13 additions & 0 deletions test/dummy/app/views/welcome/index.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -45,3 +45,16 @@ WebAuthn Enabled: <%= ActionAuth.configuration.webauthn_enabled? %>
</tr>
</tbody>
</table>

<h2>Dummy App Settings</h2>

<h3>app/models/current.rb</h3>
<pre><%= File.read(Rails.root.join('app', 'models', 'current.rb')) %></pre>
<strong>Current.user:</strong> <%= Current.user.inspect %>

<h3>app/models/user.rb</h3>
<pre><%= File.read(Rails.root.join('app', 'models', 'user.rb')) %></pre>

<h3>Associations</h3>
<pre>bin/rails g scaffold post user:belongs_to title</pre>
<pre><%= File.read(Rails.root.join('db', 'migrate', '20240114051355_create_posts.rb')) %></pre>
1 change: 1 addition & 0 deletions test/dummy/config/routes.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
Rails.application.routes.draw do
resources :posts
mount ActionAuth::Engine => 'action_auth'
root 'welcome#index'
end
10 changes: 10 additions & 0 deletions test/dummy/db/migrate/20240114051355_create_posts.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
class CreatePosts < ActiveRecord::Migration[7.1]
def change
create_table :posts do |t|
t.belongs_to :user, null: false, foreign_key: { to_table: :action_auth_users }
t.string :title

t.timestamps
end
end
end
11 changes: 10 additions & 1 deletion test/dummy/db/schema.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
#
# It's strongly recommended that you check this file into your version control system.

ActiveRecord::Schema[7.1].define(version: 2024_01_11_142545) do
ActiveRecord::Schema[7.1].define(version: 2024_01_14_051355) do
create_table "action_auth_sessions", force: :cascade do |t|
t.integer "action_auth_user_id", null: false
t.string "user_agent"
Expand Down Expand Up @@ -42,6 +42,15 @@
t.index ["external_id"], name: "index_action_auth_webauthn_credentials_on_external_id", unique: true
end

create_table "posts", force: :cascade do |t|
t.integer "user_id", null: false
t.string "title"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.index ["user_id"], name: "index_posts_on_user_id"
end

add_foreign_key "action_auth_sessions", "action_auth_users"
add_foreign_key "action_auth_webauthn_credentials", "action_auth_users"
add_foreign_key "posts", "action_auth_users", column: "user_id"
end
48 changes: 48 additions & 0 deletions test/dummy/test/controllers/posts_controller_test.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
require "test_helper"

class PostsControllerTest < ActionDispatch::IntegrationTest
setup do
@post = posts(:one)
end

test "should get index" do
get posts_url
assert_response :success
end

test "should get new" do
get new_post_url
assert_response :success
end

test "should create post" do
assert_difference("Post.count") do
post posts_url, params: { post: { title: @post.title, user_id: @post.user_id } }
end

assert_redirected_to post_url(Post.last)
end

test "should show post" do
get post_url(@post)
assert_response :success
end

test "should get edit" do
get edit_post_url(@post)
assert_response :success
end

test "should update post" do
patch post_url(@post), params: { post: { title: @post.title, user_id: @post.user_id } }
assert_redirected_to post_url(@post)
end

test "should destroy post" do
assert_difference("Post.count", -1) do
delete post_url(@post)
end

assert_redirected_to posts_url
end
end
9 changes: 9 additions & 0 deletions test/dummy/test/fixtures/posts.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# Read about fixtures at https://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html

one:
user: one
title: MyString

two:
user: two
title: MyString
7 changes: 7 additions & 0 deletions test/dummy/test/models/post_test.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
require "test_helper"

class PostTest < ActiveSupport::TestCase
# test "the truth" do
# assert true
# end
end
Loading

0 comments on commit f18c4f0

Please sign in to comment.