Merged V2.2 to HEAD

10931: Merged V2.1 to V2.2
      9931: Fix for https://issues.alfresco.com/jira/browse/ETWOONE-295
      10094: Further fix for ETWOONE-241: SAXException - XML parser apparently is not thread safe
      10101: Resolve ACT 1282: wcm workflow falling over on Oracle while hitting in clause limit of 1000 expressions.
      10188: https://issues.alfresco.com/jira/browse/ETWOONE-74 (Part 1)
      10447: ETWOONE-328: performance improvement added to rule trigger code
      10455: Fix for ETWOONE-306.
      10292: Fix for ETWOONE-92: If two users update the same contents at the same time, you get InvalidNodeRefException
      10293: Fix for ETWOONE-116: Send email action does not handle invalid email address
      10294: Fix for ETWOONE-164: when a powerpoint 2007 pptx is stored in alfresco ...
      10341: Action Evaluator request level cache


git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@10934 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Derek Hulley
2008-09-19 12:51:08 +00:00
parent 3ca446e81e
commit 8fb3a02d1f
13 changed files with 556 additions and 103 deletions

View File

@@ -48,6 +48,7 @@ import net.sf.acegisecurity.providers.dao.SaltSource;
import org.alfresco.model.ContentModel;
import org.alfresco.repo.cache.SimpleCache;
import org.alfresco.repo.security.authentication.InMemoryTicketComponentImpl.ExpiryMode;
import org.alfresco.repo.security.authentication.InMemoryTicketComponentImpl.Ticket;
import org.alfresco.repo.tenant.TenantService;
import org.alfresco.service.ServiceRegistry;
@@ -139,8 +140,7 @@ public class AuthenticationTest extends TestCase
authenticationManager = (AuthenticationManager) ctx.getBean("authenticationManager");
saltSource = (SaltSource) ctx.getBean("saltSource");
TransactionService transactionService = (TransactionService) ctx.getBean(ServiceRegistry.TRANSACTION_SERVICE
.getLocalName());
TransactionService transactionService = (TransactionService) ctx.getBean(ServiceRegistry.TRANSACTION_SERVICE.getLocalName());
userTransaction = transactionService.getUserTransaction();
userTransaction.begin();
@@ -155,8 +155,7 @@ public class AuthenticationTest extends TestCase
systemNodeRef = nodeService.createNode(rootNodeRef, children, system, container).getChildRef();
typesNodeRef = nodeService.createNode(systemNodeRef, children, types, container).getChildRef();
Map<QName, Serializable> props = createPersonProperties("Andy");
personAndyNodeRef = nodeService.createNode(typesNodeRef, children, ContentModel.TYPE_PERSON, container, props)
.getChildRef();
personAndyNodeRef = nodeService.createNode(typesNodeRef, children, ContentModel.TYPE_PERSON, container, props).getChildRef();
assertNotNull(personAndyNodeRef);
deleteAndy();
@@ -270,6 +269,10 @@ public class AuthenticationTest extends TestCase
authenticationService.authenticate("Andy_ Woof/Domain", "".toCharArray());
assertEquals("Andy_ Woof/Domain", authenticationService.getCurrentUserName());
authenticationService.createAuthentication("Andy `\u00ac\u00a6!\u00a3$%^&*()-_=+\t\n\u0000[]{};'#:@~,./<>?\\|", "".toCharArray());
authenticationService.authenticate("Andy `\u00ac\u00a6!\u00a3$%^&*()-_=+\t\n\u0000[]{};'#:@~,./<>?\\|", "".toCharArray());
assertEquals("Andy `\u00ac\u00a6!\u00a3$%^&*()-_=+\t\n\u0000[]{};'#:@~,./<>?\\|", authenticationService.getCurrentUserName());
if (! tenantService.isEnabled())
{
authenticationService.createAuthentication("Andy `\u00ac\u00a6!\u00a3$%^&*()-_=+\t\n\u0000[]{};'#:@~,./<>?\\|", "".toCharArray());
@@ -307,8 +310,7 @@ public class AuthenticationTest extends TestCase
assertTrue(AndyDetails.isCredentialsNonExpired());
assertTrue(AndyDetails.isEnabled());
assertNotSame("cabbage", AndyDetails.getPassword());
assertEquals(AndyDetails.getPassword(), passwordEncoder.encodePassword("cabbage", saltSource
.getSalt(AndyDetails)));
assertEquals(AndyDetails.getPassword(), passwordEncoder.encodePassword("cabbage", saltSource.getSalt(AndyDetails)));
assertEquals(1, AndyDetails.getAuthorities().length);
// Object oldSalt = dao.getSalt(AndyDetails);
@@ -465,8 +467,6 @@ public class AuthenticationTest extends TestCase
// assertNull(dao.getUserOrNull("Andy"));
}
public void testTicket()
{
dao.createUser("Andy", "ticket".toCharArray());
@@ -568,6 +568,147 @@ public class AuthenticationTest extends TestCase
// assertNull(dao.getUserOrNull("Andy"));
}
public void testTicketExpiryMode()
{
InMemoryTicketComponentImpl tc = new InMemoryTicketComponentImpl();
tc.setOneOff(false);
tc.setTicketsExpire(true);
tc.setValidDuration("P5S");
tc.setTicketsCache(ticketsCache);
tc.setExpiryMode(ExpiryMode.AFTER_FIXED_TIME.toString());
dao.createUser("Andy", "ticket".toCharArray());
UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken("Andy", "ticket");
token.setAuthenticated(false);
Authentication result = authenticationManager.authenticate(token);
result.setAuthenticated(true);
String ticket = tc.getNewTicket(getUserName(result));
tc.validateTicket(ticket);
assertEquals(ticketComponent.getCurrentTicket("Andy"), ticket);
tc.validateTicket(ticket);
assertEquals(ticketComponent.getCurrentTicket("Andy"), ticket);
tc.validateTicket(ticket);
assertEquals(ticketComponent.getCurrentTicket("Andy"), ticket);
synchronized (this)
{
try
{
wait(10000);
}
catch (InterruptedException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
try
{
tc.validateTicket(ticket);
assertNotNull(null);
}
catch (AuthenticationException e)
{
}
try
{
tc.validateTicket(ticket);
assertNotNull(null);
}
catch (AuthenticationException e)
{
}
try
{
tc.validateTicket(ticket);
assertNotNull(null);
}
catch (AuthenticationException e)
{
}
synchronized (this)
{
try
{
wait(10000);
}
catch (InterruptedException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
try
{
tc.validateTicket(ticket);
assertNotNull(null);
}
catch (AuthenticationException e)
{
}
tc.setExpiryMode(ExpiryMode.AFTER_INACTIVITY.toString());
ticket = tc.getNewTicket(getUserName(result));
for (int i = 0; i < 50; i++)
{
synchronized (this)
{
try
{
wait(100);
}
catch (InterruptedException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
tc.validateTicket(ticket);
}
}
synchronized (this)
{
try
{
wait(10000);
}
catch (InterruptedException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
try
{
tc.validateTicket(ticket);
assertNotNull(null);
}
catch (AuthenticationException e)
{
}
dao.deleteUser("Andy");
// assertNull(dao.getUserOrNull("Andy"));
}
public void testTicketExpires()
{
InMemoryTicketComponentImpl tc = new InMemoryTicketComponentImpl();
@@ -704,7 +845,7 @@ public class AuthenticationTest extends TestCase
// assertNull(dao.getUserOrNull("Andy"));
}
public void testAuthenticationServiceGetNewTicket()
{
authenticationService.createAuthentication("GUEST", "".toCharArray());
@@ -718,16 +859,16 @@ public class AuthenticationTest extends TestCase
// assert the user is authenticated
assertEquals("Andy", authenticationService.getCurrentUserName());
String ticket1 = authenticationService.getCurrentTicket();
authenticationService.authenticate("Andy", "auth1".toCharArray());
// assert the user is authenticated
assertEquals("Andy", authenticationService.getCurrentUserName());
String ticket2 = authenticationService.getCurrentTicket();
assertFalse(ticket1.equals(ticket2));
}

View File

@@ -49,7 +49,7 @@ public class InMemoryTicketComponentImpl implements TicketComponent
* Ticket prefix
*/
public static final String GRANTED_AUTHORITY_TICKET_PREFIX = "TICKET_";
private static ThreadLocal<String> currentTicket = new ThreadLocal<String>();
private boolean ticketsExpire;
@@ -61,10 +61,11 @@ public class InMemoryTicketComponentImpl implements TicketComponent
private String guid;
private SimpleCache<String, Ticket> ticketsCache; // Can't use Ticket as it's private
private ExpiryMode expiryMode = ExpiryMode.AFTER_FIXED_TIME;
/**
* IOC constructor
*
*/
public InMemoryTicketComponentImpl()
{
@@ -89,7 +90,7 @@ public class InMemoryTicketComponentImpl implements TicketComponent
{
expiryDate = Duration.add(new Date(), validDuration);
}
Ticket ticket = new Ticket(ticketsExpire, expiryDate, userName);
Ticket ticket = new Ticket(ticketsExpire ? expiryMode : ExpiryMode.DO_NOT_EXPIRE, expiryDate, userName, validDuration);
ticketsCache.put(ticket.getTicketId(), ticket);
String ticketString = GRANTED_AUTHORITY_TICKET_PREFIX + ticket.getTicketId();
currentTicket.set(ticketString);
@@ -119,6 +120,7 @@ public class InMemoryTicketComponentImpl implements TicketComponent
/**
* Helper method to find a ticket
*
* @param ticketString
* @return - the ticket
*/
@@ -129,7 +131,8 @@ public class InMemoryTicketComponentImpl implements TicketComponent
}
/**
* Helper method to extract the ticket id from the ticket string
* Helper method to extract the ticket id from the ticket string
*
* @param ticketString
* @return - the ticket key
*/
@@ -271,14 +274,14 @@ public class InMemoryTicketComponentImpl implements TicketComponent
/**
* Ticket
*
* @author andyh
*
*/
public static class Ticket implements Serializable
{
private static final long serialVersionUID = -5904510560161261049L;
private boolean expires;
private ExpiryMode expires;
private Date expiryDate;
@@ -287,18 +290,18 @@ public class InMemoryTicketComponentImpl implements TicketComponent
private String ticketId;
private String guid;
private Duration validDuration;
Ticket(boolean expires, Date expiryDate, String userName)
Ticket(ExpiryMode expires, Date expiryDate, String userName, Duration validDuration)
{
this.expires = expires;
this.expiryDate = expiryDate;
this.userName = userName;
this.validDuration = validDuration;
this.guid = UUIDGenerator.getInstance().generateRandomBasedUUID().toString();
String encode = (expires ? "T" : "F") +
((expiryDate == null) ? new Date().toString(): expiryDate.toString()) +
userName + guid;
String encode = (expires.toString()) + ((expiryDate == null) ? new Date().toString() : expiryDate.toString()) + userName + guid;
MessageDigest digester;
try
{
@@ -314,18 +317,18 @@ public class InMemoryTicketComponentImpl implements TicketComponent
}
catch (NoSuchAlgorithmException e1)
{
CRC32 crc = new CRC32();
crc.update(encode.getBytes());
byte[] bytes = new byte[4];
long value = crc.getValue();
bytes[0] = (byte)(value & 0xFF);
value >>>= 4;
bytes[1] = (byte)(value & 0xFF);
value >>>= 4;
bytes[2] = (byte)(value & 0xFF);
value >>>= 4;
bytes[3] = (byte)(value & 0xFF);
this.ticketId = new String(Hex.encodeHex(bytes));
CRC32 crc = new CRC32();
crc.update(encode.getBytes());
byte[] bytes = new byte[4];
long value = crc.getValue();
bytes[0] = (byte) (value & 0xFF);
value >>>= 4;
bytes[1] = (byte) (value & 0xFF);
value >>>= 4;
bytes[2] = (byte) (value & 0xFF);
value >>>= 4;
bytes[3] = (byte) (value & 0xFF);
this.ticketId = new String(Hex.encodeHex(bytes));
}
}
}
@@ -337,14 +340,33 @@ public class InMemoryTicketComponentImpl implements TicketComponent
*/
boolean hasExpired()
{
if (expires && (expiryDate != null) && (expiryDate.compareTo(new Date()) < 0))
{
return true;
}
else
Date now = new Date();
switch (expires)
{
case AFTER_FIXED_TIME:
if ((expiryDate != null) && (expiryDate.compareTo(now) < 0))
{
return true;
}
else
{
return false;
}
case AFTER_INACTIVITY:
if ((expiryDate != null) && (expiryDate.compareTo(now) < 0))
{
return true;
}
else
{
expiryDate = Duration.add(now, validDuration);
return false;
}
case DO_NOT_EXPIRE:
default:
return false;
}
}
public boolean equals(Object o)
@@ -358,9 +380,7 @@ public class InMemoryTicketComponentImpl implements TicketComponent
return false;
}
Ticket t = (Ticket) o;
return (this.expires == t.expires)
&& this.expiryDate.equals(t.expiryDate) && this.userName.equals(t.userName)
&& this.ticketId.equals(t.ticketId);
return (this.expires == t.expires) && this.expiryDate.equals(t.expiryDate) && this.userName.equals(t.userName) && this.ticketId.equals(t.ticketId);
}
public int hashCode()
@@ -368,7 +388,7 @@ public class InMemoryTicketComponentImpl implements TicketComponent
return ticketId.hashCode();
}
protected boolean getExpires()
protected ExpiryMode getExpires()
{
return expires;
}
@@ -390,10 +410,11 @@ public class InMemoryTicketComponentImpl implements TicketComponent
}
/**
* Are tickets single use
* @param oneOff
*/
/**
* Are tickets single use
*
* @param oneOff
*/
public void setOneOff(boolean oneOff)
{
this.oneOff = oneOff;
@@ -401,6 +422,7 @@ public class InMemoryTicketComponentImpl implements TicketComponent
/**
* Do tickets expire
*
* @param ticketsExpire
*/
public void setTicketsExpire(boolean ticketsExpire)
@@ -408,8 +430,19 @@ public class InMemoryTicketComponentImpl implements TicketComponent
this.ticketsExpire = ticketsExpire;
}
/**
* How should tickets expire.
* @param exipryMode
*/
public void setExpiryMode(String expiryMode)
{
this.expiryMode = ExpiryMode.valueOf(expiryMode);
}
/**
* How long are tickets valid (XML duration as a string)
*
* @param validDuration
*/
public void setValidDuration(String validDuration)
@@ -430,12 +463,12 @@ public class InMemoryTicketComponentImpl implements TicketComponent
public String getCurrentTicket(String userName)
{
String ticket = currentTicket.get();
if(ticket == null)
if (ticket == null)
{
return getNewTicket(userName);
}
String ticketUser = getAuthorityForTicket(ticket);
if(userName.equals(ticketUser))
if (userName.equals(ticketUser))
{
return ticket;
}
@@ -449,9 +482,14 @@ public class InMemoryTicketComponentImpl implements TicketComponent
{
clearCurrentSecurityContext();
}
public static void clearCurrentSecurityContext()
{
currentTicket.set(null);
}
public enum ExpiryMode
{
AFTER_INACTIVITY, AFTER_FIXED_TIME, DO_NOT_EXPIRE;
}
}