Change Alfresco users password using API

78 Views Asked by At

I'm using Alfresco 7.4.1.

I need to allow access to Alfresco with LDAP credentials only. I would like to change all the passwords of the local users, to no longer allow users access. Alfresco has around 1000 local users. Is there a way, via API, to be able to update all passwords?

I tried this API:

http://localhost:8080/alfresco/api/-default-/public/alfresco/versions/1/people/f2df59d2-7187-400f-bcbb-aaaaca5b52c9/reset-password

with the following body, but it doesn't work.

{
  "password":"newPassword",
  "id":"user.name",
  "key":"f2df59d2-7187-400f-bcbb-aaaaca5b52c9"
}
3

There are 3 best solutions below

0
On

To change the password for multiple users I ran this script

var nodes = [
  "user.user1",
  "user.user2",
  "user.user3",
  "user.user4"
];

for ( var i = 0; i < nodes.length; i++) {

  var currentNode = nodes[i];
  var pNode = people.getPerson(nodes[i]);

  if (pNode!=null && pNode.exists()){

    var userName = pNode.properties.userName;
    var password = generatePassword();

    people.setPassword(userName, password);

    logger.log("New password for user: "+userName+" has been updated. | " + userName + " | " + password + " | ");

  } else {
    logger.log("User not found: ");
  }
}

function generatePassword() {

    var length = 12,
    charset = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!$&%",
    retVal = "";

    for (var i = 0, n = charset.length; i < length; ++i) {
        retVal += charset.charAt(Math.floor(Math.random() * n));
    }
    
    return retVal;
}

To get the userNames of all Alfresco users, I made an API call (GET /people)

0
On

Instead of doing another REST call like in your script you could do all in one and instead of modifying the password you could delete the object in the local UserStore to migrate the user to a so called lightweight user authenticating to the external auth system only:

var users = people.getPeople(null); // get all person nodeRefs in the system
var personNode, username, usrNode;

for each (var u in users){
    personNode = utils.getNodeFromString(u);
    if (personNode){
        username=personNode.properties["cm:userName"];
        // find a corresponding usr node in the local alfrescoUserStore
        userNodeRef = search.selectNodes(
            "user://alfrescoUserStore", 
            "/sys:system/sys:people/usr:" + username
        )[0];

        if (userNodeRef && username != "admin"){
            logger.log("user " + personNode.properties["cm:userName"] + " has a local user - removing from UserStore...");
            // userNodeRef.remove();
        } else {
            logger.log("user " + personNode.properties["cm:userName"] + " is already a lightweight user - skipping ...");
        }
    }

}

In real live you may extend the script to only remove the usr node if the user has a secondary in a specific auth zone like /sys:system/sys:zones/cm:AUTH.EXT.ldap-ad1 which means the user has been successfully synchronized from that auth subsystem in the authentication.chain via ldap.

2
On

The API you are using does not change the user's password as you think, it tries to find a worklow initiated by /people/{personId}/request-password-reset to allow the end user to send a new password when receiving a reset password email from the workflow. So it's not what you're looking for at all...

When you configure LDAP authentication in Alfresco, you add an additional authentication to the authentication.chain. e.g.

authentication.chain=ldap-ad1:ldap-ad,alfrescoNtlm1:alfrescoNtlm

This means that when a user logs in (in this example), the specified password is first validated against ldap-ad1 and, if this fails, against alfrescoNtlm1. Your problem is that you are always authenticating against more than one authentication system.

To achieve what you are looking for, you could remove the usr nodes from the user://alfrescoUserStore under /sys:system/sys:people/. These nodes more or less only store the password for a local user. However, you should keep the password for the admin user in order to always have a local user to log in. The user node itself is stored in /sys:system/sys:people, so you don't have to worry about deleting the usr:user type nodes that contain the password.