Re: Re: Problem with grant and revoke user roles in turbine-4

"Georg Kallidis" <[email protected]> Fri, 24 Nov 2017 15:59:31 +0100
Newsgroups gmane.comp.jakarta.turbine.user
Message-ID <OF586D9D1C.7ACDC78B-ONC12581E1.004C4D55-C12581E2.00525A93__24948.1435785585$1511535588$gmane$org@cedis.fu-berlin.de>
Hi Jeffery,=20

that=B4s in any case very cool to do this fluxTooling! ;-)

I checked out your GitHub project fluxtest and I may have found the bug=20
(in Turbine).

The issue is that the Turbine service class=20
org.apache.turbine.services.security.DefaultSecurityService implementing
org.apache.turbine.services.security.SecurityService requires as user=20
model org.apache.turbine.om.security.User (=3DUser).=20
On the other side the Fulcrum implementation of the grant method uses a=20
method (update) (defined in=20
org.apache.fulcrum.security.torque.security.TorqueAbstractSecurityEntity)=20
seems to expect as contract fulcrum user object, but also=20
TorqueAbstractSecurityEntity, which is implemented by the Turbineuser om=20
class by extending the appropriate baseClass=20
org.apache.fulcrum.security.torque.turbine.DefaultAbstractTurbineUser in=20
the schema (=3D TurbineUser).=20
How to match this? It WOULD be possible to retrieve the backing=20
TurbineUser object from the User with the getUserDelegate() method.=20
But the interface TurbineUserDelegate is not part of the contract of=20
turbine.om.security.User (though DefaultUserImpl DOES implement=20
TurbineUserDelegate) this is somewhat hidden in the SecurityService (a=20
cast would be required later on).
The easiest and most transparent solution would be (in my view), that=20
org.apache.turbine.om.security.User interface extends TurbineUserDelegate=20
and that at one point the delegate is called (as the TurbineUser OM class=20
does implement Fulcrum TurbineUser, which implements Fulcrum User this=20
would be no problem. We have to call getUserDelegate before the=20
modelManager grant method is called, i.e. in DefaultSecurityService). No=20
other changes seem to be needed .. I'll create an issue in TRB JIRA as=20
soon as possible..

As a result you may have to use the Torque mapper for now, cft. your=20
action FluxUserAction, cft. the github patch=20
(https://github.com/jlpainter/turbine-flux/pull/1, you might just review=20
the changes).

I posted a copy to the dev list, where the discussion might continue ...

Best regards, Georg



Von:    Jeffery Painter <[email protected]>
An:     [email protected]
Datum:  18.11.2017 00:43
Betreff:        Re: Problem with grant and revoke user roles in turbine-4




I gave it one last shot, but I am still having trouble with casting the=20
user object. The security service seems to only want to give me the=20
wrapper version and I cannot cast it to anything that the removeUser()=20
method likes....

maybe you can take a look at the following method.


Here is my logging output.

2017-11-17 18:32:39,818 [http-nio-8080-exec-4] DEBUG=20
org.apache.turbine.flux.modules.actions.user.FluxUserAction - getUser()=20
type: org.apache.turbine.fluxtest.wrapper.TurbineUserWrapper

2017-11-17 18:32:41,105 [http-nio-8080-exec-4] DEBUG=20
org.apache.turbine.flux.modules.actions.user.FluxUserAction -=20
o.a.t.o.s.User type:=20
org.apache.turbine.fluxtest.wrapper.TurbineUserWrapper

2017-11-17 18:32:42,598 [http-nio-8080-exec-4] DEBUG=20
org.apache.turbine.flux.modules.actions.user.FluxUserAction -=20
o.a.f.s.m.t.e.TurbineUser type:=20
org.apache.turbine.fluxtest.wrapper.TurbineUserWrapper

2017-11-17 18:33:06,031 [http-nio-8080-exec-4] ERROR=20
org.apache.turbine.flux.modules.actions.user.FluxUserAction - Could not=20
remove user: org.apache.fulcrum.security.util.UnknownEntityException:=20
Could not find User/Group/Role

and the method call I am trying to use to delete the user...


     /**
      * ActionEvent responsible for removing a user from the Tambora=20
system.
      */
     public void doDelete(PipelineData pipelineData, Context context)=20
throws Exception {

         try {
             RunData data =3D getRunData(pipelineData);
             String username =3D data.getParameters().getString("username");
             if (!StringUtils.isEmpty(username)) {
                 if (security.accountExists(username)) {

                     // this is always returning the wrapper version of=20
our user
                     User user1 =3D security.getUser(username);
                     log.debug("getUser() type: " +=20
user1.getClass().getTypeName().toString() );

                     // same and does not work
                     User user2 =3D (org.apache.turbine.om.security.User)=20
security.getUser(username);
                     log.debug("o.a.t.o.s.User type: " +=20
user2.getClass().getTypeName().toString() );

                     // no change - and you cannot use the interface=20
class as a parameter to the removeUser method
org.apache.fulcrum.security.model.turbine.entity.TurbineUser user3 =3D=20
(org.apache.fulcrum.security.model.turbine.entity.TurbineUser)=20
security.getUser(username);
                     log.debug("o.a.f.s.m.t.e.TurbineUser type: " +=20
user3.getClass().getTypeName().toString() );

                     // Tried using reflection to cast and still doesn't=20
work
                     org.apache.turbine.om.security.User forceUser =3D=20
org.apache.turbine.om.security.User.class.cast(=20
security.getUser(username) );
                     log.debug("o.a.t.o.s.User type: " +=20
forceUser.getClass().getTypeName().toString() );

                     //security.revokeAll(user);
                     // remove user does the revokeAll above...
                     security.removeUser(forceUser);

                 } else {
                     log.error("User does not exist!");
                 }
             }
         } catch (Exception e) {
             log.error("Could not remove user: " + e);
         }
     }


On 11/17/2017 06:03 PM, Jeffery Painter wrote:
> Hi Georg,
>
> I did a quick test on the remove role method with the following change=20
> and it works.  My problem with role removal was that in my test case,=20
> the role was associated with users and could not be removed.  Maybe a=20
> better error message would help? :-)   The user management needs a bit=20
> more work as well to make it comply with the SecurityService. I will=20
> work on that.  The old flux tool also had some weirdness in the way it=20
> handled the getRole() getGroup() getUser() method where it was caching=20
> the last loaded entry... I am fixing that as well.
>
> I inserted a few new roles and was able to remove them.  I am working=20
> on updating the rest of the FluxTool methods so they behave=20
> appropriately.  When I get it into decent shape, I will push updates=20
> to my github project for you to test out if you like before we make a=20
> space to put it into the apache source control.
>
> That will most likely be after Nov 25th when I get back into town. Who=20
> knows - if I get bored, I may open up some code on my laptop, but not=20
> likely as we are going on a cruise where it will be nice and warm!
>
> Thanks,
> Jeff
>
>
>
> On 11/17/2017 05:17 PM, Georg Kallidis wrote:
>> Hi Jeff,
>>
>> as far as I can see, I assume the implementation class might be=20
>> TorqueTurbineModelManagerImpl? Could you check this? Your second=20
>> attempt may be indeed close, but the reason is missing. Could you=20
>> provide the stack/cause of the exception?
>>
>> Probably, if this is the case, at this point of the code of the model=20
>> manager the role, group and user are already checked, but what might=20
>> have caused the exception is a failing cast to
>>
>> - org.apache.fulcrum.security.model.turbine.entity.TurbineUser of the=20
>> user object or
>> -=20
>>=20
org.apache.fulcrum.security.torque.security.TorqueAbstractSecurityEntity=20
>> of any of the objects, which may be the reason, if in your schema the=20
>> baseclass attribute is not set to=20
>> org.apache.fulcrum.security.torque.turbine.DefaultAbstractTurbineXXX=20
>> (XXX =3D User|Role|Group) class (or another class implementing the=20
>> required interface, cft. the example torque-security-schem.xml in the=20
>> Turbine webapp archetype)...
>>
>> And thanks for your efforts to migrate / use the flux library!
>>
>> Best regards, Georg
>>
>> -----Jeffery Painter <[email protected]> schrieb: -----
>> An: [email protected]
>> Von: Jeffery Painter <[email protected]>
>> Datum: 16.11.2017 23:29
>> Betreff: Re: Problem with grant and revoke user roles in turbine-4
>>
>> I looked a little more at the test cases, and got my code setup enough
>> to try and call the fulcrum security service directly...
>>
>>                                       // try using fulcrum service
>>=20
((TurbineModelManager)fulcrumSecurityService.getModelManager()).grant(fulcr=
umUser,=20

>>
>> group, role);
>>
>> The error logs are still reporting problems:
>>
>> I verified that this loaded the user "dean" from the database as a
>> fulcrumUser and it came through with a class type of
>> com.jivecast.smartorder.om.TurbineUser rather than the wrapper that the
>> turbine security service provided. and now I get a DataBackendException
>> error on the grant call...
>>
>> 2017-11-16 17:24:43,722 [http-nio-8080-exec-3] DEBUG avalon - Located
>> the service 'org.apache.fulcrum.security.UserManager' in the local=20
>> container
>> 2017-11-16 17:24:47,895 [http-nio-8080-exec-3] DEBUG
>> com.jivecast.smartorder.modules.actions.admin.UserAction - fulcrumUser:
>> com.jivecast.smartorder.om.TurbineUser
>> 2017-11-16 17:24:54,147 [http-nio-8080-exec-3] DEBUG avalon.peerManager
>> -  get cached
>> PeerInstance():com.jivecast.smartorder.om.TurbineGroupPeerImpl@3ccc32c
>> 2017-11-16 17:24:55,750 [http-nio-8080-exec-3] DEBUG avalon.peerManager
>> -  get cached
>> PeerInstance():com.jivecast.smartorder.om.TurbineRolePeerImpl@1f7f807
>> 2017-11-16 17:24:56,031 [http-nio-8080-exec-3] DEBUG avalon.peerManager
>> -  get cached
>> PeerInstance():com.jivecast.smartorder.om.TurbineRolePeerImpl@1f7f807
>> 2017-11-16 17:24:56,315 [http-nio-8080-exec-3] DEBUG avalon.peerManager
>> -  get cached
>> PeerInstance():com.jivecast.smartorder.om.TurbineRolePeerImpl@1f7f807
>> 2017-11-16 17:24:56,599 [http-nio-8080-exec-3] DEBUG avalon.peerManager
>> -  get cached
>> PeerInstance():com.jivecast.smartorder.om.TurbineGroupPeerImpl@3ccc32c
>> 2017-11-16 17:25:03,129 [http-nio-8080-exec-3] DEBUG avalon.peerManager
>> -  get cached
>> PeerInstance():com.jivecast.smartorder.om.TurbineGroupPeerImpl@3ccc32c
>> 2017-11-16 17:25:03,143 [http-nio-8080-exec-3] DEBUG avalon.peerManager
>> -  get cached
>> PeerInstance():com.jivecast.smartorder.om.TurbineRolePeerImpl@1f7f807
>> 2017-11-16 17:25:09,097 [http-nio-8080-exec-3] DEBUG
>> com.jivecast.smartorder.modules.actions.admin.UserAction - Adding new
>> role to user: inventory
>> 2017-11-16 17:25:10,535 [http-nio-8080-exec-3] DEBUG avalon - Located
>> the service 'org.apache.fulcrum.security.ModelManager' in the local
>> container
>> 2017-11-16 17:25:10,545 [http-nio-8080-exec-3] DEBUG avalon - Located
>> the service 'org.apache.fulcrum.security.RoleManager' in the local=20
>> container
>> 2017-11-16 17:25:10,547 [http-nio-8080-exec-3] DEBUG avalon.peerManager
>> -  get cached
>> PeerInstance():com.jivecast.smartorder.om.TurbineRolePeerImpl@1f7f807
>> 2017-11-16 17:25:10,560 [http-nio-8080-exec-3] DEBUG avalon - Located
>> the service 'org.apache.fulcrum.security.UserManager' in the local=20
>> container
>> 2017-11-16 17:25:10,561 [http-nio-8080-exec-3] DEBUG avalon.peerManager
>> -  get cached
>> PeerInstance():com.jivecast.smartorder.om.TurbineUserPeerImpl@86cedb4
>> 2017-11-16 17:25:10,598 [http-nio-8080-exec-3] DEBUG avalon - Located
>> the service 'org.apache.fulcrum.security.GroupManager' in the local
>> container
>> 2017-11-16 17:25:10,599 [http-nio-8080-exec-3] DEBUG avalon.peerManager
>> -  get cached
>> PeerInstance():com.jivecast.smartorder.om.TurbineGroupPeerImpl@3ccc32c
>> 2017-11-16 17:25:25,202 [http-nio-8080-exec-3] ERROR
>> com.jivecast.smartorder.modules.actions.admin.UserAction - Error=20
setting
>> roles: org.apache.fulcrum.security.util.DataBackendException:
>> grant('dean', 'global', 'inventory') failed
>>
>>
>> any ideas?
>>
>> --=20
>> Jeff
>>
>>
>>
>> On 11/16/2017 05:00 PM, Jeffery Painter wrote:
>>> Hi Georg,
>>>
>>> I am making some good progress.  I don't know if you remember the old
>>> flux library for user management, but I have started to re-write that
>>> to work with Turbine 4.0.  I am having some troubles however with the
>>> grant/revoke roles with casting the user object incorrectly from the
>>> TurbineWrapper class.  Can you help me with the issue I am having
>>> below?  I looked at the unit tests in the Turbine source for
>>> inspiration on migrating, but it isn't recognizing the user class
>>> properly.  I even tried to manually downcast (see my code below), and
>>> still cannot make it work.
>>>
>>> If I can get this all working, I thought it might be useful to publish
>>> a new flux library compatible with Turbine-4.0 for user management as
>>> a guide to others on how to get started.
>>>
>>>
>>> My logs show the following error when calling the grant/revoke method
>>> on the security service when trying to add the "inventory" role to a
>>> user:
>>>
>>> 2017-11-16 16:49:26,918 [http-nio-8080-exec-13] DEBUG
>>> com.jivecast.smartorder.modules.actions.admin.UserAction - Adding new
>>> role to user: inventory
>>>
>>> 2017-11-16 16:49:26,918 [http-nio-8080-exec-13] DEBUG avalon - Located
>>> the service 'org.apache.fulcrum.security.RoleManager' in the local
>>> container
>>> 2017-11-16 16:49:26,918 [http-nio-8080-exec-13] DEBUG
>>> avalon.peerManager -  get cached
>>> PeerInstance():com.jivecast.smartorder.om.TurbineRolePeerImpl@71897a2b
>>>
>>> 2017-11-16 16:49:26,918 [http-nio-8080-exec-13] DEBUG avalon - Located
>>> the service 'org.apache.fulcrum.security.UserManager' in the local
>>> container
>>> 2017-11-16 16:49:26,918 [http-nio-8080-exec-13] DEBUG
>>> avalon.peerManager -  get cached
>>> PeerInstance():com.jivecast.smartorder.om.TurbineUserPeerImpl@448e6624
>>>
>>> 2017-11-16 16:49:26,918 [http-nio-8080-exec-13] DEBUG avalon - Located
>>> the service 'org.apache.fulcrum.security.GroupManager' in the local
>>> container
>>> 2017-11-16 16:49:26,918 [http-nio-8080-exec-13] DEBUG
>>> avalon.peerManager -  get cached
>>>=20
PeerInstance():com.jivecast.smartorder.om.TurbineGroupPeerImpl@151d470d
>>>
>>> 2017-11-16 16:49:26,919 [http-nio-8080-exec-13] ERROR
>>> com.jivecast.smartorder.modules.actions.admin.UserAction - Error
>>> setting roles: java.lang.ClassCastException:
>>> com.jivecast.smartorder.wrapper.TurbineUserWrapper cannot be cast to
>>>=20
org.apache.fulcrum.security.torque.security.TorqueAbstractSecurityEntity=20
>>>
>>>
>>>
>>> Here is the relevant code in my doRoles() method to make the new
>>> assignment... it is modeled after the old flux methods:
>>>
>>> I have the following import:
>>>
>>> import org.apache.turbine.services.security.SecurityService;
>>>
>>> and in the body of the class, I use the injection to get the instance
>>> mapped
>>>
>>>      /** Injected service instance */
>>>      @TurbineService
>>>      private SecurityService security;
>>>
>>> .... then my action class method is called doRoles() which does the
>>> role assignment and fails
>>>
>>>      /**
>>>       * Update the roles that are to assigned to a user for a project.
>>>       */
>>>      public void doRoles(PipelineData pipelineData, Context context)
>>> throws Exception {
>>>
>>>          try {
>>>
>>>              RunData data =3D getRunData(pipelineData);
>>>
>>>              // Get the Turbine ACL implementation for our current
>>> user, only admin can update user roles
>>>              TurbineAccessControlList adminAcl =3D
>>> getRunData(data).getACL();
>>>              if (adminAcl.hasRole("administrator")) {
>>>
>>>                  // Username of the account we are updating
>>>                  String username =3D
>>> data.getParameters().getString("username");
>>>                  if (security.accountExists(username)) {
>>>
>>>                      // Try to downcast for the security grant=20
function
>>>                      org.apache.turbine.om.security.User user =3D
>>> (org.apache.turbine.om.security.User) security.getUser(username);
>>>
>>>                      // Get the Turbine ACL implementation
>>>                      TurbineAccessControlList acl =3D=20
>>> security.getACL(user);
>>>
>>>                      /*
>>>                       * Grab all the Groups and Roles in the system.
>>>                       */
>>>                      GroupSet groups =3D security.getAllGroups();
>>>                      RoleSet roles =3D security.getAllRoles();
>>>
>>>                      for (Group group : groups) {
>>>                          String groupName =3D group.getName();
>>>                          for (Role role : roles) {
>>>                              String roleName =3D role.getName();
>>>
>>>                              /*
>>>                               * In the UserRoleForm.vm we made a
>>> checkbox for every possible Group/Role
>>>                               * combination so we will compare every
>>> possible combination with the values
>>>                               * that were checked off in the form. If
>>> we have a match then we will grant the
>>>                               * user the role in the group.
>>>                               */
>>>                              String groupRole =3D groupName + roleName;
>>>                              String formGroupRole =3D
>>> data.getParameters().getString(groupRole);
>>>
>>>                              if (formGroupRole !=3D null &&
>>> !acl.hasRole(role, group)) {
>>>                                  // add the role for this user
>>>                                  if (acl.hasRole(role) =3D=3D false) {
>>>                                      log.debug("Adding new role to
>>> user: " + role.getName());
>>>                                      security.grant(user, group,=20
role);
>>>                                  }
>>>                              } else if (formGroupRole =3D=3D null &&
>>> acl.hasRole(role, group)) {
>>>                                  // revoke the role for this user
>>>                                  log.debug("Revoke role: " +
>>> role.getName());
>>>                                  security.revoke(user, group, role);
>>>                              }
>>>                          }
>>>                      }
>>>
>>>                  } else {
>>>                      log.error("User does not exist!");
>>>                  }
>>>              } else {
>>>                  data.setMessage("You do not have access to perform
>>> this action.");
>>>              }
>>>          } catch (Exception e) {
>>>              log.error("Error setting roles: " + e.toString());
>>>          }
>>>
>>>      }
>>>
>>>
>

--=20
Jeff Painter

CEO and Founder of JiveCast
Software and analytics, made together
http://jivecast.com

301 Fayetteville St. Unit 2301, Raleigh, NC 27601
(919) 533-9024


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]