@@ -7,13 +9,16 @@
- <%= link_to edit_photo_path(photo), class: "btn btn-link btn-sm text-muted" do %>
-
- <% end %>
+ <% if current_user == photo.owner %>
+ <%= link_to edit_photo_path(photo), class: "btn btn-link btn-sm text-muted" do %>
+
+ <% end %>
- <%= link_to photo, data: { turbo_method: :delete }, class: "btn btn-link btn-sm text-muted" do %>
-
+ <%= link_to photo, method: :delete, class: "btn btn-link btn-sm text-muted" do %>
+
+ <% end %>
<% end %>
+
diff --git a/app/views/users/show.html.erb b/app/views/users/show.html.erb
index 5656d7d5..89777bd8 100644
--- a/app/views/users/show.html.erb
+++ b/app/views/users/show.html.erb
@@ -1,19 +1,23 @@
+
+
+<% if current_user == @user || !@user.private? || current_user.leaders.include?(@user) %>
+
- <%= render "photos/photo", photo: photo %>
+ <%= render "users/profile_nav", user: @user %>
+
+ <% @user.own_photos.each do |photo| %>
+
+
+ <%= render "photos/photo", photo: photo %>
+
+
+ <% end %>
<% end %>
diff --git a/config/environments/development.rb b/config/environments/development.rb
index 79e0b793..90e1a37e 100644
--- a/config/environments/development.rb
+++ b/config/environments/development.rb
@@ -2,7 +2,7 @@
Rails.application.configure do
config.action_mailer.default_url_options = { host: 'localhost', port: 3000 }
- # Allow better_errors to work in online IDE
+ # Allow better_errors to work in online IDE
config.web_console.whitelisted_ips = "0.0.0.0/0.0.0.0"
BetterErrors::Middleware.allow_ip! "0.0.0.0/0.0.0.0"
# Auto-connect to database when rails console opens
diff --git a/config/routes.rb b/config/routes.rb
index 47050a54..c8620ed5 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -4,14 +4,14 @@
devise_for :users
resources :comments
- resources :follow_requests
- resources :likes
- resources :photos
-
+ resources :follow_requests, except: [:index, :show, :new, :edit]
+ resources :likes, only: [:create, :destroy]
+ resources :photos, except: [:index]
+
get ":username" => "users#show", as: :user
get ":username/liked" => "users#liked", as: :liked
get ":username/feed" => "users#feed", as: :feed
get ":username/discover" => "users#discover", as: :discover
get ":username/followers" => "users#followers", as: :followers
get ":username/following" => "users#following", as: :following
-end
\ No newline at end of file
+end
From 962ca0c709526a37e83ba5cf96ae25bb4f70a802 Mon Sep 17 00:00:00 2001
From: Calvin Armstrong <138508650+armstrca@users.noreply.github.com>
Date: Wed, 11 Oct 2023 14:25:30 +0000
Subject: [PATCH 2/4] got live app preview to work
---
config/environments/development.rb | 1 +
1 file changed, 1 insertion(+)
diff --git a/config/environments/development.rb b/config/environments/development.rb
index 90e1a37e..399124c1 100644
--- a/config/environments/development.rb
+++ b/config/environments/development.rb
@@ -2,6 +2,7 @@
Rails.application.configure do
config.action_mailer.default_url_options = { host: 'localhost', port: 3000 }
+ config.hosts.clear
# Allow better_errors to work in online IDE
config.web_console.whitelisted_ips = "0.0.0.0/0.0.0.0"
BetterErrors::Middleware.allow_ip! "0.0.0.0/0.0.0.0"
From 51834e81930cf7e69c39841875d0360bd7d0ef8c Mon Sep 17 00:00:00 2001
From: Calvin Armstrong <138508650+armstrca@users.noreply.github.com>
Date: Wed, 11 Oct 2023 15:57:28 +0000
Subject: [PATCH 3/4] Pundit stuff
---
Gemfile | 3 +-
Gemfile.lock | 3 ++
app/controllers/application_controller.rb | 15 +++++++
app/controllers/photos_controller.rb | 33 +++++++++-----
app/policies/application_policy.rb | 53 +++++++++++++++++++++++
app/policies/photo_policy.rb | 16 +++++++
app/policies/user_policy.rb | 16 +++++++
app/views/users/show.html.erb | 2 +-
lib/tasks/dev.rake | 2 +-
9 files changed, 128 insertions(+), 15 deletions(-)
create mode 100644 app/policies/application_policy.rb
create mode 100644 app/policies/photo_policy.rb
create mode 100644 app/policies/user_policy.rb
diff --git a/Gemfile b/Gemfile
index 7b71f46c..2b366653 100644
--- a/Gemfile
+++ b/Gemfile
@@ -3,7 +3,8 @@ git_source(:github) { |repo| "https://github.com/#{repo}.git" }
ruby "3.2.1"
-gem 'devise'
+
+gem 'pundit'
gem "simple_form"
diff --git a/Gemfile.lock b/Gemfile.lock
index 42668dd8..e73e59d4 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -233,6 +233,8 @@ GEM
public_suffix (5.0.1)
puma (5.6.5)
nio4r (~> 2.0)
+ pundit (2.3.1)
+ activesupport (>= 3.0.0)
racc (1.6.2)
rack (2.2.7)
rack-protection (3.0.6)
@@ -425,6 +427,7 @@ DEPENDENCIES
pg (~> 1.1)
pry-rails
puma (~> 5.0)
+ pundit
rails (~> 7.0.4, >= 7.0.4.3)
rails-erd
rails_db
diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb
index bd664b1d..20e467b0 100644
--- a/app/controllers/application_controller.rb
+++ b/app/controllers/application_controller.rb
@@ -1,4 +1,9 @@
class ApplicationController < ActionController::Base
+ include Pundit
+
+ after_action :verify_authorized, except: :index
+ after_action :verify_policy_scoped, only: :index
+
before_action :authenticate_user!
before_action :configure_permitted_parameters, if: :devise_controller?
@@ -9,4 +14,14 @@ def configure_permitted_parameters
devise_parameter_sanitizer.permit(:sign_up, keys: [:username, :private, :name, :bio, :website, :avatar_image])
devise_parameter_sanitizer.permit(:account_update, keys: [:username, :private, :name, :bio, :website, :avatar_image])
end
+
+ rescue_from Pundit::NotAuthorizedError, with: :user_not_authorized
+
+ private
+
+ def user_not_authorized
+ flash[:alert] = "You are not authorized to perform this action."
+
+ redirect_back fallback_location: root_url
+ end
end
diff --git a/app/controllers/photos_controller.rb b/app/controllers/photos_controller.rb
index c2ba573c..0adbfa5b 100644
--- a/app/controllers/photos_controller.rb
+++ b/app/controllers/photos_controller.rb
@@ -1,6 +1,7 @@
class PhotosController < ApplicationController
before_action :set_photo, only: %i[ show edit update destroy ]
before_action :ensure_current_user_is_owner, only: [:destroy, :update, :edit]
+ before_action :ensure_user_is_authorized, only: [:show]
# GET /photos or /photos.json
def index
@@ -9,6 +10,7 @@ def index
# GET /photos/1 or /photos/1.json
def show
+ authorize @photo
end
# GET /photos/new
@@ -64,19 +66,26 @@ def destroy
end
private
- # Use callbacks to share common setup or constraints between actions.
- def set_photo
- @photo = Photo.find(params[:id])
- end
- def ensure_current_user_is_owner
- if current_user != @photo.owner
- redirect_back fallback_location: root_url, alert: "You're not authorized for that."
- end
- end
+ # Use callbacks to share common setup or constraints between actions.
+ def set_photo
+ @photo = Photo.find(params[:id])
+ end
- # Only allow a list of trusted parameters through.
- def photo_params
- params.require(:photo).permit(:image, :comments_count, :likes_count, :caption, :owner_id)
+ def ensure_current_user_is_owner
+ if current_user != @photo.owner
+ redirect_back fallback_location: root_url, alert: "You're not authorized for that."
end
+ end
+
+ # Only allow a list of trusted parameters through.
+ def photo_params
+ params.require(:photo).permit(:image, :comments_count, :likes_count, :caption, :owner_id)
+ end
+
+ # def ensure_user_is_authorized
+ # if !PhotoPolicy.new(current_user, @photo).show?
+ # raise Pundit::NotAuthorizedError, "not allowed"
+ # end
+ # end
end
diff --git a/app/policies/application_policy.rb b/app/policies/application_policy.rb
new file mode 100644
index 00000000..e000cba5
--- /dev/null
+++ b/app/policies/application_policy.rb
@@ -0,0 +1,53 @@
+# frozen_string_literal: true
+
+class ApplicationPolicy
+ attr_reader :user, :record
+
+ def initialize(user, record)
+ @user = user
+ @record = record
+ end
+
+ def index?
+ false
+ end
+
+ def show?
+ false
+ end
+
+ def create?
+ false
+ end
+
+ def new?
+ create?
+ end
+
+ def update?
+ false
+ end
+
+ def edit?
+ update?
+ end
+
+ def destroy?
+ false
+ end
+
+ class Scope
+ def initialize(user, scope)
+ @user = user
+ @scope = scope
+ end
+
+ def resolve
+ raise NotImplementedError, "You must define #resolve in #{self.class}"
+ end
+
+ private
+
+ attr_reader :user, :scope
+ end
+end
diff --git a/app/policies/photo_policy.rb b/app/policies/photo_policy.rb
new file mode 100644
index 00000000..1dfaa3d1
--- /dev/null
+++ b/app/policies/photo_policy.rb
@@ -0,0 +1,16 @@
+# app/policies/photo_policy.rb
+
+class PhotoPolicy < ApplicationPolicy
+ attr_reader :user, :photo
+
+ def initialize(user, photo)
+ @user = user
+ @photo = photo
+ end
+
+ def show?
+ user == photo.owner ||
+ !photo.owner.private? ||
+ photo.owner.followers.include?(user)
+ end
+end
diff --git a/app/policies/user_policy.rb b/app/policies/user_policy.rb
new file mode 100644
index 00000000..d1bfbce1
--- /dev/null
+++ b/app/policies/user_policy.rb
@@ -0,0 +1,16 @@
+# app/policies/user_policy.rb
+
+class UserPolicy < ApplicationPolicy
+ attr_reader :current_user, :user
+
+ def initialize(current_user, user)
+ @current_user = current_user
+ @user = user
+ end
+
+ def show?
+ user == current_user ||
+ !user.private? ||
+ user.followers.include?(current_user)
+ end
+end
diff --git a/app/views/users/show.html.erb b/app/views/users/show.html.erb
index 89777bd8..67265608 100644
--- a/app/views/users/show.html.erb
+++ b/app/views/users/show.html.erb
@@ -6,7 +6,7 @@