Bivio::Biz::Model::RealmRole
# Copyright (c) 1999-2012 bivio Software, Inc. All rights reserved. # $Id$ package Bivio::Biz::Model::RealmRole; use strict; use Bivio::Base 'Biz.PropertyModel'; use Bivio::IO::Trace; our($_TRACE); my($_S) = b_use('Auth.Support'); my($_PS) = b_use('Auth.PermissionSet'); my($_R) = b_use('Auth.Role'); my($_RS) = b_use('Auth.RoleSet'); my($_EMPTY) = {map(($_ => ${$_PS->get_empty}), $_R->get_non_zero_list)}; sub EMPTY_PERMISSION_MAP { return {%$_EMPTY}; } sub add_permissions { return _do('add', @_); } sub get_permission_map { my($self, $realm) = @_; $realm = Bivio::Auth::Realm->new($realm, $self->get_request) unless $self->is_blesser_of($realm, 'Bivio::Auth::Realm'); return { %{$self->EMPTY_PERMISSION_MAP}, $realm->is_default ? () : %{$self->get_permission_map($realm->get_default_name)}, @{$self->new->map_iterate( sub {shift->get(qw(role permission_set))}, 'unauth_iterate_start', 'role', {realm_id => $realm->get('id')}, )} }; } sub get_roles_for_permission { my($self, $realm, $permission) = @_; my($map) = $self->get_permission_map($realm); my($roles) = $_RS->get_min; foreach my $role ($_R->get_non_zero_list) { $_RS->set(\$roles, $role) if $_PS->is_set($map->{$role}, $permission); } return $roles; } sub initialize_permissions { my($self, $realm) = @_; my($type_id) = $realm->get('realm_type')->as_int; my($realm_id) = $realm->get('realm_id'); foreach my $role ($_R->get_non_zero_list) { next if $self->unauth_load(realm_id => $realm_id, role => $role); _default($self, $type_id, $role); next if $type_id eq $realm_id; $self->create({ realm_id => $realm_id, role => $role, permission_set => $self->get('permission_set'), }); } return; } sub internal_initialize { return { version => 1, table_name => 'realm_role_t', columns => { realm_id => ['RealmOwner.realm_id', 'PRIMARY_KEY'], role => [$_R, 'PRIMARY_KEY'], permission_set => [$_PS, 'NOT_NULL'], }, auth_id => 'realm_id', }; } sub remove_permissions { return _do('remove', @_); } sub _default { my($self, $type_id, $role) = @_; $self->create({ realm_id => $type_id, role => $role, permission_set => $self->EMPTY_PERMISSION_MAP->{$role}, }) unless $self->unauth_load({realm_id => $type_id, role => $role}); return; } sub _do { my($which, $self, $realm, $roles, $permissions) = @_; $self->initialize_permissions($realm); my($realm_id) = $realm->get('realm_id'); foreach my $role (map($_R->from_any($_), @$roles)) { next unless $self->unauth_load(realm_id => $realm_id, role => $role); $self->update({ permission_set => $which eq 'add' ? ($self->get('permission_set') | _permissions($realm, $role, $permissions)) : ($self->get('permission_set') & ~_permissions($realm, $role, $permissions)), }); _trace( 'permissions: ', $_PS->to_array($self->get('permission_set')) ) if $_TRACE; } return; } sub _get_permission_set { my($realm, $role) = @_; my($rr) = $realm->new_other('RealmRole'); return $rr->get('permission_set') if $rr->unauth_load( realm_id => $realm->get('realm_id'), role => $role, ); Bivio::Die->die($role->as_string, ": not set for realm"); # DOES NOT RETURN } sub _permissions { my($realm, $role, $permissions) = @_; return $permissions unless ref($permissions); return $permissions if UNIVERSAL::isa($permissions, 'Bivio::Auth:::PermissionSet'); my($ps) = $_PS->get_empty(); foreach my $operand (@$permissions) { my($permission) = Bivio::Auth::Permission->unsafe_from_any($operand); if ($permission && $permission->get_name eq $operand) { $_PS->set($ps, $permission); } else { my($r) = $_R->unsafe_from_any($operand); Bivio::Die->die($operand, ': neither a Role nor Permission') unless $r && $r->get_name eq $operand; $$ps &= _get_permission_set($realm, $r); } } return $$ps; } 1;