Bivio::Delegate::SimpleAuthSupport
# Copyright (c) 2001-2010 bivio Software, Inc. All rights reserved.
# $Id$
package Bivio::Delegate::SimpleAuthSupport;
use strict;
use Bivio::Base 'Collection.Attributes';
use Bivio::IO::Trace;
our($_TRACE);
my($_C) = b_use('IO.Config');
my($_RT) = b_use('Model.RowTag');
my($_RO) = b_use('Model.RealmOwner');
my($_RR) = b_use('Model.RealmRole');
my($_PS) = b_use('Auth.PermissionSet');
my($_P) = b_use('Auth.Permission');
my($_USER) = b_use('Auth.RealmType')->USER;
my($_CRR) = b_use('Cache.RealmRole');
my($_DEFAULT_PERMISSIONS) = {};
my($_EMPTY_PERMISSION_MAP) = $_RR->EMPTY_PERMISSION_MAP;
sub clear_model_cache {
my($proto, $req) = @_;
$req->delete(__PACKAGE__);
return;
}
sub get_auth_user {
# (proto, Agent.Request) : Biz.Model
# Expects I<Request.auth_user_id> to be set. If it isn't set, returns
# C<undef>. LoginForm or some other cookie handler should set this.
my(undef, $req) = @_;
# This special field is set by one of the handlers (LoginForm).
my($auth_user_id) = $req->unsafe_get('auth_user_id');
_trace('auth_user_id=', $auth_user_id) if $_TRACE;
return
undef unless $auth_user_id;
# Make sure user loads and has a valid password (could login)
my($auth_user) = $_RO->new($req);
return $auth_user
if $auth_user->unauth_load({
realm_id => $auth_user_id,
realm_type => $_USER,
}) && $auth_user->has_valid_password;
return undef;
}
sub load_permissions {
# (proto, Auth.Realm, Auth.Role, Agent.Request) : Auth.PermissionSet
# Returns the permission set from RealmRole table. If there are no permissions,
# loads default permissions from RealmRole table.
my($proto, $realm, $role, $req) = @_;
my($owner) = $realm->unsafe_get('owner');
if ($owner and my $res = _get($owner->get('realm_id'), $role, $req)) {
return $res;
}
my($rid) = $realm->get_default_id;
return ($_DEFAULT_PERMISSIONS->{$rid} ||= {})->{$role}
||= _get($rid, $role, $req)
|| $_EMPTY_PERMISSION_MAP->{$role}
|| b_die($role, ': EMPTY_PERMISSION_MAP missing role');
}
sub task_permission_ok {
# (proto, Auth.PermissionSet, Auth.PermissionSet, Agent.Request) : boolean
# Returns true if I<user> has all permissions in I<task>.
# Computes SUPER_USER_TRANSIENT and SUBSTITUTE_USER_TRANSIENT.
my($proto, $user, $task, $req) = @_;
foreach my $op ('', qw(super_user substitute_user test dev)) {
if ($op) {
my($method) = 'is_' . $op;
next
unless ($op =~ /^su/ ? $req : $_C)->$method();
$_PS->set(
\$user,
$_P->from_name($op . '_transient'));
_trace($op, ' user: ', $_PS->to_array($user)) if $_TRACE;
}
# Does this role have all the required permission?
return 1 if ($user & $task) eq $task;
}
_trace('insufficient privileges') if $_TRACE;
return 0;
}
sub _get {
my($realm_id, $role, $req) = @_;
return $_CRR->permission_set_for_realm_role($realm_id, $role, $req);
}
1;