GM-Alex / user-access-manager

Official mirror of https://plugins.svn.wordpress.org/user-access-manager/
39 stars 18 forks source link

UAM groups and visitors rights, and compatibility with plugin nav-menu-roles #17

Open Trebly opened 7 years ago

Trebly commented 7 years ago

Hi,

A particularity of “visitor” is that the alone way to hide for him, some content, is to not publish this content (if the visibility is not limited to others)

In one way it is a paradox, the visibility of a published post (or others contents) can be perfectly managed with UAM but only if the user is logged in (user registered attached to a group of users).

With UAM you can choose who have to view (or others rights) on documents if they are logged in, but any not logged in (visitor) will see any published document.

The important consequence is that it is impossible for admin, author, reviewers to see their article into the whole context of the site (list in category, keywords, search etc..) as could see a visitor (a not logged user) until the post or page has not been published.

Then for admin or author to discover that there are errors into category associations, keywords, menu accesses, search process etc… it must be visible by anybody before… (so, a little late).

A partial deal, a workaround, with this problem, is to create with UAM a “lowest group” which has no more than the visitor rights. But this doesn’t functions always because to view contents as a visitor this particular user has to be logged in, here is the paradox. Because there are many others system behavior which are changed uniquely by the loggin status… This has many effects and sometimes this workaround is not at all usable.

Case of Incompatibility with “nav-menu-roles” Because of the way to define the user rights combined with logged in, and menu selections the conjoined use of “UAM” and “nav-menu-roles” leads to exclude for visitors elements of menu and destroy his structure (I could explain in details the logical process which leads to this, but it is a little long).

Solution : The solution is to use UAM with a little enhancement (need 6 lines of code) : – when the user has a num id = 0 (a visitor) the visibility depends of a pseudo and permanent group “UAM-visitor”. With this feature if a post is not associated to the group “UAM-visitor” it will not be visible by visitors. Then you can hide or show a post for visitor with just a click, which is, any way, completely impossible without this enhancement. (note : the enhancement includes the automatically add of this pseudo group).

Do somebody or the author interested in this enhancement. Best regards

Trebly


note 1: for now, each time a new version is published I have to update it with this enhancement, which is a little bothering


note 2: Since first writing I imagine how could behave UAM with a group defined with no user group attached and rights open in reading. Normally to attach a document to this group would say : doesn't concern anybody except admin which is allowed for all. It should be a "null" operator of selection ?


note 3 : I had to draw the "object model" of UAM

For several instances of this model I had to draw the way for menu and documents to become accessible or not by a defined user (read and right)


note 4 - The result (of point 3) is that UAM groups seems more "documents groups" than any concept around user groups : groups of documents which can be read or/and edited by several users groups then UAM groups best name seems to be User Access Manager to objects by groups ... define a group

evielutions commented 7 years ago

Hi,

I think I'm having the same issue as I'm using a conditional menu plugin. When UAM is activated the visitor gets broken links, navigation does not work properly when deactivated everything works fine. @Trebly what are the 6 lines of code you added and where was it added to prevent this? Thanks in advance!

Trebly commented 7 years ago

Hi,

Sorry to answer only now, I was not connected for last four days.

Here are the changes that I have performed into UAM.

Before all, I must tell that the purpose of this patch is to be able to declare explicitly the association of a group to a user named "uam-visitor" (or any string constant defined into php for user-visitor - todo) using capabilites defined for the "visitors". The main difference of this added feature is that, versus current WP behavior, when you associate an object to a group (see later) a visitor will not get default capabilites but those defined for a role "uam-visitor" (read a document for example) even for a published object (in WP by default a visitor can read any published document). An "uam-visitor" must be defined into roles list. Note that if his rights are exactly the same as for current visitor definition, UAM wihtout this patch can have the same result using a group defined with no user attached. This is an effect of (what I consider as a contradiction) "no user attached to the group" means 'visitor' - because currently a visitor is a 'no-user' " and by default any published document is visible by visitors. But if you want that a visitor has not the same capabilities as for default visitor of WP (cannot read all, or have not access to all categories etc.), even for a published object, you must choose the patch. Then you will be able to define the "uam-visitor" capabilites and attach any of documents, that can be seen by a visitor, to the group defined in particular for uam-visitor with clause "read only by".

Then a visitor will have for actions filtered by UAM, only the capabilities defined for "uam-visitor" (for example see only the documents and other object managed by UAM) for object for which this group is checked and no others at all.

To install the feature:

A - Because the patch need a "wp_role" "uam-visitor" we create it if you have not created it manually (if not you will crash) Patch 1 : Add role "uam-visitor" : can be done simply manually. This patch is here only for memory : It is a security but no ended : then it can crash if current user is not admin when soft is run. in user-access-manager.php add near line 380 :

        $oCurUserData = wp_get_current_user();
// before
        $oUamAccessHandler = $oUserAccessManager->getAccessHandler();
// and at the end of block <if (isset($oUserAccessManager)) {>
    /**
     * Set of UAM-visitor - Added by Trebly:b60827 (previously tested 01/2016)
     * If a UAM-visitor role doesn't exist it is created : it should exist if the admin as set permanent uam user-user-group
     * using the uam-visitor role which can have particular capabilities.
     * Here the dynamically set allows coherency with assignation
     * of the uam-visitor role to any not logged-in user
     */
    // ###trebly:b60119:hold user simply logged in as visitor role
    if (function_exists('add_role')) {
       // global $wp_roles;
        $l_wp_roles = wp_roles();
        $exist_visitor_role = false;
        foreach ($l_wp_roles->role_names as $i_role => $name) {
            if ($name == "uam-visitor") {
                $exist_visitor_role = true;
                break;
            }
        }
       // Anyway visitor role must be handled even have not been be permanently defined, 
      //set it dynamically with default capability : with unique default capability "read"
// CARE : this can crash. a Check is missing for rights to access add_role
       if (! $exist_visitor_role == true) {
               add_role('uam-visitor', 'Custom UAM visitor Role (WARNING: set by default => don\'forget to set the role permanently : default read all)', array('read' => true));
      }

Patch 2 : Mandatory : If userId == 0 Get "uam-visitor" capabilities and associate its to current user:

In class/UamUserGroup.php Replace near line 780

        if (isset($oCurUserData->{$oDatabase->prefix . "capabilities"})) {
            $aCapabilities = $oCurUserData->{$oDatabase->prefix . "capabilities"};
        } else {
            $aCapabilities = array();
        }

        $aRoles = (is_array($aCapabilities) && count($aCapabilities) > 0) ? array_keys($aCapabilities) : array('norole');

by (note : if role "uam-visitor" has not been defined this will crash)

        // Patched by Trebly:b60903-1
        if ($iObjectId != 0) {
            $oCurUserData = get_userdata($iObjectId);
            if (isset($oCurUserData->{$oDatabase->prefix . "capabilities"})) {
                $aCapabilities = $oCurUserData->{$oDatabase->prefix . "capabilities"};
            } else {
                $aCapabilities = array();
            }       
            $aRoles = (is_array($aCapabilities) && count($aCapabilities) > 0) ? array_keys($aCapabilities) : array('norole');
        } else // visitor has ID=0 and the role is uam-visitor
        {
            $aRoles=array('uam-visitor'); // the role 'uam-visitor is either defined of by default set ( UAM construct) with only capability to "read"
        }
        // End of patch Trebly:b60903-1

that's all.

You will see appear "uam-visitor" into the list of roles (defined manually with WP roles manager). You will be able to create a group for which only attached objects will be accessible by "uam-visitor". This because you have defined his capabilities by patch 2 (capabilities of userId ==0 got from "uam-visitor" role).

Note : the visitor will not not be able to read - for example - published documents - if they are not attached to the group. Then an admin can see all "published" documents with all their context (categories particularly) while standard visitor can not see them. This can be extended to any capability.

Best regards

Trebly


Note 1 : you can use this description for the group: "any not logged-in user has the role "uam-visitor". If this group is not checked the object will be hidden to visitors ("not logged in" user)"

Note 2 : About the User object instance for visitor in WP. I must, first, say that there are some little changes into WP since beginning because User.id is currently == 0 for visitor while before User object was fully undefined or null. This is a first step to get a User object for a visitor. When whole WP code and plugins will check the user.id==0 either than not connected, the problem will end. More, other attributes of the object could be used, particularly association with rights. The relation between User instance and connections will be more clear (multiple, defined limited number etc.). A visitor becomes a User not logged in, any more or not yet or staying as not connected. Many confusions and complicated ways to perform some features comes from the fact that currently visitor has no existence as User and the soft need to use the connection status to manage actions with visitors, this leads to many difficulties.

Note 3 : About the content of this patch and others plugins or WP features interactions This is a step to the definition of the visitor as a user with capabilities but limited to UAM. Admin must be careful because for WP or others plugins visitor remains filtered by 'not logged in'. Then if a plugin like "nav-menu-roles" admin must be aware of the fact that eventhough the role "uam-visitor" appears into the list of roles it is not usable because this is the criteria "logged in or not" which must and will be used for menu access. But nevertheless true access to objects will be filtered by UAM.

GM-Alex commented 7 years ago

Hey Trebly,

thanks again for your (like always) superb explanation. What I don't get is that you are saying that published contents are always accessible to visitors, but if you assign an user group to a content object this object can only be viewed by members of that group and is hidden for visitors. Beside that was I think of pseudo groups for every user (adding a visitor user to these groups is a great idea). What do you guys think?

masimies commented 7 years ago

Comment for this. As it may cause difficulties to understand. If we keep things simple. There is need to prevent acces to somewhere. -> Then prevent the access with UAM-groups Access to pages,menus or widgets. -> You need a membership-plugin, as you anyway need a frontend login system In case of membership-plugin prevents something. -> Allow it with UAM-groups, like "visitor"-group, what have access "all" With public-access needs. ->Do nothing

Trebly commented 7 years ago

Hi,

To answer simply first to your question: You tell

What I don't get is that you are saying that published contents are always accessible to visitors, but if you assign an user group to a content object this object can only be viewed by members of that group and is hidden for visitors.

You are right, I just tell that with WP you cannot see a document in his context while you have not published it. Consequently if you don't want to show it to visitor (immediately, particularly before you could validate environment : categories, keywords, see it into list with excerpt, menus etc.), who have reading access to any published document by default, you need to attach them to a UAM user group (even the most simple which - see next part - can have no role checked and only "read" capability then don't need the patch).

But the problem and way to open it doesn't end there.

The problem comes from the fact that using UAM group the admin forbids to not associated roles (and not inherited) to see an object. The consequence and that this process leads to disconnect the object from the group to make it visible to visitors, while the true problem in my mind can be to give a role to visitor and declare the capability (not by the fact that the "user" is not connected + articles have no restricted access by UAM + articles are published).

The logical process of WP and others plugins is not the same in the two cases.

When you define an UAM group for visitor, which associates users capabilities to access the object attached by the mean of the role "uam-user" (generally just one role, this is the purpose), you create a hook (the patch which prune the "uam-visitor" role to not connected userId ==0) which makes react UAM to visitors as defined into "uam-visitor" role definition (capabilities).

This have many consequences.

I summarize: With a UAM-visitor, you can:

Best regards

Trebly


Complements (can be redundant and coming from previous writings which I thought less concise and practical but which can provide useful details not there are several way to tell the same)

I precise that using groups with no role defined has the same logical effect but which operates only on the "read" capability the alone capability associated to visitor by WP.

About the problem of broken links: I answer separately into the corresponding thread, in my opinion it is independent.

Let us name this group: "uam-visitors-access-allowed-objects" or "UAM-V2A" with the description: "object readable by not logged-in user has defined in the role "uam-visitor". If this group is not checked the object will be hidden to visitor (anybody not logged in)". (please Alex note that it is more easy to name the UAM groups: "UAM-group of objects with access by roles")

This means that we activate the UAM filter which can tell : "don't show (capability : read = not) to user which have not other roles, roles which are not allowed by other group or mean (inherited)" which complex proposal (by negations) is equivalent to the more simple "by this bellowing to this group of this object, the object will be visible by the users which have the associated role".

Basically WP doesn't know the "visitor" it knows only, which is the first criteria:

the plugin (which I use) "nav-menu-roles" have this structure.

The question, that I have formulated first two years ago, have been : how can I hide published documents to visitor but see from some others roles. UAM could not directly (in my perception) answer because it was not possible to tell with: this role attached to this group to which I attach my object can read the object but not others this because the role "visitor" is not present.

Particularly, this is the most important, if you create a group linked to a role (necessarily logged in) and attach it to an object (but to no other to be more simple), this object will be visible from the role and to roles that are over into hierarchy of roles induced by capabilities (motor of rights of WP). So, necessarily because implicitly the not connected user has the lowest level of rights, visitors will be forbidden to read this object.

In WP when you publish a document you open the minimum level right to read everything which is not forbidden by a rule applicable to a role (an UAM group), obviously a user logged in. The consequence is double:

To answer to your question, after these complementary remarks, my patch creates a hook which makes UAM to react to the visitor (identified by userId ==0) as if it was the "uam-visitor" (getting current role, to apply to his treatment, from "uam-visitor" role). This, while all other WP features and pluggins see the visitor simply as not connected user without defined role (the visitor with the default capabilities). The consequence is that UAM can lock the visibility to any document which is for his treatment declared as not visible (for itself behavior).

When you tell :

What I don't get is that you are saying that published contents are always accessible to visitors, but if you assign an user group to a content object this object can only be viewed by members of that group and is hidden for visitors.

You are right but I have explained above that in such case you cannot fully control the whole visibility of visitor but only for logged in users attached to the role of this group. Surely if you disconnect the object it becomes visible but never you had as admin the same view of the document as the "future" visitor" will see. This is particularly for categories because other plugins or WP can hide them to not logged in users, this is also valid for the plugin "nav-menu-roles"

We must nevertheless examine the behavior of WP and others pluggins into two cases:

With a Standard UAM user group if you link this group to roles, to give access to visitor to these objects you need to disconnect (uncheck) objects. So UAM current use need to suppress a role (even empty) to get the behavior.

With my patch a visitor has access to everything is visible by the visitor except the objects not declared to be attached to the group "uam-visitor". But any other filter in WP or plugin will show everything visible into the context "not logged in". To show the object you have to connect objects to "uam-visitor" (check).

With the patch you can give a role with various special capabilities which can be differentiated by groups of objects to visitor (use of several roles uam-visitor(i) (extension of the patch to several roles).

The others pluggins as "nav-menu-roles" don't react at all in the same way.

What I can tell is that with UAM natural group the visitor which has no access to documents by this mean will not see elements of menu.