Skip to content

Commit

Permalink
Merge pull request #31 from phpcr/cleanup-phpcr-security
Browse files Browse the repository at this point in the history
add PrincipalInterface and cleanup docs
  • Loading branch information
dbu committed Jul 25, 2012
2 parents 72388ef + 87009cd commit d9ff4b3
Show file tree
Hide file tree
Showing 8 changed files with 145 additions and 66 deletions.
40 changes: 27 additions & 13 deletions doc/JCR_TO_PHPCR.txt
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ Basic conversion
****************

Most PHP coding standards require that interfaces have the Interface in their
name. We followed this, thus Node becomes NodeInterface and so on.
name. This has been followed, thus Node becomes NodeInterface and so on.

PHP does not allow method overloading (having the same method name with
different parameter numbers and/or types). PHP uses optional parameters with
Expand All @@ -38,8 +38,8 @@ The implementing visitor will have to do a type-check.
* In PHP you can not have a class method called "clone" because it is a
reserved keyword. Workspace::clone is named Workspace::cloneFrom as it clones
a node from a workspace into the current workspace.
* For java.io.InputStream we use PHP streams (resources). For java.util.Calendar
we use the DateTime class. For the java.math.BigDecimal, we use strings that
* For java.io.InputStream PHP streams (resources) are used. For java.util.Calendar
we use the DateTime class. For the java.math.BigDecimal, strings are used that
can be used with the bcmath PHP extension.

For some notes about value conversion, see the Value section below.
Expand All @@ -60,7 +60,7 @@ since Java 1.5.)

Wherever the iterators are used, PHPCR requires iterators implementing
SeekableIterator and Countable. Together, those iterators have the same
expressivnes as the JCR RangeIterator.
expressiveness as the JCR RangeIterator.

Note: Plain PHP arrays would be even simpler than any interfaces, while still
allowing to use foreach. But they would have the major drawback that no lazy
Expand All @@ -70,7 +70,7 @@ ArrayIterator from the array. Client code must not forget however that the API
does *not* require the ArrayAccess interface with random access by key.


Additionally, we declared API elements as Traversable where it makes sense.
Additionally, API elements have been declared as Traversable where it makes sense.
This allows to directly use the objects in a foreach statement.
The implementation either has to implement IteratorAggregate::getIterator to
return a suitable iterator, or be an iterator itselves.
Expand Down Expand Up @@ -104,7 +104,7 @@ Do NOT put 'implements Traversable' into the class signature, it confuses PHP.
* Security/AccessControlListInterface iterates over all entries, like
getAccessControlEntries(). The iterator keys have no significant meaning.

For other interfaces, there is no obvious default iterator, so we left them without.
For other interfaces, there is no obvious default iterator, so they are left without.
Version/VersionHistoryInterface extends the NodeInterface. Even though iterating
over the versions seems natural, we did not want to change the behaviour for
this subclass of NodeInterface.
Expand All @@ -117,7 +117,7 @@ PHPCR got rid of both Value and ValueFactory. They only make sense in the
context of strong typing.

The PropertyInterface methods directly access the native property values.
We keep type conversions possible with the type-specific getters.
Type conversions are still possible with the type-specific getters.

* PropertyInterface::getValue returns the value in its default format,
dereferencing (WEAK)REFERENCES but not PATH properties.
Expand Down Expand Up @@ -174,8 +174,8 @@ dereference reference properties for this array.
For performance reason, implementations should delay instantiating the
PropertyInterface objects until they are actually needed.

We dropped the getValues and getLengths methods for *multivalue properties* in
favor of returning either a single value or an array of values in the same
The getValues and getLengths methods for *multivalue properties* where dropped
in favor of returning either a single value or an array of values in the same
method.

PropertyInterface::addValue() has been added to quickly append a value to
Expand Down Expand Up @@ -282,7 +282,20 @@ backend (if the session is not yet in a transaction).
Locking
*******

For no timeout, instead of java Long.MAX_VALUE PHP_MAX_INT is used.
This works exactly as with JCR. For no timeout, instead of the java
Long.MAX_VALUE the PHP constant PHP_MAX_INT is used.


Security
********

JCR provides an ACL model built on top of the java.security.Principal
interface. The interfaces have been ported to PHPCR, and a PrincipalInterface
similar to the Java one had to be added to PHPCR as well, as there is no
equivalent in PHP.

This chapter has not been implemented yet and might still need to be adjusted
to fit PHP.


Drawing the line
Expand Down Expand Up @@ -310,9 +323,9 @@ At the time of this writing, some JCR features have not been implemented in any
PHPCR implementation. In those areas, changes are more likely to happen, once
implementation starts and people figure out what needs to be done. Those areas
are:
* Lock
* Observation
* Retention

* Observation (partially)
* Retention and Hold
* Security


Expand All @@ -336,3 +349,4 @@ Contributors:
* Henri Bergius <henri.bergius (at) iki.fi>
* Jordi Boggiano <j.boggiano (at) seld.be>
* Christian Stocker <chregu (at) liip.ch>
* And others: https://github.com/phpcr/phpcr/graphs/contributors
14 changes: 6 additions & 8 deletions src/PHPCR/Security/AccessControlEntryInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,13 @@
namespace PHPCR\Security;

/**
* An AccessControlEntry represents the association of one or more Privilege
* objects with a specific Principal.
* An AccessControlEntryInterface represents the association of one or more
* PrivilegeInterface objects with a specific principal.
*
* The \Traversable interface enables the implementation to be addressed with
* <b>foreach</b>. AccessControlEntry has to implement either \RecursiveIterator
* or \Iterator.
* The iterator is equivalent to <b>getPrivileges()</b> returning a list of
* <b>foreach</b>. Concrete AccessControlEntry have to implement either
* \RecursiveIterator or \Iterator.
* The iterator is equivalent to <b>getPrivileges()</b>, returning a list of
* PrivilegeInterface. The iterator keys have no significant meaning.
*
* @package phpcr
Expand All @@ -43,9 +43,7 @@ interface AccessControlEntryInterface extends \Traversable
/**
* Returns the principal associated with this access control entry.
*
* @return java.security.Principal a Principal.
*
* @todo find replacement for java.security.Principal
* @return PrincipalInterface
*
* @api
*/
Expand Down
2 changes: 1 addition & 1 deletion src/PHPCR/Security/AccessControlException.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
* Exception thrown by access control related methods of AccessControlManager.
*
* @package phpcr
* @subpackage interfaces
* @subpackage exceptions
* @api
*/
class AccessControlException extends \PHPCR\RepositoryException
Expand Down
38 changes: 18 additions & 20 deletions src/PHPCR/Security/AccessControlListInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,18 +25,19 @@
namespace PHPCR\Security;

/**
* The AccessControlList is an AccessControlPolicy representing a list of
* access control entries.
* The AccessControlListInterface is an AccessControlPolicyInterface
* representing a list of access control entries.
*
* It is mutable before being set to the AccessControlManager and consequently
* defines methods to read and mutate the list i.e. to get, add or remove
* individual entries.
* It is mutable before being set to the AccessControlManagerInterface and
* consequently defines methods to read and mutate the list i.e. to get, add or
* remove individual AccessControlEntryInterface instances.
*
* The \Traversable interface enables the implementation to be addressed with
* <b>foreach</b>. AccessControlList has to implement either \RecursiveIterator
* or \Iterator.
* The iterator is equivalent to <b>getAccessControlEntries()</b> returning a
* list of AccessControlEntry. The iterator keys have no significant meaning.
* The iterator is equivalent to <b>getAccessControlEntries()</b> returning
* AccessControlEntryInterface instances. The iterator keys have no significant
* meaning.
*
* @package phpcr
* @subpackage interfaces
Expand All @@ -45,14 +46,12 @@
interface AccessControlListInterface extends \PHPCR\Security\AccessControlPolicyInterface, \Traversable
{
/**
* Gets every registered access control entry.
*
* Returns all access control entries present with this policy.
* This method is only guaranteed to return an AccessControlEntry if that
* AccessControlEntry has been assigned through this API.
*
* @return array Lis of all AccessControlEntry objects present with this
* policy.
* This method is only guaranteed to return an access control entry object
* if that access control entry object has been assigned through this API.
*
* @return array all AccessControlEntry objects present with this policy.
*
* @throws \PHPCR\RepositoryException - if an error occurs.
*
Expand All @@ -74,10 +73,11 @@ function getAccessControlEntries();
* Principal can never remove a Privilege added by a previous call.
*
* The modification does not take effect until this policy has been set to
* a node by calling AccessControlManagerInterface::setPolicy() and save is
* performed.
* a node by calling AccessControlManagerInterface::setPolicy() and
* Session::save is performed.
*
* @param ? $principal - a Principal. TODO: define a type for this. JCR has javax.security.Principal
* @param PrincipalInterface $principal the entity that should have this
* privilege
* @param array $privileges - an array of Privileges.
*
* @return boolean true if this policy was modify; false otherwise.
Expand All @@ -87,18 +87,16 @@ function getAccessControlEntries();
* access control related exception occurs.
* @throws \PHPCR\RepositoryException - if another error occurs.
*
* @todo find replacement for java.security.Principal
*
* @api
*/
function addAccessControlEntry($principal, array $privileges);
function addAccessControlEntry(PrincipalInterface $principal, array $privileges);

/**
* Removes the specified access control entry object from this policy.
*
* Only exactly those entries obtained through getAccessControlEntries can
* be removed. This method does not take effect until this policy has been
* re-set to a node by calling AccessControlManagerInterface::setPolicy()
* re-assigned to a node by calling AccessControlManagerInterface::setPolicy()
* and save is performed.
*
* @param \PHPCR\Security\AccessControlEntryInterface $ace the access
Expand Down
31 changes: 17 additions & 14 deletions src/PHPCR/Security/AccessControlManagerInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ function privilegeFromName($privilegeName);
* the set returned by calling PrivilegeInterface::getAggregatePrivileges()
* for that privilege.
*
* The results reported by the this method reflect the net effect of the
* The results reported by this method reflect the net effect of the
* currently applied control mechanisms. It does not reflect unsaved access
* control policies or unsaved access control entries. Changes to access
* control status caused by these mechanisms only take effect on
Expand Down Expand Up @@ -195,7 +195,7 @@ function getEffectivePolicies($absPath);
* @param string $absPath The absolute path to the node of which privileges
* are requested.
*
* @return Iterator over the applicable access control policies
* @return \Iterator over the applicable access control policies
* implementing <b>SeekableIterator</b> and <b>Countable</b>. Values
* are the AccessControlPolicyInterface instances. Keys have no
* meaning. Returns an empty iterator if no policies are applicable.
Expand All @@ -214,18 +214,20 @@ function getApplicablePolicies($absPath);
/**
* Binds the policy to the node at absPath.
*
* The behavior of the call $acm->setPolicy($absPath, $policy) differs
* The behavior of AccessControlManagerInterface::setPolicy() differs
* depending on how the policy object was originally acquired.
*
* If policy was acquired through $acm->getApplicablePolicies($absPath)
* then that policy object is added to the node at absPath.
* If the policy was acquired through
* AccessControlManagerInterface::getApplicablePolicies() then that policy
* object is added to the node at absPath.
*
* On the other hand, if <code>$policy</code> was acquired through
* $acm->getPolicies(absPath) then that policy object (usually after being
* altered) replaces its former version on the node at $absPath.
* On the other hand, if the policy was acquired through
* AccessControlManagerInterface::getPolicies() then that policy object
* (usually after being altered) replaces its former version on the node at
* $absPath.
*
* This is session-write method and therefore the access control policy
* is only dispatched on <code>save()</code> and will only take effect upon
* This is a session-write method and therefore the access control policy
* is only dispatched on Session::save() and will only take effect upon
* persist.
*
* @param string $absPath The absolute path to the node of which privileges
Expand Down Expand Up @@ -255,12 +257,12 @@ function getApplicablePolicies($absPath);
function setPolicy($absPath, \PHPCR\Security\AccessControlPolicyInterface $policy);

/**
* Removes the specified AccessControlPolicy from the node at $absPath.
* Removes the specified AccessControlPolicyInterface from the node at $absPath.
*
* An AccessControlPolicy can only be removed if it was bound to the
* An AccessControlPolicyInterface can only be removed if it was bound to the
* specified node through this API before. The effect of the removal only
* takes place upon SessionInterface::save(). Note, that an implementation
* default or any other effective AccessControlPolicy that has not been
* default or any other effective AccessControlPolicyInterface that has not been
* applied to the node before may never be removed using this method.
*
* @param string $absPath The absolute path to the node of which privileges
Expand All @@ -273,7 +275,8 @@ function setPolicy($absPath, \PHPCR\Security\AccessControlPolicyInterface $polic
* @throws \PHPCR\PathNotFoundException if no node at absPath exists or the
* session does not have sufficent access to retrieve a node at that
* location.
* @throws \PHPCR\Security\AccessControlException if no policy exists.
* @throws \PHPCR\Security\AccessControlException if the policy to remove
* does not exist at the node at absPath.
* @throws \PHPCR\AccessDeniedException if the session lacks
* MODIFY_ACCESS_CONTROL privilege for the absPath node.
* @throws \PHPCR\Lock\LockException if a lock applies at the node at
Expand Down
8 changes: 4 additions & 4 deletions src/PHPCR/Security/AccessControlPolicyInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,11 @@
namespace PHPCR\Security;

/**
* The AccessControlPolicy is a marker interface for all kind of access control
* policies. This API defines two subinterfaces:
* The AccessControlPolicyInterface is a marker interface for all kind of
* access control policies. This API defines two subinterfaces:
*
* - NamedAccessControlPolicy
* - AccessControlList
* - NamedAccessControlPolicyInterface
* - AccessControlListInterface
*
* @package phpcr
* @subpackage interfaces
Expand Down
72 changes: 72 additions & 0 deletions src/PHPCR/Security/PrincipalInterface.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
<?php

/**
* This file is part of the PHPCR API
*
* This file in particular is derived from the Principal interface
* of the package java.security. For more information about the Java
* interface have a look at
* http://docs.oracle.com/javase/6/docs/api/index.html?java/security/Principal.html
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* @license http://www.apache.org/licenses/LICENSE-2.0 Apache Software License 2.0
* @link http://phpcr.github.com/
*/

namespace PHPCR\Security;

/**
* As there are no ACL standard interfaces in PHP this interface provides the
* Principal interface similar to the java.security.Principal
*
* The Principal is any entity that can be assigned privileges. E.g. a person,
* a role, a computer.
*
* The reason to have this interface is that the PHPCR implementation needs to
* store the principals and use them on later requests.
*/
interface PrincipalInterface
{
/**
* Compares this principal to the passed object. Returns true if both this
* principal and the passed object match the same thing.
*
* This is necessary, as the same hashCode does not guarantee equality, and
* the === operator is too strict, as there could be two instances of the
* same principal.
*
* @param mixed $object
*
* @return boolean true if the principal passed to the method is the same
* as this object
*/
function equals($object);

/**
* The hash code must be the same for the same principal.
*
* However it should be unique inside your application for different
* principals.
*
* @return int a hashcode for this principal.
*/
function hashCode();

/**
* Returns the name of this principal.
*
* @return string name of this principal
*/
function getName();
}

0 comments on commit d9ff4b3

Please sign in to comment.