cancel
Showing results for 
Search instead for 
Did you mean: 

set password auto expiration

monicakumari
Star Contributor
Star Contributor

Hello everyone. I am trying to do something like -

      All user passwords should expire every 90 days.
      Users should be forced to reset their expired passwords upon login to share with last password.

anybody have any idea, how to do it ?

thanks in advance.

1 ACCEPTED ANSWER

this worked..

var userNodeQuery = "TYPE:\"usr:user\"";
	var userNodeQueryDef = {
		       query: userNodeQuery ,
		       language: "fts-alfresco" ,
			   store: "user://alfrescoUserStore"
		};
	
	userNodes = search.query(userNodeQueryDef);

View answer in original post

14 REPLIES 14

afaust
Legendary Innovator
Legendary Innovator

As always with any functionality that is not provided out-of-the-box you need to do significant custom implementation to achieve this. Luckily, Alfresco already provides the Java-level API to manage, store and validate expiration dates on authentications. Whenever a user is created or a new password is set, you could use a policy / behaviour to automatically set the expiration date back to 90 days in the future.

With that in place, you'd "only" need to implement all the missing UI functionality, i.e. displaying expiration reminders and handling the password change prompt. Unfortunately, since Alfresco is a web application, you cannot force users to change their password - I mean, you can force the dialog upon them, but they can always opt not to change the password by simply closing the browser, or they could use browser tools to hide / disable the popup.

Thank you so much for your help. I have tried something - 

I have created a behaviour to set a custom date(90 days from current date) to property ContentModel.PROP_CREDENTIALS_EXPIRY_DATE.

        Calendar now = Calendar.getInstance();
        now.add(Calendar.DATE, 90);
        passwordExpiryDate = now.getTime();

        nodeService.setProperty(nodeRef, ContentModel.PROP_CREDENTIALS_EXPIRY_DATE, passwordExpiryDate);

and then trying to fetch this property just to check whether it is set or not.

         logger.debug("PROP_CREDENTIALS_EXPIRY_DATE :  " + nodeService.getProperty(nodeRef, ContentModel.PROP_CREDENTIALS_EXPIRY_DATE));

it is showing the correct value on console.

then, I have created a sceduler to run a .js file everyday to fetch this property. Its showing null.

not sure, why its showing null if the proprty is alredy set.

then, to check this I did

       Calendar now = Calendar.getInstance();
        now.add(Calendar.DATE, 90);
        passwordExpiryDate = now.getTime();

        nodeService.setProperty(nodeRef, ContentModel.PROP_CREDENTIALS_EXPIRY_DATE, passwordExpiryDate);

to another java file (which triggers when a new user is created) and

logger.debug("PROP_CREDENTIALS_EXPIRY_DATE :  " + nodeService.getProperty(nodeRef, ContentModel.PROP_CREDENTIALS_EXPIRY_DATE));

to the same behaviour.

now property PROP_CREDENTIALS_EXPIRY_DATE is setting while creating a new user, but when behaviour triggers, logs is showing NULL value.

don't know what mistake I am doing, whether  PROP_CREDENTIALS_EXPIRY_DATE  property can directly be used or not. If yes, then how.

could you please help me with this.

Please let know If there is another way to do it or this way is correct and I am making some mistake.

thanks in advance.

afaust
Legendary Innovator
Legendary Innovator

Keep in mind that there are two nodes for each locally-maintained user. A cmSmiley Tongueerson node (which also exists for LDAP/AD synchronised users) which is accessed by most APIs, and the usr:user which contains the local authentication data (password + expiry). So be careful which of these two nodes you are accessing in your code.

yes, thank you.. I have checked, the custom behaviour is having a user type nodeRef and the another class is having a person type nodeRef.

so, How do I get the user type nodeRef from a person type nodeRef ? do you have any idea ? which API can help me to get this ?

afaust
Legendary Innovator
Legendary Innovator

You should ideally never touch the node of type usr:user directly. There is MutableAuthenticationDao (bean "authenticationDao") which provides access to all you need, e.g. operations that take a user name as identifier and check / retrieve / set the expiration time.

Thank you so much for you help.. I dove done what I was trying to do. But I have a issue -  not exactly an issue but may be, it might create some issue .

I have created a behaviour "CheckPasswordExpiration.java" to set password expiration date and a scheduler to check the expiration date on daily basis. there was no issue till I created the scheduler. 

there  is an another seperate behaviour "GenerateEmails.java" which runs when a new user is created just to send mail notifications.

when I created the scheduler, a javascript file (to send email notification) and whenever it triggers, the another seperate behaviour "GenerateEmails.java" automatically triggers which is showing exception.

2018-01-05 14:35:00,439  ERROR [quartz.core.ErrorLogger] [DefaultScheduler_Worker-1] Job (jobGroup.jobD threw an exception.
 org.quartz.SchedulerException: Job threw an unhandled exception. [See nested exception: org.alfresco.error.AlfrescoRuntimeException: 00050016 Failed to execute transaction-level behaviour public abstract void org.alfresco.repo.node.NodeServicePolicies$OnCreateNodePolicy.onCreateNode(org.alfresco.service.cmr.repository.ChildAssociationRef) in transaction a187771c-4769-4d88-807c-f97f335913ce]
    at org.quartz.core.JobRunShell.run(JobRunShell.java:227)
    at org.quartz.simpl.SimpleThreadPool$WorkerThread.run(SimpleThreadPool.java:563)
Caused by: org.alfresco.error.AlfrescoRuntimeException: 00050016 Failed to execute transaction-level behaviour public abstract void org.alfresco.repo.node.NodeServicePolicies$OnCreateNodePolicy.onCreateNode(org.alfresco.service.cmr.repository.ChildAssociationRef) in transaction a187771c-4769-4d88-807c-f97f335913ce
    at org.alfresco.repo.policy.TransactionBehaviourQueue.execute(TransactionBehaviourQueue.java:255)
    at org.alfresco.repo.policy.TransactionBehaviourQueue.beforeCommit(TransactionBehaviourQueue.java:134)
    at org.alfresco.util.transaction.TransactionSupportUtil$TransactionSynchronizationImpl.doBeforeCommit(TransactionSupportUtil.java:535)
    at org.alfresco.util.transaction.TransactionSupportUtil$TransactionSynchronizationImpl.doBeforeCommit(TransactionSupportUtil.java:514)
    at org.alfresco.util.transaction.TransactionSupportUtil$TransactionSynchronizationImpl.beforeCommit(TransactionSupportUtil.java:479)
    at org.springframework.transaction.support.TransactionSynchronizationUtils.triggerBeforeCommit(TransactionSynchronizationUtils.java:95)
    at org.springframework.transaction.support.AbstractPlatformTransactionManager.triggerBeforeCommit(AbstractPlatformTransactionManager.java:925)
    at org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:738)
    at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:724)
    at org.springframework.transaction.interceptor.TransactionAspectSupport.commitTransactionAfterReturning(TransactionAspectSupport.java:475)
    at org.alfresco.util.transaction.SpringAwareUserTransaction.commit(SpringAwareUserTransaction.java:482)
    at org.alfresco.repo.transaction.RetryingTransactionHelper.doInTransaction(RetryingTransactionHelper.java:479)
    at org.alfresco.repo.transaction.RetryingTransactionHelper.doInTransaction(RetryingTransactionHelper.java:326)
    at org.alfresco.repo.action.scheduled.AbstractScheduledAction$JobDefinition$1.runTransactionalAction(AbstractScheduledAction.java:557)
    at org.alfresco.repo.action.scheduled.AbstractScheduledAction$JobDefinition$1.doWork(AbstractScheduledAction.java:426)
    at org.alfresco.repo.security.authentication.AuthenticationUtil.runAs(AuthenticationUtil.java:548)
    at org.alfresco.repo.action.scheduled.AbstractScheduledAction$JobDefinition.execute(AbstractScheduledAction.java:392)
    at org.quartz.core.JobRunShell.run(JobRunShell.java:216)

this behaviour must not trigger when this javascript run through scheduler.

do you have any idea, why this is happening. I can provide you any another information if you need.

thank you.

afaust
Legendary Innovator
Legendary Innovator

I am totally NOT a fan of transaction-level behaviours for precisely these kinds of issues that most people, who are not Alfresco experts, run into. I would assume your GenerateEmail.java behaviour is simply bound to an incorrect policy (not just on create but also on update), or may not work with the specific authentication context (runAs some user X). Unfortunately, that log output (and lack of configuration XML for reference) is not enough to remote-guess the issue.

Thank you for your help and quick response. I really appriciate it.

Axel, I don't know which XML configuration is it.

These are all the files (attached)I have created. don't know why this is happening.

PasswordExiration-notification.js - scheduler javascript file to check password expiration on daily basis and send mail notifications.

PasswordExpirationCheck.java - this behaviour triggers when the password is updated or created a new user just to set password expiration true and the no. of days.   both the value will get from alfresco-global.properties file.

GenerateNewUserWelcomeEmail.java - this was created to trigger when a new user is created. this behaviour is triggering automatically when the scheduler triggers. which must not and throwing some all those exceptions.

sevice-context.xml

alfresco-global.properties file.

afaust
Legendary Innovator
Legendary Innovator

Unfortunately, none of these files show how the password expiration JS is being registered / triggered. So far, nothing provides any clues to what kind of OnCreateNode behaviour is being triggered or what the specific error is in that case. Judging from the Alfresco source code of TransactionBehaviourQueue, you should have way more information in the log than you have provided so far, so maybe if you could also provide the full alfresco.log for that error, it could help.

I am curious: How is that password expiration notification JS working, I mean doing the search.luceneSearch() on the Alfresco user store, when it is not indexed by default? Did you add extra cores to SOLR for that? Also, luceneSearch is a very old-school, legacy way to search and has not received any optimsiations since 4.0. Furthermore, processing ALL users in one JS action is quite a massive job - what if the process fails for a single user? Does it start over again, and send duplicate mails to all the users that have already been processed? You may also overwhelm the caches by processing too many users in a single transaction.