make synapse permissions depend on topic1 and topic2 (#839)
* deep change to synapse policy - is this ok? * make synapse policy resilient to nil topic1/topic2/map * use a transaction to handle authorization vs invalid record in synapse controller * more synapse controller tests * inline documentation * fix policy(Synapse).create?
This commit is contained in:
parent
4dc32d7d2e
commit
e49e5c258a
3 changed files with 53 additions and 9 deletions
|
@ -22,10 +22,18 @@ class SynapsesController < ApplicationController
|
||||||
@synapse = Synapse.new(synapse_params)
|
@synapse = Synapse.new(synapse_params)
|
||||||
@synapse.desc = '' if @synapse.desc.nil?
|
@synapse.desc = '' if @synapse.desc.nil?
|
||||||
@synapse.desc.strip! # no trailing/leading whitespace
|
@synapse.desc.strip! # no trailing/leading whitespace
|
||||||
authorize @synapse
|
|
||||||
|
# we want invalid params to return :unprocessable_entity
|
||||||
|
# so we have to authorize AFTER saving. But if authorize
|
||||||
|
# fails, we need to rollback the SQL transaction
|
||||||
|
success = nil
|
||||||
|
ActiveRecord::Base.transaction do
|
||||||
|
success = @synapse.save
|
||||||
|
success ? authorize(@synapse) : skip_authorization
|
||||||
|
end
|
||||||
|
|
||||||
respond_to do |format|
|
respond_to do |format|
|
||||||
if @synapse.save
|
if success
|
||||||
format.json { render json: @synapse, status: :created }
|
format.json { render json: @synapse, status: :created }
|
||||||
else
|
else
|
||||||
format.json { render json: @synapse.errors, status: :unprocessable_entity }
|
format.json { render json: @synapse.errors, status: :unprocessable_entity }
|
||||||
|
|
|
@ -16,16 +16,16 @@ class SynapsePolicy < ApplicationPolicy
|
||||||
end
|
end
|
||||||
|
|
||||||
def create?
|
def create?
|
||||||
user.present?
|
if record.try(:topic1) && record.try(:topic2)
|
||||||
# TODO: add validation against whether you can see both topics
|
topic1_show? && topic2_show? && user.present?
|
||||||
|
else
|
||||||
|
# allows us to use policy(Synapse).create?
|
||||||
|
user.present?
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def show?
|
def show?
|
||||||
if record.defer_to_map.present?
|
topic1_show? && topic2_show? && synapse_show?
|
||||||
map_policy.show?
|
|
||||||
else
|
|
||||||
record.permission == 'commons' || record.permission == 'public' || record.user == user
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def update?
|
def update?
|
||||||
|
@ -43,7 +43,26 @@ class SynapsePolicy < ApplicationPolicy
|
||||||
end
|
end
|
||||||
|
|
||||||
# Helpers
|
# Helpers
|
||||||
|
|
||||||
def map_policy
|
def map_policy
|
||||||
@map_policy ||= Pundit.policy(user, record.defer_to_map)
|
@map_policy ||= Pundit.policy(user, record.defer_to_map)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def topic1_show?
|
||||||
|
@topic1_policy ||= Pundit.policy(user, record.topic1)
|
||||||
|
@topic1_policy&.show?
|
||||||
|
end
|
||||||
|
|
||||||
|
def topic2_show?
|
||||||
|
@topic2_policy ||= Pundit.policy(user, record.topic2)
|
||||||
|
@topic2_policy&.show?
|
||||||
|
end
|
||||||
|
|
||||||
|
def synapse_show?
|
||||||
|
if record.defer_to_map.present?
|
||||||
|
map_policy&.show?
|
||||||
|
else
|
||||||
|
record.permission == 'commons' || record.permission == 'public' || record.user == user
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -35,6 +35,16 @@ RSpec.describe SynapsesController, type: :controller do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
context 'with private topics' do
|
||||||
|
it 'redirects to /' do
|
||||||
|
post :create, format: :json, params: {
|
||||||
|
synapse: valid_attributes.merge(topic1_id: create(:topic, permission: 'private'), topic2_id: create(:topic, permission: 'private'))
|
||||||
|
}
|
||||||
|
expect(response.status).to eq 302
|
||||||
|
expect(response).to redirect_to('/')
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
context 'with invalid params' do
|
context 'with invalid params' do
|
||||||
it 'returns 422 UNPROCESSABLE ENTITY' do
|
it 'returns 422 UNPROCESSABLE ENTITY' do
|
||||||
post :create, format: :json, params: {
|
post :create, format: :json, params: {
|
||||||
|
@ -42,6 +52,13 @@ RSpec.describe SynapsesController, type: :controller do
|
||||||
}
|
}
|
||||||
expect(response.status).to eq 422
|
expect(response.status).to eq 422
|
||||||
end
|
end
|
||||||
|
it 'does not create a synapse' do
|
||||||
|
expect {
|
||||||
|
post :create, format: :json, params: { synapse: invalid_attributes }
|
||||||
|
}.to change {
|
||||||
|
Synapse.count
|
||||||
|
}.by 0
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue