Пример #1
0
        /// <summary>
        /// Treats this object as an action question and matches it against the list of
        /// permissions given as a parameter.
        /// </summary>
        /// <remarks>This may throw if things aren't right (permissions attribute isn't Perm[], etc)</remarks>
        /// <returns>True if it's allowed.</returns>
        public bool check( Mob target )
        {
            // Make sure we have everything we need for a proper question.
            if( (this.perms & PermBits.Verb) || (this.perms & PermBits.Attr) )
            if( String.IsNullOrEmpty( this.specific ) )
                throw new ArgumentException( "Permission question has verb or attribute, but no specific name." );
            if( this.perms == 0 )
            throw new ArgumentException( "Permission question has no bits set." );
            if( (this.perms.mask & (this.perms.mask - 1)) != 0 )
            throw new ArgumentException( "Permission question has more than one bit." );
            if( this.perms & PermBits.AO )
            throw new ArgumentException( "Permission question can't specify AO." );
            // Post-condition: We have a proper single bit permission question with a specific if appropriate.

            // Team members can do anything they please. The find may fail here if it's an anonymous player.
            Mob actor = target.world.findObject( this.actorId );
            if( actor != null && actor.teamMember )
            return true;

            // If we're editing the permissions attribute itself, only team members can do that.
            if( (this.perms & PermBits.AW) && this.specific == Mob.Attributes.Permissions )
            return false;

            // Get the permissions assertions, starting with the specific target mob and working up the inheritance chain.
            var permissions = new List<KeyValuePair<Mob, Perm[]>>();
            for( Mob m = target; m != null; m = m.parent )
            {
            var permattr = m.attrGet( Mob.Attributes.Permissions );
            if( permattr != null )
            {
                Perm[] tp;
                object tpcontents = permattr.contents;
                if( tpcontents is object[] )
                    tp = ((object[])tpcontents).Select( p => (Perm)p ).ToArray();
                else
                    tp = (Perm[])permattr.contents;
                permissions.Add( new KeyValuePair<Mob, Perm[]>( m, tp ) );
            }
            }

            // Are we dealing with an attribute? If so, look for a sticky bit starting at the bottom.
            if( this.perms & PermBits.Attr )
            {
            // This is not so efficient, but it should be okay for the small numbers we're working with.
            for( int i = permissions.Count - 1; i > 0; --i )
            {
                var kvp = permissions[i];
                if( kvp.Value.Any( (p) => p.specific == this.specific && p.perms & PermBits.AO ) )
                {
                    // We really want to do this check with this other object's permissions.
                    return check( kvp.Key );
                }
            }
            }

            // If it's not an AO attribute, then the owner is allowed to do anything.
            if( target.ownerId == this.actorId )
            return true;

            // Find all the mob IDs in the inheritance chain for this question's actor ID. We
            // stop before #1 because it probably has all sorts of powers.
            var actors = new List<int>();
            if( this.actorId == 1 )
            actors.Add( 1 );
            else if( actor == null )
            {
            // This can come about from anonymous users.
            actors.Add( this.actorId );
            }
            else
            {
            for( Mob m = actor; m != null && m.id != 1; m = m.parent )
                actors.Add( m.id );
            }

            // If we find nothing, we have to fall back to looking for an "opaque" attribute
            // to determine what the base permissions are. So we'll just do that now and tack the defaults
            // onto the end.
            if( target.findAttribute( Mob.Attributes.Opaque ) == null )
            {
            // Not opaque: give a set of default permissions that lets people read most of it.
            var clearPerms = new Perm[]
            {
                new Perm()
                {
                    actorId = Mob.Any.id,
                    perms = PermBits.AR | PermBits.OR | PermBits.OF | PermBits.VR,
                    specific = null
                }
            };
            permissions.Add( new KeyValuePair<Mob,Perm[]>( target, clearPerms ) );
            }

            // Go through until we find a permission that matches what we're looking for.
            foreach( var kvp in permissions )
            {
            foreach( var p in kvp.Value )
            {
                // This permission applies if:
                // - The actor is Any, and the caller is not Anon. (Permissions must be granted to Anon.)
                // - The actor is a set value, and that value is in the caller's inheritance chain.
                if( (this.actorId != Mob.Anon.id && p.actorId == Mob.Any.id) || actors.Any( a => a == p.actorId ) )
                {
                    // Make sure we're talking about the same subject.
                    if( matches( p ) )
                        return p.type == Type.Allow;
                }
            }
            }

            // Didn't find anything: denied.
            return false;
        }
Пример #2
0
 /// <summary>
 /// Treats us as an action and matches us against the specified permission.
 /// Returns true if the permission matches.
 /// </summary>
 public bool matches( Perm other )
 {
     // Specifics might be null, but they must still match. Any bits that are shared
     // make the permission relevant.
     return (this.perms & other.perms)
     && (string.IsNullOrEmpty( other.specific ) || this.specific == other.specific);
 }
Пример #3
0
        public void Permissions()
        {
            createBasicWorld();

            // Make a chain to test inheritance.
            _testObj.permissions = new Perm[]
            {
            new Perm()
            {
                actorId = _player.id,
                type = Perm.Type.Allow,
                perms = PermBits.AW,
                specific = "test"
            },
            new Perm()
            {
                actorId = Mob.Any.id,
                type = Perm.Type.Deny,
                perms = PermBits.VW,
                specific = null
            },
            new Perm()
            {
                actorId = 1,
                type = Perm.Type.Allow,
                perms = PermBits.AO | PermBits.AW,
                specific = "test2"
            }
            };
            _testObj.ownerId = _god.id;
            _testObj.attrSet( "test", "test" );
            _testObj.attrSet( "test2", "test" );

            var test2 = Mob.Wrap( _sw.createObject() );
            test2.ownerId = _god.id;
            test2.parentId = _testObj.id;
            test2.locationId = _god.id;
            test2.permissions = new Perm[]
            {
            new Perm()
            {
                actorId = _player.id,
                type = Perm.Type.Deny,
                perms = PermBits.AW,
                specific = "test"
            },
            new Perm()					// This is invalid
            {
                actorId = _player.id,
                type = Perm.Type.Allow,
                perms = PermBits.AW,
                specific = "test2"
            }
            };
            test2.ownerId = _testObj.id;

            var test3 = Mob.Wrap( _sw.createObject() );
            test3.parentId = test2.id;
            test3.locationId = _god.id;
            test3.ownerId = _player.id;

            // Now try some questions against it all.
            Perm q = new Perm()
            {
            actorId = _player.id,
            perms = PermBits.VW,
            specific = "bob"
            };
            bool success = q.check( test2 );
            Assert.IsFalse( success );

            success = q.check( test3 );
            Assert.IsTrue( success );

            q = new Perm()
            {
            actorId = _player.id,
            perms = PermBits.AW,
            specific = "test2"
            };
            success = q.check( test3 );
            Assert.IsFalse( success );
        }