/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License, Version 1.0 only
* (the "License"). You may not use this file except in compliance
* with the License.
*
* You can obtain a copy of the license at
* trunk/opends/resource/legal-notices/CDDLv1_0.txt
* or http://forgerock.org/license/CDDLv1.0.html.
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at
* trunk/opends/resource/legal-notices/OpenDS.LICENSE. If applicable,
* add the following below this CDDL HEADER, with the fields enclosed
* by brackets "[]" replaced with your own identifying information:
* Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*
*
* Copyright 2012 profiq, s.r.o.
*/
package org.opends.server.extensions;
import org.testng.annotations.BeforeMethod;
import org.opends.server.schema.GeneralizedTimeSyntax;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.LinkedList;
import java.util.List;
import org.opends.messages.Message;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
import org.opends.server.TestCaseUtils;
import org.opends.server.protocols.internal.InternalClientConnection;
import org.opends.server.protocols.internal.InternalSearchOperation;
import org.opends.server.types.*;
import static org.testng.Assert.*;
public class PasswordExpirationTimeVirtualAttributeProviderTestCase
extends ExtensionsTestCase
{
private Entry notExpired;
private Entry expired;
@BeforeClass()
public void startServer()
throws Exception
{
TestCaseUtils.startServer();
notExpired = TestCaseUtils.makeEntry("dn: uid=tuser," + TestCaseUtils.TEST_ROOT_DN_STRING,
"objectClass: top",
"objectClass: person",
"objectClass: organizationalPerson",
"objectClass: inetOrgPerson",
"uid: tuser",
"cn: Test User",
"sn: User",
"userPassword: password",
"createTimestamp: 20120315163235Z");
expired = TestCaseUtils.makeEntry("dn: uid=tuser," + TestCaseUtils.TEST_ROOT_DN_STRING,
"objectClass: top",
"objectClass: person",
"objectClass: organizationalPerson",
"objectClass: inetOrgPerson",
"uid: tuser",
"cn: Test User",
"sn: User",
"userPassword: password",
"createTimestamp: 20110315163235Z");
}
@Test
public void test30dPwPolicy() throws Exception
{
TestCaseUtils.addEntry(notExpired);
TestCaseUtils.addEntry("dn: cn=Subentry Password Policy," + TestCaseUtils.TEST_ROOT_DN_STRING,
"objectClass: top",
"objectClass: subentry",
"objectClass: pwdPolicy",
"cn: Subentry Password Policy",
"pwdAttribute: userPassword",
"pwdLockout: TRUE",
"pwdMaxFailure: 3",
"pwdFailureCountInterval: 300",
"pwdLockoutDuration: 300",
"pwdAllowUserChange: TRUE",
"pwdSafeModify: TRUE",
"pwdMaxAge: 2592000", // 30 days
"subtreeSpecification: {minimum 1, specificationFilter \"(objectclass=*)\"}");
long expirationTime = getTimeValueFromAttribute("ds-pwp-password-expiration-time");
long createTime = getTimeValueFromAttribute("pwdchangedtime");
assertEquals(expirationTime, createTime + 2592000000L);
}
@BeforeMethod()
public void environmentSetup() throws Exception
{
TestCaseUtils.initializeMemoryBackend(TestCaseUtils.TEST_BACKEND_ID,
TestCaseUtils.TEST_ROOT_DN_STRING,
true);
}
@AfterMethod()
public void environmentCleanup() throws Exception
{
TestCaseUtils.clearMemoryBackend(TestCaseUtils.TEST_BACKEND_ID);
}
@Test(expectedExceptions = AssertionError.class)
public void testNoExpiration() throws Exception
{
TestCaseUtils.addEntry(notExpired);
TestCaseUtils.addEntry("dn: cn=Subentry Password Policy," + TestCaseUtils.TEST_ROOT_DN_STRING,
"objectClass: top",
"objectClass: subentry",
"objectClass: pwdPolicy",
"cn: Subentry Password Policy",
"pwdAttribute: userPassword",
"pwdLockout: TRUE",
"pwdMaxFailure: 3",
"pwdFailureCountInterval: 300",
"pwdLockoutDuration: 300",
"pwdAllowUserChange: TRUE",
"pwdSafeModify: TRUE",
"subtreeSpecification: {minimum 1, specificationFilter \"(objectclass=*)\"}");
getTimeValueFromAttribute("ds-pwp-password-expiration-time");
}
@Test
public void testPwPolicyExpiring() throws Exception
{
TestCaseUtils.addEntry(notExpired);
TestCaseUtils.addEntry("dn: cn=Subentry Password Policy," + TestCaseUtils.TEST_ROOT_DN_STRING,
"objectClass: top",
"objectClass: subentry",
"objectClass: pwdPolicy",
"cn: Subentry Password Policy",
"pwdAttribute: userPassword",
"pwdLockout: TRUE",
"pwdMaxFailure: 3",
"pwdFailureCountInterval: 300",
"pwdLockoutDuration: 300",
"pwdAllowUserChange: TRUE",
"pwdSafeModify: TRUE",
"pwdMaxAge: 2592000", // 30 days
"subtreeSpecification: {minimum 1, specificationFilter \"(objectclass=*)\"}");
long expirationTime = getTimeValueFromAttribute("ds-pwp-password-expiration-time");
long createTime = getTimeValueFromAttribute("pwdchangedtime");
assertEquals(expirationTime, createTime + 2592000000L);
}
@Test
public void testPwPolicyExpired() throws Exception
{
TestCaseUtils.addEntry(expired);
TestCaseUtils.addEntry("dn: cn=Subentry Password Policy," + TestCaseUtils.TEST_ROOT_DN_STRING,
"objectClass: top",
"objectClass: subentry",
"objectClass: pwdPolicy",
"cn: Subentry Password Policy",
"pwdAttribute: userPassword",
"pwdLockout: TRUE",
"pwdMaxFailure: 3",
"pwdFailureCountInterval: 300",
"pwdLockoutDuration: 300",
"pwdAllowUserChange: TRUE",
"pwdSafeModify: TRUE",
"pwdMaxAge: 648000", // 7.5 days
"subtreeSpecification: {minimum 1, specificationFilter \"(objectclass=*)\"}");
long expirationTime = getTimeValueFromAttribute("ds-pwp-password-expiration-time");
long createTime = getTimeValueFromAttribute("pwdchangedtime");
assertEquals(expirationTime, createTime + 648000000L);
}
private long getTimeValueFromAttribute(String attributeName)
throws Exception
{
// Establish the internal connection as root
InternalClientConnection conn =
InternalClientConnection.getRootConnection();
assertNotNull(conn);
// Define the attribute to be returned
LinkedHashSet<String> retAttr = new LinkedHashSet<String>();
retAttr.add(attributeName);
retAttr.add("pwdpolicysubentry");
// Process the search request
InternalSearchOperation search =
conn.processSearch(notExpired.getDN().toString(),
SearchScope.BASE_OBJECT,
DereferencePolicy.DEREF_ALWAYS,
0,
0,
false,
"(objectclass=*)",
retAttr);
assertEquals(search.getResultCode(), ResultCode.SUCCESS);
LinkedList<SearchResultEntry> entries = search.getSearchEntries();
assertNotNull(entries);
assertEquals(entries.size(), 1);
SearchResultEntry entry = entries.get(0);
assertNotNull(entry);
List<Attribute> attrs = entry.getAttribute(attributeName);
assertNotNull(attrs);
assertEquals(attrs.size(), 1);
Attribute attr = attrs.get(0);
assertNotNull(attr);
Iterator<AttributeValue> it = attr.iterator();
assertTrue(it.hasNext());
AttributeValue val = it.next();
conn.disconnect(DisconnectReason.UNBIND, true, Message.EMPTY);
return
GeneralizedTimeSyntax.decodeGeneralizedTimeValue(val.getValue());
}
}