Re: Potential userlogic update issue

2023-11-28 Thread GCHQDeveloper29
Hi,

The updateAttr function in my prior email exists within my 'logic' class.
I.e. org.apache.syncope.core.logic.AttributeLogic

The second code block within the same email is what would/could exist within 
the Rest-CXF class of the extension.

If I remove the @Transactional annotation on the updateAttr function, I start 
getting 'Could not find EntityManager for domain Master' exceptions, from my 
userDAO.findByUsername() call, (userDAO being autowired within the logic class).
I have also tried passing through the UserDAO from the LogicContext class 
however that does not work either.
On Tuesday, 28 November 2023 at 13:14, Francesco Chicchiriccò 
 wrote:

> Hi,
> I assume the code below lies inside a REST service implementation class.
>
> Basically, it manipulates payload objects (UserCR, AttrPatch and so on) then 
> invokes UserLogic for actual processing.
>
> If so, then you should remove @Transactional from such method as by doing so 
> you are essentially breaking the transaction mechanism as managed by 
> UserLogic.
>
> HTH
> Regards.
>
> On 28/11/23 11:53, GCHQDeveloper29 wrote:
>
>> Hi there,
>>
>> I'm hoping to gain some advice (or report a bug in the case I've not just 
>> been a fool!).
>> I'm currently on version 3.0.4, although plan to move to 3.0.5 soon, and am 
>> using version 1.5.7 of the LDAP connector.
>>
>> I have a slightly different version of the following function sat behind a 
>> rest endpoint, but am observing peculiar behaviour when calling the rest 
>> endpoint (hence triggering an update in userLogic).
>>
>> ```
>> @Transactional
>> public Response updateAttr(final UpdateAttrTO updateAttrTO, final String 
>> attribute)
>> {
>> // key can either be the username or the UUID of the user
>> String key = updateAttrTO.getKey();
>> String attrVal = updateAttrTO.getAttrVal();
>>
>> try {
>> // getUser gets the user object, first trying by username, then by UUID
>> User user = getUser(key);
>> String uuid = user.getKey();
>> String username = user.getUsername();
>>
>> // Create the patch and user update request
>> Attr attr = new Attr.Builder(attribute)
>> .value(attrVal)
>> .build();
>>
>> AttrPatch patch = new AttrPatch.Builder(attr)
>> .operation(attrVal == "" ? PatchOperation.DELETE : 
>> PatchOperation.ADD_REPLACE)
>> .build();
>>
>> UserUR userUR = new UserUR.Builder(uuid)
>> .plainAttr(patch)
>> .build();
>>
>> // Attempt to patch the user
>> ProvisioningResult provisioningResult = userLogic.update(userUR, 
>> false);
>>
>> return Response.ok().build();
>>
>> }
>> // Catch if a user cannot be found
>> catch (NotFoundException e)
>> {
>> return Response.status(400, e.getLocalizedMessage()).build();
>> }
>> // Catch any other unanticipated error
>> catch (Exception e)
>> {
>> return Response.status(500, e.getLocalizedMessage()).build();
>> } }
>> ```
>>
>> The above function can be called as below (I use rest parameters in 
>> actuality):
>> ```
>> UpdateAttrTO updateAttrTO = new UpdateAttrTO();
>> updateAttrTO.setKey("ExampleKey");
>> updateAttrTO.setAttrVal("ExampleAttrVal");
>> return updateAttr(updateAttrTO, "ExampleAttribute");
>> ```
>>
>> When I do this, the value gets updated within syncopes database, however the 
>> propogation task (to an LDAP connector), updates the downstream resource 
>> with the previous value.
>> For example, if I were to do the following for a user "user123", that does 
>> not initially have "ExampleAttribute" set, the downstream resource is always 
>> one value behind:
>>
>> ```
>> // 
>> // Syncope value - N/A
>> // Downstream LDAP resource - N/A
>> // 
>>
>> UpdateAttrTO updateAttrTO1 = new UpdateAttrTO();
>> updateAttrTO1.setKey("user123");
>> updateAttrTO1.setAttrVal(""); updateAttr(updateAttrTO1, 
>> "ExampleAttribute");
>>
>> // -
>> // Syncope value - ""
>> // Downstream LDAP resource - N/A
>> // -
>>
>> UpdateAttrTO updateAttrTO2 = new UpdateAttrTO();
>> updateAttrTO2.setKey("user123");
>> updateAttrTO2.setAttrVal("");
>> updateAttr(updateAttrTO2, "ExampleAttribute");
>>
>> // 
>> // Syncope value - ""
>> // Downstream LDAP resource - ""
>> // 
>> ```
>>
>> Hopefully I explained the situation sufficiently, if not please let me know 
>> and I can try to give some more detail.
>>
>> Kind Regards, GCHQDeveloper29.
>
> --
> Francesco Chicchiriccò
>
> Tirasa - Open Source Excellence
> http://www.tirasa.net/
> Member at The Apache Software Foundation
> Syncope, Cocoon, Olingo, CXF, OpenJPA, PonyMail
> http://home.apache.org/~ilgrosso/

Re: Potential userlogic update issue

2023-11-28 Thread Francesco Chicchiriccò

Hi,
I assume the code below lies inside a REST service implementation class.

Basically, it manipulates payload objects (UserCR, AttrPatch and so on) then 
invokes UserLogic for actual processing.

If so, then you should remove @Transactional from such method as by doing so 
you are essentially breaking the transaction mechanism as managed by UserLogic.

HTH
Regards.

On 28/11/23 11:53, GCHQDeveloper29 wrote:

Hi there,

I'm hoping to gain some advice (or report a bug in the case I've not just been 
a fool!).
I'm currently on version 3.0.4, although plan to move to 3.0.5 soon, and am 
using version 1.5.7 of the LDAP connector.

I have a slightly different version of the following function sat behind a rest 
endpoint, but am observing peculiar behaviour when calling the rest endpoint 
(hence triggering an update in userLogic).

```
@Transactional
public Response updateAttr(final UpdateAttrTO updateAttrTO, final String 
attribute)
{
    // key can either be the username or the UUID of the user
    String key = updateAttrTO.getKey();
    String attrVal = updateAttrTO.getAttrVal();

    try {
        // getUser gets the user object, first trying by username, then by UUID
        User user = getUser(key);
        String uuid = user.getKey();
        String username = user.getUsername();

        // Create the patch and user update request
        Attr attr = new Attr.Builder(attribute)
            .value(attrVal)
            .build();

        AttrPatch patch = new AttrPatch.Builder(attr)
            .operation(attrVal == "" ? PatchOperation.DELETE : 
PatchOperation.ADD_REPLACE)
            .build();

        UserUR userUR = new UserUR.Builder(uuid)
            .plainAttr(patch)
            .build();

        // Attempt to patch the user
        ProvisioningResult provisioningResult = 
userLogic.update(userUR, false);

        return Response.ok().build();

    }
    // Catch if a user cannot be found
    catch (NotFoundException e)
    {
        return Response.status(400, e.getLocalizedMessage()).build();
    }
    // Catch any other unanticipated error
    catch (Exception e)
    {
        return Response.status(500, e.getLocalizedMessage()).build();
    }
}
```

The above function can be called as below (I use rest parameters in actuality):
```
UpdateAttrTO updateAttrTO = new UpdateAttrTO();
updateAttrTO.setKey("ExampleKey");
updateAttrTO.setAttrVal("ExampleAttrVal");
return updateAttr(updateAttrTO, "ExampleAttribute");
```

When I do this, the value gets updated within syncopes database, however the 
propogation task (to an LDAP connector), updates the downstream resource with 
the previous value.
For example, if I were to do the following for a user "user123", that does not initially 
have "ExampleAttribute" set, the downstream resource is always one value behind:

```
// 
// Syncope value - N/A
// Downstream LDAP resource - N/A
// 

UpdateAttrTO updateAttrTO1 = new UpdateAttrTO();
updateAttrTO1.setKey("user123");
updateAttrTO1.setAttrVal("");
updateAttr(updateAttrTO1, "ExampleAttribute");

// -
// Syncope value - ""
// Downstream LDAP resource - N/A
// -

UpdateAttrTO updateAttrTO2 = new UpdateAttrTO();
updateAttrTO2.setKey("user123");
updateAttrTO2.setAttrVal("");
updateAttr(updateAttrTO2, "ExampleAttribute");

// 
// Syncope value - ""
// Downstream LDAP resource - ""
// 
```

Hopefully I explained the situation sufficiently, if not please let me know and 
I can try to give some more detail.

Kind Regards,
GCHQDeveloper29.



--
Francesco Chicchiriccò

Tirasa - Open Source Excellence
http://www.tirasa.net/

Member at The Apache Software Foundation
Syncope, Cocoon, Olingo, CXF, OpenJPA, PonyMail
http://home.apache.org/~ilgrosso/


Potential userlogic update issue

2023-11-28 Thread GCHQDeveloper29
Hi there,

I'm hoping to gain some advice (or report a bug in the case I've not just been 
a fool!).
I'm currently on version 3.0.4, although plan to move to 3.0.5 soon, and am 
using version 1.5.7 of the LDAP connector.

I have a slightly different version of the following function sat behind a rest 
endpoint, but am observing peculiar behaviour when calling the rest endpoint 
(hence triggering an update in userLogic).

```
@Transactional
public Response updateAttr(final UpdateAttrTO updateAttrTO, final String 
attribute)
{
// key can either be the username or the UUID of the user
String key = updateAttrTO.getKey();
String attrVal = updateAttrTO.getAttrVal();

try {
// getUser gets the user object, first trying by username, then by UUID
User user = getUser(key);
String uuid = user.getKey();
String username = user.getUsername();

// Create the patch and user update request
Attr attr = new Attr.Builder(attribute)
.value(attrVal)
.build();

AttrPatch patch = new AttrPatch.Builder(attr)
.operation(attrVal == "" ? PatchOperation.DELETE : PatchOperation.ADD_REPLACE)
.build();

UserUR userUR = new UserUR.Builder(uuid)
.plainAttr(patch)
.build();

// Attempt to patch the user
ProvisioningResult provisioningResult = userLogic.update(userUR, false);

return Response.ok().build();

}
// Catch if a user cannot be found
catch (NotFoundException e)
{
return Response.status(400, e.getLocalizedMessage()).build();
}
// Catch any other unanticipated error
catch (Exception e)
{
return Response.status(500, e.getLocalizedMessage()).build();
}}
```

The above function can be called as below (I use rest parameters in actuality):
```
UpdateAttrTO updateAttrTO = new UpdateAttrTO();
updateAttrTO.setKey("ExampleKey");
updateAttrTO.setAttrVal("ExampleAttrVal");
return updateAttr(updateAttrTO, "ExampleAttribute");
```

When I do this, the value gets updated within syncopes database, however the 
propogation task (to an LDAP connector), updates the downstream resource with 
the previous value.
For example, if I were to do the following for a user "user123", that does not 
initially have "ExampleAttribute" set, the downstream resource is always one 
value behind:

```
// 
// Syncope value - N/A
// Downstream LDAP resource - N/A
// 

UpdateAttrTO updateAttrTO1 = new UpdateAttrTO();
updateAttrTO1.setKey("user123");
updateAttrTO1.setAttrVal("");updateAttr(updateAttrTO1, "ExampleAttribute");

// -
// Syncope value - ""
// Downstream LDAP resource - N/A
// -

UpdateAttrTO updateAttrTO2 = new UpdateAttrTO();
updateAttrTO2.setKey("user123");
updateAttrTO2.setAttrVal("");
updateAttr(updateAttrTO2, "ExampleAttribute");

// 
// Syncope value - ""
// Downstream LDAP resource - ""
// 
```

Hopefully I explained the situation sufficiently, if not please let me know and 
I can try to give some more detail.

Kind Regards,GCHQDeveloper29.