Commit f0f2a945 authored by paz's avatar paz

Merge branch 'paz/authorize-with-a-bang' into 'release-4.0'

Let authorizer raise error, rename authorizing methods, and fix response if not found.

See merge request !248
parents 2f53ce63 264e23cd
Pipeline #21988 passed with stages
in 4 minutes and 14 seconds
......@@ -23,8 +23,8 @@ module SchleuderApiDaemonHelper
end
end
def authorized?(resource, action)
current_account.authorized?(resource, action) || halt(403)
def authorize!(resource, action)
current_account.authorize!(resource, action) || halt(404)
end
def current_account
......
......@@ -37,8 +37,8 @@ module Schleuder
admin_lists.where(email: list.email).exists?
end
def authorized?(resource, action)
authorizer.authorized?(resource, action)
def authorize!(resource, action)
authorizer.authorize!(resource, action)
end
def scoped(resource)
......
......@@ -8,12 +8,12 @@ module Schleuder
@account = account
end
def authorized?(resource, action)
def authorize!(resource, action)
return nil if resource.nil?
action = action.to_s
action << '?' unless action.last == '?'
policy(resource).public_send(action)
policy(resource).public_send(action) || raise(Errors::Unauthorized.new(resource))
end
def scoped(klass)
......
......@@ -8,8 +8,8 @@ module Schleuder
private
def authorized?(resource, action)
current_account.authorized?(resource, action) || raise(Errors::Unauthorized.new)
def authorize!(resource, action)
current_account.authorize!(resource, action)
end
def get_list_by_id_or_email(identifier)
......
......@@ -2,33 +2,33 @@ module Schleuder
class KeysController < BaseController
def find_all(list_id)
list = get_list_by_id_or_email(list_id)
authorized?(list, :list_keys)
authorize!(list, :list_keys)
list.keys
end
def import(list_id, key)
list = get_list_by_id_or_email(list_id)
authorized?(list, :add_keys)
authorize!(list, :add_keys)
list.import_key(key)
end
def check(list_id)
list = get_list_by_id_or_email(list_id)
authorized?(list, :check_keys)
authorize!(list, :check_keys)
list.check_keys
end
def find(list_id, fingerprint)
list = get_list_by_id_or_email(list_id)
key = list.key(fingerprint)
authorized?(key, :read)
authorize!(key, :read)
key
end
def delete(list_id, fingerprint)
list = get_list_by_id_or_email(list_id)
key = list.key(fingerprint) || halt(404)
authorized?(key, :delete)
authorize!(key, :delete)
key.delete!
end
end
......
......@@ -5,7 +5,7 @@ module Schleuder
end
def create(listname, fingerprint, adminaddress, adminfingerprint, adminkey)
authorized?(List, :create)
authorize!(List, :create)
ListBuilder.new(
{email: listname, fingerprint: fingerprint}, adminaddress, adminfingerprint, adminkey
).run
......@@ -17,19 +17,19 @@ module Schleuder
def find(identifier)
list = get_list_by_id_or_email(identifier)
authorized?(list, :read)
authorize!(list, :read)
list
end
def update(identifier, attributes)
list = get_list_by_id_or_email(identifier)
authorized?(list, :update)
authorize!(list, :update)
list.update(attributes)
end
def delete(identifier)
list = get_list_by_id_or_email(identifier)
authorized?(list, :delete)
authorize!(list, :delete)
list.destroy
end
......@@ -39,7 +39,7 @@ module Schleuder
def send_list_key_to_subscriptions(list_id)
list = get_list_by_id_or_email(list_id)
authorized?(list, :send_list_key)
authorize!(list, :send_list_key)
list.send_list_key_to_subscriptions
end
end
......
module Schleuder
class SubscriptionsController < BaseController
def find_all(filter={})
authorized?(Subscription, :list)
authorize!(Subscription, :list)
current_account.scoped(Subscription).where(filter)
end
def find(email)
subscription = Subscription.where(email: email).first
authorized?(subscription, :read)
authorize!(subscription, :read)
subscription
end
def subscribe(list_id, attributes, key_material)
list = get_list_by_id_or_email(list_id)
authorized?(list, :subscribe)
authorize!(list, :subscribe)
list.subscribe(
attributes['email'],
attributes['fingerprint'],
......@@ -25,13 +25,13 @@ module Schleuder
def update(email, attributes)
subscription = Subscription.where(email: email).first
authorized?(subscription, :update)
authorize!(subscription, :update)
subscription.update(attributes)
end
def delete(email)
subscription = Subscription.where(email: email).first
authorized?(subscription, :delete)
authorize!(subscription, :delete)
subscription.destroy
end
......
module Schleuder
module Errors
class Unauthorized < Base
def initialize
super t('errors.unauthorized')
def initialize(resource=nil)
owner_email = case resource
when List
resource.owner_address
when Subscription, GPGME::Key
resource.list.owner_address
else
# Shouldn't happen, but who knows what life brings...
'LISTNAME-owner@DOMAIN'
end
super t('errors.unauthorized', list_owner_email: owner_email)
end
end
end
......
......@@ -75,6 +75,12 @@ de:
too_many_matching_keys: |
Zu viele Schlüssel gefunden für '%{input}':
%{key_strings}
unauthorized: |
Die Konfiguration dieser Liste verhindert, dass du diese Aktion ausführen darfst.
Wenn du nicht Hilfe brauchst wende dich bitte an
deine Listen-Admins <%{list_owner_email}>)
oder lies die Dokumentation <https://schleuder.org/schleuder/docs/>.
keyword_handlers:
handler_failed: Das Schlüsselwort '%{keyword}' verursachte einen unbekannten Fehler. Die System-Administratoren wurden benachrichtigt.
keyword_admin_notify:
......
......@@ -75,6 +75,12 @@ en:
too_many_matching_keys: |
Too many matching keys for '%{input}':
%{key_strings}
unauthorized: |
Unfortunately you are not allowed to do that.
If you need help please contact
your list-admins <%{list_owner_email}>
or read the documentation <https://schleuder.org/schleuder/docs/>.
keyword_handlers:
handler_failed: Running keyword '%{keyword}' caused an unknown error. System-admins have been notified.
keyword_admin_notify:
......
......@@ -30,7 +30,7 @@ describe 'subscription via api' do
expect(JSON.parse(last_response.body)[0]['email']).to eq subscription.email
end
it 'returns a 403 when no list with the given email exists' do
it 'returns a 404 when no list with the given email exists' do
list = create(:list, email: 'somelist@example.org')
subscription = create(:subscription, list_id: list.id, admin: true)
account = create(:account, email: subscription.email)
......@@ -38,8 +38,8 @@ describe 'subscription via api' do
get 'subscriptions.json?list_id=non_existing@example.org', { 'CONTENT_TYPE' => 'application/json' }
expect(last_response.status).to be 403
expect(last_response.body).to eq 'Not authorized'
expect(last_response.status).to be 404
expect(last_response.body).to eq 'Not found'
end
it 'returns a 403 if no subscription is associated with the account' do
......
require 'spec_helper'
describe Schleuder::Authorizer do
describe '#authorized?' do
it 'returns nil when resource is nil' do
describe '#authorize!' do
it 'raises an error when resource is nil' do
account = create(:account)
expect(Authorizer.new(account).authorized?(nil, :some_action)).to eq nil
expect(Authorizer.new(account).authorize!(nil, :some_action)).to eql nil
end
it 'returns true if account is authorized' do
it 'does not raise an error if account is authorized' do
list = create(:list)
subscription = create(:subscription, list_id: list.id, admin: false)
account = create(:account, email: subscription.email)
expect(Authorizer.new(account).authorized?(list, :read)).to eq true
caught_exception = nil
begin
Authorizer.new(account).authorize!(list, :read)
rescue Schleuder::Errors::Unauthorized => exc
caught_exception = exc
end
expect(caught_exception.class).to eql NilClass
end
it 'returns false if account is NOT authorized' do
it 'raises an error if account is NOT authorized' do
account = create(:account)
list = create(:list)
expect(Authorizer.new(account).authorized?(list, :read)).to eq false
begin
Authorizer.new(account).authorize!(list, :read)
rescue Schleuder::Errors::Unauthorized => exc
caught_exception = exc
end
expect(caught_exception.class).to eql Errors::Unauthorized
end
end
......
......@@ -85,14 +85,13 @@ describe Schleuder::KeysController do
expect(result.fingerprint).to eq '59C71FB38AEE22E091C78259D06350440F759BD3'
end
it 'returns unauthorized if user is authorized but no key is found for given fingerprint' do
it 'returns nil if user is authorized but no key is found for given fingerprint' do
list = create(:list)
subscription = create(:subscription, list_id: list.id, admin: true)
account = create(:account, email: subscription.email)
expect do
KeysController.new(account).find(list.id, '80C71FB38AEE22E091C78259D06350440F759BD3')
end.to raise_error(Schleuder::Errors::Unauthorized)
key = KeysController.new(account).find(list.id, '80C71FB38AEE22E091C78259D06350440F759BD3')
expect(key).to eql(nil)
end
it 'raises an unauthorized error when the user is not authorized' do
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment