Skip site navigation (1)Skip section navigation (2)

FreeBSD Manual Pages


home | help
SPOPS::Secure(3)      User Contributed Perl Documentation     SPOPS::Secure(3)

       SPOPS::Secure - Implement security across one or	more classes of	SPOPS

	# In the configuration for your	object,	add security to	objects
	# created by this class:

	$spops = {
	  myobject => {
	       class =>	'My::Object',
	       isa   =>	[ qw/ SPOPS::Secure SPOPS::DBI / ],

       By adding this module into the 'isa' configuration key for your SPOPS
       class, you implement a mostly transparent per-object security system.
       This security system relies on a	few things being implemented:

       o   A SPOPS class implementing users

       o   A SPOPS class implementing groups

       o   A SPOPS class implementing security objects

       Easy, eh? Fortunately, SPOPS comes with all three, although you are
       free to modify them as you see fit. (As of version 0.42,	see the
       'eg/My' directory in the	source distribution for	the sample classes.)

       Most people interested in security should not be	reading	the docs for
       this class. Instead, look at SPOPS::Manual::Security which offers a
       broad view of security as well as how to	use, implement and extend it.

       The methods that	this class implements can be used by any SPOPS class.
       The variable $item below	refers to the fact that	you can	either do an
       object method call or a class method call. If you do a class method
       call, you must pass in the ID of	the object for which you want to get
       or set security.

       However,	you may	also implement security	on the class level as well.
       For instance, if	your application uses classes to implement modules
       within an application, you might	wish to	restrict the module by
       security	very similar to	the security implemented for individual
       objects.	In this	case, you would	have a class name and no object	ID
       ($object_id) value. (See	SPOPS::Manual::Security	for more information.)

   check_security( [ \%params ]	)
       The method check_security() returns a code corresponding	to the LEVEL
       constants exported from this package. This code tells you what
       permissions the logged in (or passed in)	user has. You can pass user
       and group parameters to check security for other	items as well.

       Note that you can check security	for multiple groups but	only one user
       at a time. Passing an arrayref of user objects for the 'user' parameter
       will result in the first	user object being checked and the remainder
       discarded. This is probably not what you	want.


	# Find the permission for the currently	logged-in user for $item

	# Get the security for this $item for a	particuar
	# user;	note that this *does* find the groups this
	# user belongs to and checks those as well

	$item->check_security({	user =>	$user });

	# Find the security for	this item for either of	the
	# groups specified

	$item->check_security({	group => [ $group, $group ] });

   get_security( [ \%params ] )
       Returns a hashref of security information about the particular class or
       object. The keys	of the hashref are the constants, SEC_SCOPE_WORLD,
       SEC_SCOPE_GROUP and SEC_SCOPE_USER. The value corresponding to the
       SEC_SCOPE_WORLD key is simply the WORLD permission for the object or
       class. Similarly, the value of SEC_SCOPE_USER is	the permission for the
       user specified. The SEC_SCOPE_GROUP key has as its value	a hashref with
       the IDs of the group as keys. (Examples below)

       Note that if the	user specified does not	have permissions for the
       class/object, then its entry is blank.

       The parameters correspond to check_security. The	default	is to retrieve
       the security for	the currently logged-in	user and groups	(plus WORLD),
       but you can restrict the	output if necessary.

       Note that the WORLD key is always set, no matter	how much you restrict
       the user/groups.

       Finally:	this will not be on the	test, since you	will probably not need
       to use this very	often unless you are subclassing this class to create
       your own	custom security	checks.	The "check_security()" and
       "set_security()"	methods	are likely the only interfaces you need	with
       security	whether	it be object or	class-based. The "get_security()"
       method is used primarily	for internal purposes, but you might also need
       it if you are writing security administration tools.


	# Return a hashref using the currently logged-in
	# user and the groups the user belongs to
	# Sample of what $perm looks like:
	# $perm	= { 'u'	=> 4, 'w' => 1,	'g' => { 5162 => 4, 7182 => 8 }	};
	# Which	means that the user has	a permission of	SEC_LEVEL_READ,
	# the user belongs to two groups with IDs 5162 and 7182	which have
	# permissions of READ and WRITE, respectively, and the WORLD
	# permission is	NONE.
	my $perm = $item->get_security();

	# Find the security for	a particular user object and its groups
	my $perm = $item->get_security({ user => $that_user });

	# Find the security for	two groups, no user objects.
	my $perm = $item->get_security({ group => [ $group1, $group2 ] });

   get_security_scopes(	\%params )
       Called by get_security()	to determine which user	object and which group
       objects to use to check security	on an object.

       Returns:	two-item list, the first is the	$user object and the second is
       an arrayref of $group objects.

   set_security( \%params )
       The method set_security() returns a status as to	whether	the permission
       has been	set to what you	requested.

       The default is to operate on one	item at	a time,	but you	can specify
       many items at once with the 'multiple' parameter.


	# Set $item security for WORLD to READ

	my $wrv	=  $item->set_security({ scope => SEC_SCOPE_WORLD,
					 level => SEC_LEVEL_READ });
	unless ( $wrv )	{
	  # error! security not	set properly

	# Set $item security for GROUP $group to WRITE

	my $grv	=  $item->set_security({ scope => SEC_SCOPE_GROUP,
					 scope_id => $group->id,
					 level => SEC_LEVEL_WRITE });
	unless ( $grv )	{
	  # error! security not	set properly

	# Set $item security for USER objects whose IDs	are the	keys in	the
	# hash %multiple and whose values are the levels corresponding to the
	# ID.
	# (Note	that this is a contrived example for setting up	the %multiple
	# hash - you should always do some sort	of validation/checking before
	# passing user-specified information to	a method.)

	my %multiple = (
	 $user1->id => $cgi->param( 'level_' . $user1->id ),
	 $user2->id => $cgi->param( 'level_' . $user2->id )
	my $rv = $item->set_security({ scope =>	SEC_SCOPE_USER,
				       level =>	\%multiple });
	if ( $rv != scalar keys	%multiple ) {
	  # error! security not	set properly for all items

	# Set $item security for multiple scopes whose values
	# are in the hash %multiple; note that the hash	%multiple
	# has a	separate layer now since we're specifying multiple
	# scopes within	it.

	my %multiple = (
	    $user1->id => $cgi->param( 'level_'	. $user1->id ),
	    $user2->id => $cgi->param( 'level_'	. $user2->id ),
	    $group1->id	 => $cgi->param( 'level_group_'	. $group1->id ),
	my $rv = $item->set_security({ scope =>	[ SEC_SCOPE_USER, SEC_SCOPE_GROUP ],
				       level =>	\%multiple });

   create_initial_security( \%params )
       Creates the security for	a newly	created	object.	Generally this entails
       looking at the "creation_security" key of an object configuration and
       mapping the permissions there to	the object.


       o   class: Specify the class you	want to	use to create the initial

       o   object_id: Specify the object ID you	want to	use to create the
	   initial security.

       A handful of methods enable SPOPS to implement superuser/group
       checking. A superuser is	a user who can perform any action, and a
       member of the supergroup	can do the same.

       If your class does not use the supergroup, just setup a function:

	sub is_supergroup { return undef }

       _check_superuser( $user_object, \@group_object )

       Checks whether the given	user and group listing has superuser status.
       Returns a hashref suitable for passing to "check_security()".

       NOTE: We	may rename this	to "check_superuser()" in the future.

       is_superuser( $user_id )

       Returns true if $user_id	is the superuser, false	if not.	Default	is for
       the value 1 to be the superuser ID, but subclasses can easily override.

       is_supergroup( @group_id	)

       Returns true if one of @group_id	is the supergroup, false if not.
       Default is for the value	1 to be	the supergroup ID, but subclasses can
       easily override.

       This module exports nothing by default. You can import specific tags
       that refer to the scope and level, or you can import groups of them.

       Note that you should always use these tags. They	may seem unwieldly,
       but they	make your program easier to read and allow us to modify	the
       values for these	behind the scenes without you modifying	any of your
       code. If	you use	the values directly, you will get what is coming to

       You can import individual tags like this:

	use SPOPS::Secure qw( SEC_SCOPE_WORLD );

       Or you can import the tags in groups like this:

	use SPOPS::Secure qw( :scope );

       Scope Tags

       o   SEC_SCOPE_WORLD

       o   SEC_SCOPE_GROUP

       o   SEC_SCOPE_USER

       Level Tags

       o   SEC_LEVEL_NONE


       o   SEC_LEVEL_READ

       o   SEC_LEVEL_WRITE

       Verbose Level Tags

       These tags return a text	value for the different	security levels.

       o   SEC_LEVEL_VERBOSE_NONE (returns 'NONE')


       o   SEC_LEVEL_VERBOSE_READ (returns 'READ')

       o   SEC_LEVEL_VERBOSE_WRITE (returns 'WRITE')

       Groups of Tags

       o   scope: brings in all	SEC_SCOPE tags

       o   level: brings in all	SEC_LEVEL tags

       o   verbose: brings in all SEC_LEVEL_VERBOSE tags

       o   all:	brings in all tags

       Refactor	create_initial_security()

       This method is too long and confusing --	break it into pieces.

       Sort out	the different set_* methods

       The different set_* methods are currently quite confusing.

       Add caching

       Gotta gotta gotta get a caching interface done, where we	simply say:

	$object->cache_security_level( $user );

       And cache the security level for	that object for	that user. **Any**
       security	modifications to that object wipe out the cache	for that

       None known, besides girth.

       Copyright (c) 2001-2004, inc..	All rights reserved.

       This library is free software; you can redistribute it and/or modify it
       under the same terms as Perl itself.

       Chris Winters  <>

perl v5.32.0			  2004-06-02		      SPOPS::Secure(3)


Want to link to this manual page? Use this URL:

home | help