|
From: Chris W. <la...@us...> - 2005-09-21 04:16:23
|
Update of /cvsroot/openinteract/OpenInteract2/lib/OpenInteract2 In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv9323/OpenInteract2 Modified Files: Action.pm Log Message: modify URL parameter assigning, etc.; don't cache content generated by administrator requests; add task_security_allowed() plus docs, which led to a small refactoring of some internal security methods Index: Action.pm =================================================================== RCS file: /cvsroot/openinteract/OpenInteract2/lib/OpenInteract2/Action.pm,v retrieving revision 1.75 retrieving revision 1.76 diff -C2 -d -r1.75 -r1.76 *** Action.pm 4 Jul 2005 03:07:53 -0000 1.75 --- Action.pm 21 Sep 2005 04:16:12 -0000 1.76 *************** *** 276,293 **** # check to ensure that's consistent (it discriminates based on # param values) ! ! my @url_params = $self->_get_url_additional_names; ! if ( scalar @url_params ) { ! my $request = CTX->request; ! if ( $request ) { ! my @url_values = $request->param_url_additional; ! my $param_count = 0; ! foreach my $value ( @url_values ) { ! next unless ( $url_params[ $param_count ] ); ! $self->param( $url_params[ $param_count ], $value ); ! $param_count++; ! } ! } ! } my $cached_content = $self->_check_cache; --- 276,280 ---- # check to ensure that's consistent (it discriminates based on # param values) ! $self->url_additional_param_from_request(); my $cached_content = $self->_check_cache; *************** *** 472,475 **** --- 459,490 ---- # SECURITY + sub task_security_allowed { + my ( $self, $task_to_check ) = @_; + unless ( $task_to_check ) { + oi_error "Must provide a task name to check for method ", + "'task_security_allowed()'."; + } + my ( $user_level, $req_level ); + eval { + $user_level = $self->_find_security_level( $task_to_check ); + $req_level = + $self->_find_required_security_for_task( $task_to_check ); + }; + if ( $@ ) { + my $msg = "Caught exception when checking security of " . + "task '$task_to_check': $@"; + $log ||= get_logger( LOG_ACTION ); + $log->warn( $msg ); + return 0; + } + else { + return ( $user_level >= $req_level ); + } + } + + + # side effects! -- assigns 'security_level' and 'security_required' + # properties, and only works on + sub _check_security { my ( $self ) = @_; *************** *** 482,517 **** return $self->security_level unless ( $self->is_secure ); - my $action_security = $self->security; - unless ( $action_security ) { - $log->error( "Secure action, no security configuration" ); - oi_error "Configuration error: action is secured but no ", - "security requirements configured"; - } - my ( $required_level ); - - # NOTE: values in $action_security have already been translated to - # security levels by OI2::Config::Initializer::_action_security_level() - # at server startup. - - # specify security per task... my $task = $self->task; ! if ( ref $action_security eq 'HASH' ) { ! $required_level = $action_security->{ $task } || ! $action_security->{DEFAULT} || ! $action_security->{default}; ! } ! ! # specify security for entire action... ! else { ! $required_level = $action_security; ! } ! ! unless ( defined $required_level ) { ! $log->is_info && ! $log->info( "Assigned security level WRITE to task ", ! "'$task' since no security requirement found" ); ! $required_level = SEC_LEVEL_WRITE; ! } ! $self->security_required( $required_level ); --- 497,502 ---- return $self->security_level unless ( $self->is_secure ); my $task = $self->task; ! my $required_level = $self->_find_required_security_for_task( $task ); $self->security_required( $required_level ); *************** *** 529,533 **** } ! # Find the level for this user/group and this action sub _find_security_level { --- 514,518 ---- } ! # no side effects! -- find the action security level for this user/group sub _find_security_level { *************** *** 537,542 **** unless ( $self->is_secure ) { $log->is_debug && ! $log->debug( sprintf( "Action '%s' not secured assigning " . ! "default level.", $self->name ) ); return DEFAULT_ACTION_SECURITY; } --- 522,527 ---- unless ( $self->is_secure ) { $log->is_debug && ! $log->debug( sprintf( "Action '%s' not secured, assigning " . ! "default level", $self->name ) ); return DEFAULT_ACTION_SECURITY; } *************** *** 558,561 **** --- 543,588 ---- + # no side effects! -- find the level necessary to exec the given task + + sub _find_required_security_for_task { + my ( $self, $task_to_check ) = @_; + + # NOTE: values in $action_security have already been translated to + # security levels by OI2::Config::Initializer::_action_security_level() + # at server startup. + my $action_security = $self->security; + unless ( $action_security ) { + $log->error( "Action ", $self->name, ": Configured as secure ", + "but no security configuration" ); + + # TODO: just return WRITE instead of throwing error? + oi_error "Configuration error: action is secured but no ", + "security requirements configured"; + } + + my $task = $task_to_check || $self->task; + + my ( $required_level ); + + # specify security per task... + if ( ref $action_security eq 'HASH' ) { + $required_level = $action_security->{ $task } || + $action_security->{DEFAULT} || + $action_security->{default}; + } + + # specify security for entire action... + else { + $required_level = $action_security; + } + + unless ( defined $required_level ) { + $log->is_info && + $log->info( "Assigned security level WRITE to task ", + "'$task' since no security requirement found" ); + $required_level = SEC_LEVEL_WRITE; + } + return $required_level; + } ######################################## *************** *** 717,720 **** --- 744,751 ---- return; } + + # do not cache admin requests + return undef if ( CTX->request->auth_is_admin ); + my $expire_time = $expire->{ $self->task } || $expire->{ CACHE_ALL_KEY() } || ''; $log->is_debug && *************** *** 940,943 **** --- 971,1016 ---- + sub url_additional_param { + my ( $self ) = @_; + my @url_params = $self->_get_url_additional_names; + return unless ( scalar @url_params ); + unless ( $self->{_url_additional_assigned} ) { + $self->url_additional_param_from_request; + } + my @values = (); + foreach my $param_name ( @url_params ) { + push @values, $self->param( $param_name ); + } + return @values; + } + + sub url_additional_unassigned { + my ( $self ) = @_; + my @url_params = $self->_get_url_additional_names; + my $request = CTX->request; + return unless ( $request ); + + } + + sub url_additional_param_from_request { + my ( $self ) = @_; + return if ( $self->{_url_additional_assigned} ); + my @url_params = $self->_get_url_additional_names; + return unless ( scalar @url_params ); + my $request = CTX->request; + return unless ( $request ); + + my @url_values = $request->param_url_additional; + my $param_count = 0; + foreach my $value ( @url_values ) { + next unless ( $url_params[ $param_count ] ); + $self->param( $url_params[ $param_count ], $value ); + $param_count++; + } + $self->{_url_additional_assigned}++; + return @url_values; + } + + # shortcuts... *************** *** 2211,2216 **** } ! (Note: you will never need to do this since the ! C<_find_security_level()> method does this (and more) for you.) B<security_level> ($) --- 2284,2291 ---- } ! NOTE: you will never need to do this since the ! C<_find_security_level()> method does this (and more) for you; you can ! also use the public C<task_security_allowed( $some_task )> to whether ! the current user/group can execute C<$some_task> in this action. B<security_level> ($) *************** *** 2491,2494 **** --- 2566,2590 ---- } + C<task_security_allowed( $task_to_check )> + + Returns true or false depending on whether the current user/group is + allowed to execute the task C<$task_to_check> on this action. This is + very useful to be able to display conditional links based on a user's + capabilities. For instance, if I wanted to display an 'Edit me' link + depending on whether a user had the ability to execute the 'edit' task + within my action, I could do: + + [% IF ACTION.task_security_allowed( 'edit' ) %] + <a href="...">Edit me</a> + [% END %] + + Will throw an exception if not given C<$task_to_check>. + + If you need the security level of the current user/group for this + action, just look in the property C<security_level>. + + Returns: true if current user/group can execute C<$task_to_check>, + false if not + =head2 Object Execution Methods |