package Vee::Authorization;

use strict;
use warnings;

use base 'Exporter';

=head1 NAME

Vee::Authorization - Custom authorization for Catalyst

=head1 SYNOPSIS

    $c->can_i('create_post', $thread->id);

=head1 DESCRIPTION

Quick authorization module, to check whether the currently logged-in user has
been given a particular permission.

=head1 FUNCTIONS

=head2 has_permission

Returns 1 if the current user has the given permission in the given scope, 0 if
the permission has been explicitly denied, or undef if there is no applicable
rule.

=cut

sub has_permission {
    my ($c, $permission, $scope) = @_;
    $scope = $scope ? [ $scope, '' ] : '';
    return 0 unless $c->user;

    my @usergroups = $c->model('UserGroups')->search({ user_id => [ 0, $c->user->obj->id ] })->get_column('group_id')->all;
#    my %seen;

    # TODO: get group parents!
    my @groupperms = $c->model('GroupPermissions')->search({
        group_id => { -in => \@usergroups },
        permission => [ $permission, 'splat' ],
        scope => $scope,
    }, {
        order_by => \'scope = "" DESC, permission = "splat" DESC',
        group_by => [ 'scope', 'permission' ],
        columns => [ 'polarity' ],
    });
    if (!@groupperms) {
        return undef
    } elsif (grep { $_->polarity eq 'deny' } @groupperms) {
        return 0
    } else {
        return 1
    }
}

# infuse Catalyst with some awesome
{
    no strict 'refs';
    *{'Vee::can_i'} = \&has_permission;
}

=head1 AUTHOR

Maintainer: Alex "Eevee" Munroe (C<veekun@veekun.com>)

See the included F<AUTHORS> file for a full list of contributers.

=head1 LICENSE

See the included F<LICENSE> file.

=cut

1;
