Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Blog app: Add Authorization Rules #10

Merged
merged 23 commits into from
Jul 15, 2023
Merged
Show file tree
Hide file tree
Changes from 21 commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
e9a8227
install cancancan library
cherelemma Jul 13, 2023
210c90e
install cancancan and generate ability model
cherelemma Jul 15, 2023
963a39c
create migration for role and update schema
cherelemma Jul 15, 2023
4b12fe9
Add destroy method to post controller
Tshobohwa Jul 15, 2023
a57b0c1
Add destroy comment method
Tshobohwa Jul 15, 2023
6afcf6e
Fix errors
Tshobohwa Jul 15, 2023
8ba00e2
Add destroy routes
Tshobohwa Jul 15, 2023
36c1b60
Add authorization rules for delete post
Tshobohwa Jul 15, 2023
dd53e26
update the pages layout
cherelemma Jul 15, 2023
e08ac24
Update index.html
Tshobohwa Jul 15, 2023
fef04f0
add conditional Delete button to users' show view
cherelemma Jul 15, 2023
1f839fc
format the index page of the app
cherelemma Jul 15, 2023
310202c
update the stylesheet
cherelemma Jul 15, 2023
20b7e6e
Merge branch 'add-authorization-rules' of github.com:Microverse-Fulls…
cherelemma Jul 15, 2023
12c5f96
debug and fix linters error
cherelemma Jul 15, 2023
9808581
Merge branch 'dev' into add-authorization-rules
cherelemma Jul 15, 2023
f9bdda8
changing db credantials
cherelemma Jul 15, 2023
3a54d7c
update pages layout and page elements
cherelemma Jul 15, 2023
96ef339
add load_and_authorize_resource method at the top of PostsController
cherelemma Jul 15, 2023
33cd046
styling posts show page
cherelemma Jul 15, 2023
1dab854
fix stylelint and rubucop error
cherelemma Jul 15, 2023
52a9cee
like button styling
cherelemma Jul 15, 2023
8ddf8e3
update post delete method
cherelemma Jul 15, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -79,3 +79,5 @@ group :test do
end

gem 'devise', '~> 4.9'

gem 'cancancan', '~> 3.5'
2 changes: 2 additions & 0 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ GEM
bootsnap (1.16.0)
msgpack (~> 1.2)
builder (3.2.4)
cancancan (3.5.0)
capybara (3.39.2)
addressable
matrix
Expand Down Expand Up @@ -268,6 +269,7 @@ PLATFORMS

DEPENDENCIES
bootsnap
cancancan (~> 3.5)
capybara
debug
devise (~> 4.9)
Expand Down
144 changes: 129 additions & 15 deletions app/assets/stylesheets/application.css
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,39 @@
box-sizing: border-box;
}

.wrapper {
margin: 1rem auto;
gap: 1rem;
box-shadow: 0 0 2px 2px rgb(231, 231, 237);
}

.wrapper,
.container {
width: 80vw;
width: 90vw;
height: 100vh;
display: flex;
flex-direction: column;
align-items: center;
margin: 2rem 0;
background-color: whitesmoke;
}

.navbar {
width: 100%;
display: flex;
flex-direction: row;
justify-content: space-between;
align-items: center;
gap: 1rem;
padding: 1rem;
background-color: #1868f1;
border: 1px solid rgb(128, 128, 128);
}

.logout {
cursor: pointer;
padding: 5px 10px;
font-size: 15px;
font-weight: bold;
}

.user {
Expand All @@ -21,6 +46,7 @@
justify-content: center;
align-items: center;
gap: 2rem;
padding: 1rem;
}

.user-photo {
Expand All @@ -36,7 +62,7 @@
}

.user-info {
width: 46%;
width: 80%;
display: flex;
flex-direction: row;
justify-content: space-between;
Expand All @@ -51,7 +77,9 @@
}

.user-posts {
justify-content: flex-end;
display: flex;
flex-direction: column;
gap: 1rem;
align-self: flex-end;
padding: 2rem 1rem 1rem 1rem;
font-size: small;
Expand All @@ -70,10 +98,11 @@ a {
}

.post {
width: 60%;
width: 90%;
display: flex;
flex-direction: column;
border: 3px solid black;
margin-bottom: 1rem;
}

.post h3 {
Expand All @@ -86,42 +115,81 @@ a {
padding: 0.5rem 1rem;
}

.post-text {
display: grid;
grid-template-columns: 2fr 0.5fr;
gap: 1rem;
}

.count {
display: flex;
flex-direction: row;
justify-content: flex-end;
justify-content: space-around;
align-items: center;
padding: 0.5rem 1rem;
font-size: small;
font-size: medium;
gap: 0.5rem;
}

.post-text .count {
display: flex;
flex-direction: column;
justify-content: space-around;
align-items: flex-start;
padding: 0.5rem 2rem 0.5rem 10vh;
font-size: medium;
gap: 0.5rem;
}

.count span {
padding: 0 0.25rem;
}

.like_count_btn {
display: flex;
flex-direction: row;
align-items: center;
gap: 1rem;
}

.post-comments {
width: 60%;
width: 100%;
display: flex;
flex-direction: column;
padding: 1rem;
gap: 0.5rem;
border: 3px solid black;
}

.btn-link {
width: auto;
align-self: center;
}

button {
button,
form input[type="submit"] {
border-bottom: 5px solid black;
border-right: 3px solid black;
border-radius: 5px;
padding: 5px;
}

.like_count_btn button {
width: 2vw;
height: 2vw;
font-size: x-large;
padding: 0;
}

form input[type="hidden"] {
width: 1px;
height: 1px;
}

.btn-link,
.btn-link button {
cursor: pointer;
padding: 5px;
font-size: 15px;
margin: 10px 0;
}

.post-form,
Expand All @@ -135,21 +203,39 @@ button {
background-color: #f5f5f5;
}

.comments,
.posts {
width: 80%;
display: flex;
flex-direction: column;
flex-direction: row;
padding: 1rem;
gap: 1rem;
}

.comments {
display: grid;
grid-template-columns: 0.5fr 2.5fr 0.5fr;
}

.post .add-comment {
margin: 0 auto;
align-self: center;
}

.comment-form textarea,
.post-form textarea {
width: 100%;
height: 100px;
padding: 0.5rem;
border: 1px solid black;
border-radius: 5px;
}

.comment-btn,
.like-button {
width: auto;
cursor: pointer;
padding: 5px 10px;
margin-left: 5rem;
font-size: 15px;
border-bottom: 5px solid black;
border-right: 3px solid black;
border-radius: 5px;
Expand Down Expand Up @@ -184,6 +270,15 @@ form input {
padding: 0.5rem;
}

.like_count_btn form {
width: 3vw;
}

.comments form {
width: auto;
align-self: flex-end;
}

.shared {
display: flex;
flex-direction: column-reverse;
Expand Down Expand Up @@ -226,14 +321,20 @@ ul {

.auth_links {
display: flex;
flex-direction: row;
flex-direction: column;
justify-content: flex-start;
align-items: center;
gap: 1rem;
width: 30vw;
margin: auto auto;
}

.sign_in_up {
display: flex;
flex-direction: row;
gap: 1rem;
}

.auth_links a {
color: blue;
padding: 0.5rem;
Expand Down Expand Up @@ -284,8 +385,21 @@ ul {
}

.form-elements {
width: 100%;
display: flex;
flex-direction: row;
align-items: center;
gap: 1rem;
margin: 1rem 0;
}

.like-button {
border: none;
background-color: transparent;
font-size: 2rem;
}

.short-button {
width: 7vw;
align-items: flex-end;
}
12 changes: 12 additions & 0 deletions app/controllers/comments_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,18 @@ def create
end
end

def destroy
@comment = Comment.find(params[:id])
@post = @comment.post

if can? :destroy, @comment
@comment.destroy
redirect_to user_post_path(@post.author, @post), notice: 'Comment was successfully deleted.'
else
redirect_to user_posts_path(current_user), alert: 'You are not authorized to delete this comment.'
end
end

private

def comment_params
Expand Down
13 changes: 13 additions & 0 deletions app/controllers/posts_controller.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
class PostsController < ApplicationController
load_and_authorize_resource

def index
@user = User.includes(posts: { comments: :author }).find(params[:user_id])
@current_user = current_user
Expand Down Expand Up @@ -27,6 +29,17 @@ def create
end
end

def destroy
@post = Post.find(params[:id])

if can? :destroy, @post
@post.destroy
redirect_to "/users/#{current_user.id}/posts", notice: 'Successfully deleted.'
else
redirect_to user_post_path(@post.author_id, @post), alert: 'Unauthorized action.'
end
end

private

def post_params
cherelemma marked this conversation as resolved.
Show resolved Hide resolved
Expand Down
38 changes: 38 additions & 0 deletions app/models/ability.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
class Ability
include CanCan::Ability

def initialize(user)
# Define abilities for the user here. For example:
can :read, :all

return unless user.present?

can :manage, User, id: user.id # user can manage only his own profile
can :manage, Post, author_id: user.id # user can manage only his own posts
can :manage, Comment, user_id: user.id # user can manage only his own comments
can :create, Like # user can create likes

return unless user.role == 'admin'

can :destroy, Post # admin can delete any post
can :destroy, Comment # admin can delete any comment

# The first argument to `can` is the action you are giving the user
# permission to do.
# If you pass :manage it will apply to every action. Other common actions
# here are :read, :create, :update and :destroy.
#
# The second argument is the resource the user can perform the action on.
# If you pass :all it will apply to every resource. Otherwise pass a Ruby
# class of the resource.
#
# The third argument is an optional hash of conditions to further filter the
# objects.
# For example, here the user can only update published articles.
#
# can :update, Article, published: true
#
# See the wiki for details:
# https://github.com/CanCanCommunity/cancancan/blob/develop/docs/define_check_abilities.md
end
end
3 changes: 2 additions & 1 deletion app/models/user.rb
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
class User < ApplicationRecord
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable, :trackable and :omniauthable
devise :database_authenticatable, :registerable,
devise :database_authenticatable, :registerable, :confirmable,
:recoverable, :rememberable, :validatable

has_many :posts, foreign_key: :author_id, dependent: :destroy
has_many :comments, foreign_key: :user_id, dependent: :destroy
has_many :likes, foreign_key: :user_id, dependent: :destroy
Expand Down
Loading