Skip to content

Commit

Permalink
Merge pull request #10 from amrhossamdev/advanced-login
Browse files Browse the repository at this point in the history
Admin now can control users
  • Loading branch information
amrhossamdev authored Sep 18, 2024
2 parents b18ee63 + f9c464a commit 77e4c4f
Show file tree
Hide file tree
Showing 13 changed files with 155 additions and 31 deletions.
7 changes: 5 additions & 2 deletions .idea/simple_app.iml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

11 changes: 6 additions & 5 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,12 @@ gem "turbo-rails"
gem "stimulus-rails"
# Build JSON APIs with ease [https://github.com/rails/jbuilder]
gem "jbuilder"
gem 'ostruct'
gem 'bcrypt', '~> 3.1.7'
gem 'pg'

gem "ostruct"
gem "bcrypt", "~> 3.1.7"
gem "pg"
gem "faker"
gem "will_paginate", "3.3.1"
gem "bootstrap-will_paginate", "1.0.0"
gem "sassc-rails"
gem "rails-controller-testing"
gem "bootstrap-sass", "~> 3.4.1"
Expand Down Expand Up @@ -63,7 +65,6 @@ group :test do
gem "guard-minitest"
end


group :development do
# Use console on exceptions pages [https://github.com/rails/web-console]
gem "web-console"
Expand Down
12 changes: 10 additions & 2 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,8 @@ GEM
bootstrap-sass (3.4.1)
autoprefixer-rails (>= 5.2.1)
sassc (>= 2.0.0)
bootstrap-will_paginate (1.0.0)
will_paginate
brakeman (6.2.1)
racc
builder (3.3.0)
Expand All @@ -109,6 +111,8 @@ GEM
drb (2.2.1)
erubi (1.13.0)
execjs (2.9.1)
faker (3.4.2)
i18n (>= 1.8.11, < 2)
ffi (1.17.0-aarch64-linux-gnu)
ffi (1.17.0-aarch64-linux-musl)
ffi (1.17.0-arm-linux-gnu)
Expand All @@ -135,7 +139,7 @@ GEM
guard-minitest (2.4.6)
guard-compat (~> 1.2)
minitest (>= 3.0)
i18n (1.14.5)
i18n (1.14.6)
concurrent-ruby (~> 1.0)
importmap-rails (2.0.1)
actionpack (>= 6.0.0)
Expand Down Expand Up @@ -282,7 +286,7 @@ GEM
rubocop-minitest (0.36.0)
rubocop (>= 1.61, < 2.0)
rubocop-ast (>= 1.31.1, < 2.0)
rubocop-performance (1.21.1)
rubocop-performance (1.22.1)
rubocop (>= 1.48.1, < 2.0)
rubocop-ast (>= 1.31.1, < 2.0)
rubocop-rails (2.26.1)
Expand Down Expand Up @@ -356,6 +360,7 @@ GEM
websocket-driver (0.7.6)
websocket-extensions (>= 0.1.0)
websocket-extensions (0.1.5)
will_paginate (3.3.1)
xpath (3.2.0)
nokogiri (~> 1.8)
zeitwerk (2.6.18)
Expand All @@ -379,9 +384,11 @@ DEPENDENCIES
bcrypt (~> 3.1.7)
bootsnap
bootstrap-sass (~> 3.4.1)
bootstrap-will_paginate (= 1.0.0)
brakeman
capybara
debug
faker
guard
guard-minitest
importmap-rails
Expand All @@ -403,6 +410,7 @@ DEPENDENCIES
tzinfo-data
web-console
webdrivers
will_paginate (= 3.3.1)

BUNDLED WITH
2.5.18
1 change: 1 addition & 0 deletions app/assets/stylesheets/application.css
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
@import "bootstrap";
/*
* This is a manifest file that'll be compiled into application.css, which will include all the files
* listed below.
Expand Down
24 changes: 20 additions & 4 deletions app/controllers/users_controller.rb
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
class UsersController < ApplicationController
before_action :logged_in_user, only: [:index, :edit, :update]
before_action :correct_user, only: [:edit, :update]

before_action :logged_in_user, only: [:index, :edit, :update, :destroy]
before_action :correct_user, only: [:edit, :update]
before_action :admin_user, only: :destroy

def show
@user = User.find(params[:id])
Expand All @@ -23,11 +23,21 @@ def create
end
end

def destroy
user = User.find(params[:id])
if user.destroy
flash[:success] = "User deleted"
else
flash[:danger] = "User could not be deleted"
end
redirect_to users_url, status: :see_other
end

def edit
end

def index
@users = User.all
@users = User.paginate(page: params[:page], per_page: 10)
end

def update
Expand Down Expand Up @@ -62,4 +72,10 @@ def user_params
params.require(:user).permit(:name, :email, :password, :password_confirmation)
end

def admin_user
unless current_user.admin?
flash[:danger] = "Access Denied."
redirect_to root_url
end
end
end
12 changes: 12 additions & 0 deletions app/views/users/_user.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<ul class="users">
<% @users.each do |user| %>
<li>
<%= link_to gravatar_for( user, size: 50), user %>
<%= link_to user.name, user %>
<% if current_user.admin? && !current_user?(user) %>
| <%= link_to "delete", user, data: { "turbo-method": :delete,
turbo_confirm: "You sure?" } %>
<% end %>
</li>
<% end %>
</ul>
12 changes: 4 additions & 8 deletions app/views/users/index.html.erb
Original file line number Diff line number Diff line change
@@ -1,11 +1,7 @@
<% provide(:title, 'All users') %>
<h1>All users</h1>
<%= will_paginate %>
<ul class="users">
<% @users.each do |user| %>
<li>
<%= gravatar_for user, size: 50 %>
<%= link_to user.name, user %>
</li>
<% end %>
</ul>
<%= render "users/user" %>
<%= will_paginate %>
5 changes: 5 additions & 0 deletions db/migrate/20240918050726_add_admin_to_users.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
class AddAdminToUsers < ActiveRecord::Migration[7.2]
def change
add_column :users, :admin, :boolean, default: false
end
end
3 changes: 2 additions & 1 deletion db/schema.rb

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

19 changes: 10 additions & 9 deletions db/seeds.rb
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
# This file should ensure the existence of records required to run the application in every environment (production,
# development, test). The code here should be idempotent so that it can be executed at any point in every environment.
# The data can then be loaded with the bin/rails db:seed command (or created alongside the database with db:setup).
#
# Example:
#
# ["Action", "Comedy", "Drama", "Horror"].each do |genre_name|
# MovieGenre.find_or_create_by!(name: genre_name)
# end
99.times do |n|
name = Faker::Name.name
email = "example-#{n + 1}@railstutorial.org"

User.create(name: name,
email: email,
password: "123456",
password_confirmation: "123456",
admin: true)
end
26 changes: 26 additions & 0 deletions test/controllers/users_controller_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -42,4 +42,30 @@ def setup
get users_path
assert_redirected_to login_url
end

test "should not allow the admin attribute to be edited via the web" do
log_in_as(@other_user)
assert_not @other_user.admin?
patch user_path(@other_user), params: {
user: { password: "password",
password_confirmation: "password",
admin: true } }
assert_not @other_user.admin?
end

test "should redirect destroy when not logged in" do
assert_no_difference "User.count" do
delete user_path(@user)
end
assert_response :see_other
assert_redirected_to login_url
end
test "should redirect destroy when logged in as a non-admin" do
log_in_as(@other_user)
assert_no_difference "User.count" do
delete user_path(@user)
end
assert_redirected_to root_url
end

end
18 changes: 18 additions & 0 deletions test/fixtures/users.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,27 @@
amr:
name: Amr Hossam
email: amr@gmail.com
admin: true
password_digest: <%= User.digest("password") %>

amr2:
name: Amr2
email: foo@gmail.com
password_digest: <%= User.digest("password") %>

lana:
name: Lana Kane
email: hands@example.gov
password_digest: <%= User.digest('password') %>

malory:
name: Malory Archer
email: boss@example.gov
password_digest: <%= User.digest('password') %>

<% 30.times do |n| %>
user_<%= n %>:
name: <%= "User #{n}" %>
email: <%= "user-#{n}@example.com" %>
password_digest: <%= User.digest('password') %>
<% end %>
36 changes: 36 additions & 0 deletions test/integration/users_index_test.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
require "test_helper"

class UsersIndexTest < ActionDispatch::IntegrationTest

def setup
@admin = users(:amr)
@non_admin = users(:amr2)
end

# TODO check that

# test "index as admin including pagination and delete links" do
# log_in_as(@admin)
# get users_path
# assert_template "users/index"
# assert_select "div.pagination"
# first_page_of_users = User.paginate(page: 1)
# first_page_of_users.each do |user|
# assert_select "a[href=?]", user_path(user), text: user.name
# unless user == @admin
# assert_select "a[href=?]", user_path(user), text: "delete", method: :delete
# end
# end
# assert_difference "User.count", -1 do
# delete user_path(@non_admin)
# end
# end

test "index as non-admin" do
log_in_as(@non_admin)
get users_path
assert_template "users/index"
assert_select "a", text: "delete", count: 0

end
end

0 comments on commit 77e4c4f

Please sign in to comment.