dimanche 12 avril 2020

How can I do a before_action to redirect if you're signed in but not a member of the account

I am trying to create a before_action in my controller so only members (users) on an account can see and edit content related to an account. At the moment if I change the URL on the browser I can see and edit accounts that a user is not a member.

This is my discussion_controller:

    class DiscussionsController < ApplicationController
  before_action :set_discussion, only: [:show, :edit, :update, :destroy]
  before_action :authenticate_user!

  # GET /discussions
  def index
    @newactivitys = Newactivity.all.order(created_at: :desc).limit(6)
    @pagy, @discussions = pagy(Discussion.joins(:posts).group('discussions.id').order('MAX(posts.created_at) DESC'))
  end

  # GET /discussions/1
  def show
    @newactivitys = Newactivity.all.order(created_at: :desc).limit(6)
  end

  # GET /discussions/new
  def new
    @discussion = Discussion.new
    @discussion.posts.new
    @newactivitys = Newactivity.all.order(created_at: :desc).limit(6)
  end

  # GET /discussions/1/edit
  def edit
    @newactivitys = Newactivity.all.order(created_at: :desc).limit(6)
  end

  # POST /discussions
  def create
    @newactivitys = Newactivity.all.order(created_at: :desc).limit(6)
    @discussion = Discussion.new(discussion_params)
    @discussion.posts.each{ |post| post.user = current_user }

    if @discussion.save
      redirect_to @discussion, notice: 'Discussion was successfully created.'
    else
      render :new
    end
  end

  # PATCH/PUT /discussions/1
  def update
    if @discussion.update(discussion_params)
      redirect_to @discussion, notice: 'Discussion was successfully updated.'
    else
      render :edit
    end
  end

  # DELETE /discussions/1
  def destroy
    @discussion.destroy
    redirect_to discussions_url, notice: 'Discussion was successfully destroyed.'
  end

  private
    # Use callbacks to share common setup or constraints between actions.
    def set_discussion
      @discussion = current_account.discussions.find(params[:id])
    end


    # Only allow a trusted parameter "white list" through.
    def discussion_params
      params.require(:discussion).permit(:account_id, :user_id, :channel_id, :channel_name, :title, posts_attributes: [:body])
    end
end

and my models: User

class User < ApplicationRecord
  include ActionText::Attachable

  # Include default devise modules. Others available are:
  # :lockable, :timeoutable, andle :trackable
  devise :database_authenticatable, :registerable,
         :recoverable, :rememberable, :validatable,
         :confirmable, :invitable, :masqueradable,
         :omniauthable

  include UserAgreements, UserAccounts

  has_person_name

  include PgSearch::Model
  pg_search_scope :search_by_full_name, against: [:first_name, :last_name], using: { tsearch: { prefix: true } }

  # ActiveStorage Associations
  has_one_attached :avatar

  # Associations
  has_many :api_tokens, dependent: :destroy
  has_many :connected_accounts, dependent: :destroy
  has_many :discussions
  has_many :posts
  has_many :channels
  has_many :newactivitys, foreign_key: :recipient_id


  # We don't need users to confirm their email address on create,
  # just when they change it
  before_create :skip_confirmation!

  # Validations
  validates :name, presence: true
end

Discussion:

class Discussion < ApplicationRecord
  acts_as_tenant :account
  belongs_to :account
  has_many :posts, dependent: :destroy
  has_many :users, through: :posts

  belongs_to :channel

  scope :sorted, ->{ order(updated_at: :desc) }

  validates :title, presence: true

  accepts_nested_attributes_for :posts
end

And account:

    class Account < ApplicationRecord
  include Pay::Billable

  belongs_to :owner, class_name: "User"
  has_many :account_invitations, dependent: :destroy
  has_many :account_users, dependent: :destroy
  has_many :users, through: :account_users

  has_one_attached :logo

  scope :personal, ->{ where(personal: true) }
  scope :impersonal, ->{ where(personal: false) }

  has_one_attached :avatar

  validates :name, presence: true

  def email
    account_users.includes(:user).order(created_at: :asc).first.user.email
  end

  def personal_account_for?(user)
    personal? && owner_id == user.id
  end
end

Thank you!

Aucun commentaire:

Enregistrer un commentaire