diff --git a/src/main/java/caosdb/server/CaosAuthenticator.java b/src/main/java/caosdb/server/CaosAuthenticator.java index f2297c56ab843cd16d3997fc6ac8985d5c5ac33c..8fefee3b453dabc0c613228e2495acacb19deaa0 100644 --- a/src/main/java/caosdb/server/CaosAuthenticator.java +++ b/src/main/java/caosdb/server/CaosAuthenticator.java @@ -56,7 +56,7 @@ public class CaosAuthenticator extends Authenticator { try { final AuthenticationToken sessionToken = AuthenticationUtils.parseSessionTokenCookie( - request.getCookies().getFirst(AuthenticationUtils.SESSION_TOKEN_COOKIE), null); + request.getCookies().getFirst(AuthenticationUtils.SESSION_TOKEN_COOKIE)); if (sessionToken != null) { subject.login(sessionToken); diff --git a/src/main/java/caosdb/server/CaosDBServer.java b/src/main/java/caosdb/server/CaosDBServer.java index 4b0ead406d99ceb4214eed55c08caf8aea5e19f4..bfca2f3c13520ec83a35c8f3bd8d88cdb6ae1f81 100644 --- a/src/main/java/caosdb/server/CaosDBServer.java +++ b/src/main/java/caosdb/server/CaosDBServer.java @@ -24,6 +24,7 @@ import caosdb.server.accessControl.AnonymousRealm; import caosdb.server.accessControl.AuthenticationUtils; import caosdb.server.accessControl.CaosDBAuthorizingRealm; import caosdb.server.accessControl.CaosDBDefaultRealm; +import caosdb.server.accessControl.ConsumedInfoCleanupJob; import caosdb.server.accessControl.OneTimeAuthenticationToken; import caosdb.server.accessControl.SessionToken; import caosdb.server.accessControl.SessionTokenRealm; @@ -313,7 +314,7 @@ public class CaosDBServer extends Application { public static void initOneTimeTokens() throws Exception { OneTimeAuthenticationToken.initConfig(); - OneTimeAuthenticationToken.initConsumedInfoCleanup(); + ConsumedInfoCleanupJob.scheduleDaily(); } /** @@ -581,7 +582,7 @@ public class CaosDBServer extends Application { final Subject subject = SecurityUtils.getSubject(); if (subject.isAuthenticated() && subject.getPrincipal() != AnonymousAuthenticationToken.PRINCIPAL) { - final SessionToken sessionToken = SessionToken.generate(subject, null); + final SessionToken sessionToken = SessionToken.generate(subject); // set session token cookie (httpOnly, secure cookie which // is used to recognize a user session) diff --git a/src/main/java/caosdb/server/accessControl/AuthenticationUtils.java b/src/main/java/caosdb/server/accessControl/AuthenticationUtils.java index 9dd660e54fc6c91d97470467dcddef01fd7e4d05..0cbaf9ef0b6a61d66ffe9b2687c0501710ae2be9 100644 --- a/src/main/java/caosdb/server/accessControl/AuthenticationUtils.java +++ b/src/main/java/caosdb/server/accessControl/AuthenticationUtils.java @@ -97,12 +97,11 @@ public class AuthenticationUtils { * @return A new SessionToken * @see {@link AuthenticationUtils#createSessionTokenCookie(SessionToken)}, {@link SessionToken} */ - public static SelfValidatingAuthenticationToken parseSessionTokenCookie( - final Cookie cookie, final String curry) { + public static SelfValidatingAuthenticationToken parseSessionTokenCookie(final Cookie cookie) { if (cookie != null) { final String tokenString = URLDecodeWithUTF8(cookie.getValue()); if (tokenString != null && !tokenString.equals("")) { - return SelfValidatingAuthenticationToken.parse(tokenString, curry); + return SelfValidatingAuthenticationToken.parse(tokenString); } } return null; @@ -195,4 +194,10 @@ public class AuthenticationUtils { public static Collection<String> getRoles(Subject user) { return new CaosDBAuthorizingRealm().doGetAuthorizationInfo(user.getPrincipals()).getRoles(); } + + public static boolean isFromOneTimeTokenRealm(Subject subject) { + return ((Principal) subject.getPrincipal()) + .getRealm() + .equals(OneTimeAuthenticationToken.REALM_NAME); + } } diff --git a/src/main/java/caosdb/server/accessControl/ConsumedInfoCleanupJob.java b/src/main/java/caosdb/server/accessControl/ConsumedInfoCleanupJob.java new file mode 100644 index 0000000000000000000000000000000000000000..97652d6f24e74efb1686fe816d0aa83b7b9c2d9f --- /dev/null +++ b/src/main/java/caosdb/server/accessControl/ConsumedInfoCleanupJob.java @@ -0,0 +1,29 @@ +package caosdb.server.accessControl; + +import caosdb.server.CaosDBServer; +import org.quartz.CronScheduleBuilder; +import org.quartz.Job; +import org.quartz.JobBuilder; +import org.quartz.JobDetail; +import org.quartz.JobExecutionContext; +import org.quartz.JobExecutionException; +import org.quartz.SchedulerException; +import org.quartz.Trigger; +import org.quartz.TriggerBuilder; + +public class ConsumedInfoCleanupJob implements Job { + + public static void scheduleDaily() throws SchedulerException { + JobDetail job = JobBuilder.newJob(ConsumedInfoCleanupJob.class).build(); + Trigger trigger = + TriggerBuilder.newTrigger() + .withSchedule(CronScheduleBuilder.dailyAtHourAndMinute(0, 0)) + .build(); + CaosDBServer.scheduleJob(job, trigger); + } + + @Override + public void execute(JobExecutionContext context) throws JobExecutionException { + ConsumedInfo.cleanupConsumedInfo(); + } +} diff --git a/src/main/java/caosdb/server/accessControl/OneTimeAuthenticationToken.java b/src/main/java/caosdb/server/accessControl/OneTimeAuthenticationToken.java index 16b48b54dbca9ab0bf51b4001dcee7ddeac42c41..886a7ba33e1ec5a528aa2f9cdb787c8f53168d7f 100644 --- a/src/main/java/caosdb/server/accessControl/OneTimeAuthenticationToken.java +++ b/src/main/java/caosdb/server/accessControl/OneTimeAuthenticationToken.java @@ -51,15 +51,37 @@ import org.quartz.SchedulerException; import org.quartz.Trigger; import org.quartz.TriggerBuilder; -class ConsumedInfoCleanupJob implements Job { +class ConsumedInfo { - @Override - public void execute(JobExecutionContext context) throws JobExecutionException { - OneTimeAuthenticationToken.cleanupConsumedInfo(); + private static Map<String, ConsumedInfo> consumedOneTimeTokens = new HashMap<>(); + + public static void cleanupConsumedInfo() { + synchronized (consumedOneTimeTokens) { + for (Iterator<Map.Entry<String, ConsumedInfo>> it = + consumedOneTimeTokens.entrySet().iterator(); + it.hasNext(); ) { + Map.Entry<String, ConsumedInfo> next = it.next(); + if (next.getValue().isExpired()) { + it.remove(); + } + } + } } -} -class ConsumedInfo { + public static void consume(OneTimeAuthenticationToken oneTimeAuthenticationToken) { + if (oneTimeAuthenticationToken.isValid()) { + String key = ConsumedInfo.getKey(oneTimeAuthenticationToken); + ConsumedInfo consumedInfo = null; + synchronized (consumedOneTimeTokens) { + consumedInfo = consumedOneTimeTokens.get(key); + if (consumedInfo == null) { + consumedInfo = new ConsumedInfo(oneTimeAuthenticationToken); + consumedOneTimeTokens.put(key, consumedInfo); + } + } + consumedInfo.consume(); + } + } private OneTimeAuthenticationToken oneTimeAuthenticationToken; private List<Long> attempts = new LinkedList<>(); @@ -95,6 +117,7 @@ class ConsumedInfo { } else if (getAttemptTimeout() < System.currentTimeMillis()) { throw new AuthenticationException("One-time token attempts timeout expired."); } + // TODO log? attempts.add(System.currentTimeMillis()); } } @@ -113,8 +136,8 @@ public class OneTimeAuthenticationToken extends SelfValidatingAuthenticationToke public static final int DEFAULT_TIMEOUT_MS = Integer.parseInt( CaosDBServer.getServerProperty(ServerProperties.KEY_ONE_TIME_TOKEN_EXPIRES_MS)); + public static final String REALM_NAME = "OneTimeAuthenticationToken"; // TODO move to UserSources - private static Map<String, ConsumedInfo> consumedOneTimeTokens = new HashMap<>(); private long maxAttempts; private long attemptsTimeout; @@ -123,61 +146,28 @@ public class OneTimeAuthenticationToken extends SelfValidatingAuthenticationToke final long date, final long timeout, final String salt, - final String curry, final String checksum, final String[] permissions, final String[] roles, final long maxAttempts, final long attemptsTimeout) { - super(principal, date, timeout, salt, curry, checksum, permissions, roles); + super(principal, date, timeout, salt, checksum, permissions, roles); this.attemptsTimeout = attemptsTimeout; this.maxAttempts = maxAttempts; consume(); } - /** TODO not yet called anywhere */ - public static void cleanupConsumedInfo() { - synchronized (consumedOneTimeTokens) { - for (Iterator<Map.Entry<String, ConsumedInfo>> it = - consumedOneTimeTokens.entrySet().iterator(); - it.hasNext(); ) { - Map.Entry<String, ConsumedInfo> next = it.next(); - if (next.getValue().isExpired()) { - it.remove(); - } - } - } - } - public long getAttemptsTimeout() { return attemptsTimeout; } public void consume() { - consume(this); - } - - public static void consume(OneTimeAuthenticationToken oneTimeAuthenticationToken) { - if (oneTimeAuthenticationToken.isValid()) { - String key = ConsumedInfo.getKey(oneTimeAuthenticationToken); - ConsumedInfo consumedInfo = null; - synchronized (consumedOneTimeTokens) { - consumedInfo = consumedOneTimeTokens.get(key); - if (consumedInfo == null) { - consumedInfo = new ConsumedInfo(oneTimeAuthenticationToken); - consumedOneTimeTokens.put(key, consumedInfo); - } - } - consumedInfo.consume(); - } else { - oneTimeAuthenticationToken.isValid(); - } + ConsumedInfo.consume(this); } public OneTimeAuthenticationToken( final Principal principal, final long timeout, - final String curry, final String[] permissions, final String[] roles, final Long maxAttempts, @@ -185,7 +175,6 @@ public class OneTimeAuthenticationToken extends SelfValidatingAuthenticationToke super( principal, timeout, - curry, permissions, roles, defaultIfNull(maxAttempts, DEFAULT_MAX_ATTEMPTS), @@ -201,7 +190,7 @@ public class OneTimeAuthenticationToken extends SelfValidatingAuthenticationToke * @param curry * @return */ - public static OneTimeAuthenticationToken parse(final Object[] array, final String curry) { + public static OneTimeAuthenticationToken parse(final Object[] array) { final Principal principal = new Principal((String) array[1], (String) array[2]); final String[] roles = toStringArray((Object[]) array[3]); final String[] permissions = toStringArray((Object[]) array[4]); @@ -212,21 +201,11 @@ public class OneTimeAuthenticationToken extends SelfValidatingAuthenticationToke final long maxAttempts = (Long) array[9]; final long attemptsTimeout = (Long) array[10]; return new OneTimeAuthenticationToken( - principal, - date, - timeout, - salt, - curry, - checksum, - permissions, - roles, - maxAttempts, - attemptsTimeout); + principal, date, timeout, salt, checksum, permissions, roles, maxAttempts, attemptsTimeout); } private static OneTimeAuthenticationToken generate( final Principal principal, - final String curry, final String[] permissions, final String[] roles, final long timeout, @@ -234,7 +213,7 @@ public class OneTimeAuthenticationToken extends SelfValidatingAuthenticationToke final long attemptsTimeout) { return new OneTimeAuthenticationToken( - principal, timeout, curry, permissions, roles, maxAttempts, attemptsTimeout); + principal, timeout, permissions, roles, maxAttempts, attemptsTimeout); } public static List<Config> loadConfig(InputStream input) throws Exception { @@ -261,23 +240,22 @@ public class OneTimeAuthenticationToken extends SelfValidatingAuthenticationToke } public static OneTimeAuthenticationToken generate(Config c) { - return generate(c, new Principal(AnonymousAuthenticationToken.PRINCIPAL), null); + return generate(c, new Principal(REALM_NAME, c.getName())); } - public static OneTimeAuthenticationToken generateForPurpose( - String purpose, Subject user, String curry) { + public static OneTimeAuthenticationToken generateForPurpose(String purpose, Subject user) { Config c = purposes.get(purpose); if (c != null) { Principal principal = (Principal) user.getPrincipal(); - return generate(c, principal, curry); + + return generate(c, principal); } return null; } - public static OneTimeAuthenticationToken generate(Config c, Principal principal, String curry) { + public static OneTimeAuthenticationToken generate(Config c, Principal principal) { return generate( principal, - curry, c.getPermissions(), c.getRoles(), c.getTimeout(), @@ -355,9 +333,18 @@ public class OneTimeAuthenticationToken extends SelfValidatingAuthenticationToke private int maxAttempts = 1; private int timeout = DEFAULT_TIMEOUT_MS; private int attemptsTimeout = DEFAULT_ATTEMPTS_TIMEOUT_MS; + private String name = AnonymousAuthenticationToken.PRINCIPAL.getUsername(); public Config() {} + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + public int getTimeout() { return timeout; } @@ -451,22 +438,13 @@ public class OneTimeAuthenticationToken extends SelfValidatingAuthenticationToke } } - public static void initConsumedInfoCleanup() throws SchedulerException { - JobDetail job = JobBuilder.newJob(ConsumedInfoCleanupJob.class).build(); - Trigger trigger = - TriggerBuilder.newTrigger() - .withSchedule(CronScheduleBuilder.dailyAtHourAndMinute(0, 0)) - .build(); - CaosDBServer.scheduleJob(job, trigger); - } - @Override protected void setFields(Object[] fields) { if (fields.length == 2) { this.maxAttempts = (long) fields[0]; this.attemptsTimeout = (long) fields[1]; } else { - throw new InstantiationError("Too few arguments."); + throw new InstantiationError("Too few fields."); } } @@ -479,10 +457,10 @@ public class OneTimeAuthenticationToken extends SelfValidatingAuthenticationToke this.date, this.timeout, this.salt, - this.curry, calcChecksum((Object[]) this.permissions), calcChecksum((Object[]) this.roles), this.maxAttempts, + this.attemptsTimeout, pepper); } diff --git a/src/main/java/caosdb/server/accessControl/SelfValidatingAuthenticationToken.java b/src/main/java/caosdb/server/accessControl/SelfValidatingAuthenticationToken.java index 5de7cb21c52bb498eb0b065f607f3de0110741bc..e65b70efb407ea211f9ed0d5f516a7d17c05eb12 100644 --- a/src/main/java/caosdb/server/accessControl/SelfValidatingAuthenticationToken.java +++ b/src/main/java/caosdb/server/accessControl/SelfValidatingAuthenticationToken.java @@ -31,12 +31,11 @@ import org.eclipse.jetty.util.ajax.JSON; public abstract class SelfValidatingAuthenticationToken extends Principal implements AuthenticationToken { - protected static final transient String PEPPER = Utils.getUID(); + protected static final transient String PEPPER = Utils.getSecureFilename(32); private static final long serialVersionUID = -7212039848895531161L; protected final long date; protected final long timeout; protected final String checksum; - protected final String curry; protected final String salt; protected final String[] permissions; protected final String[] roles; @@ -50,7 +49,9 @@ public abstract class SelfValidatingAuthenticationToken extends Principal } public static final String getFreshSalt() { - return Utils.getUID(); + // salt should be at least 8 octets long. https://www.ietf.org/rfc/rfc2898.txt + // let's double that + return Utils.getSecureFilename(16); } protected static <T> T defaultIfNull(T val, T def) { @@ -65,11 +66,10 @@ public abstract class SelfValidatingAuthenticationToken extends Principal final long date, final long timeout, final String salt, - final String curry, final String checksum, final String[] permissions, final String[] roles) { - this(principal, date, timeout, salt, curry, permissions, roles, checksum, false); + this(principal, date, timeout, salt, permissions, roles, checksum, false); } private SelfValidatingAuthenticationToken( @@ -77,7 +77,6 @@ public abstract class SelfValidatingAuthenticationToken extends Principal final long date, final long timeout, final String salt, - final String curry, final String[] permissions, final String[] roles, String checksum, @@ -87,7 +86,6 @@ public abstract class SelfValidatingAuthenticationToken extends Principal this.date = date; this.timeout = timeout; this.salt = salt; - this.curry = curry; this.permissions = defaultIfNull(permissions, new String[] {}); this.roles = defaultIfNull(roles, new String[] {}); if (fields.length > 0) setFields(fields); @@ -100,7 +98,6 @@ public abstract class SelfValidatingAuthenticationToken extends Principal public SelfValidatingAuthenticationToken( final Principal principal, final long timeout, - final String curry, final String[] permissions, final String[] roles, Object... fields) { @@ -109,7 +106,6 @@ public abstract class SelfValidatingAuthenticationToken extends Principal System.currentTimeMillis(), timeout, getFreshSalt(), - curry, permissions, roles, null, @@ -171,13 +167,13 @@ public abstract class SelfValidatingAuthenticationToken extends Principal return ret; } - public static SelfValidatingAuthenticationToken parse(String token, String curry) { + public static SelfValidatingAuthenticationToken parse(String token) { Object[] array = (Object[]) JSON.parse(token); switch (array[0].toString()) { case "O": - return OneTimeAuthenticationToken.parse(array, curry); + return OneTimeAuthenticationToken.parse(array); default: - return SessionToken.parse(array, curry); + return SessionToken.parse(array); } } diff --git a/src/main/java/caosdb/server/accessControl/SessionToken.java b/src/main/java/caosdb/server/accessControl/SessionToken.java index 5f6753afba662dc8db1b1aab539a78ff36585fff..2e82e3553497e56e4578f45a7768a9f7a5c71b77 100644 --- a/src/main/java/caosdb/server/accessControl/SessionToken.java +++ b/src/main/java/caosdb/server/accessControl/SessionToken.java @@ -34,25 +34,23 @@ public class SessionToken extends SelfValidatingAuthenticationToken { final long date, final long timeout, final String salt, - final String curry, final String checksum, final String[] permissions, final String[] roles) { - super(principal, date, timeout, salt, curry, checksum, permissions, roles); + super(principal, date, timeout, salt, checksum, permissions, roles); } public SessionToken( final Principal principal, final long timeout, - final String curry, final String[] permissions, final String[] roles) { - super(principal, timeout, curry, permissions, roles); + super(principal, timeout, permissions, roles); } private static final long serialVersionUID = 5887135104218573761L; - public static SessionToken parse(final Object[] array, final String curry) { + public static SessionToken parse(final Object[] array) { final Principal principal = new Principal((String) array[1], (String) array[2]); final String[] roles = toStringArray((Object[]) array[3]); final String[] permissions = toStringArray((Object[]) array[4]); @@ -60,21 +58,18 @@ public class SessionToken extends SelfValidatingAuthenticationToken { final long timeout = (Long) array[6]; final String salt = (String) array[7]; final String checksum = (String) array[8]; - return new SessionToken(principal, date, timeout, salt, curry, checksum, permissions, roles); + return new SessionToken(principal, date, timeout, salt, checksum, permissions, roles); } private static SessionToken generate( - final Principal principal, - final String curry, - final String[] permissions, - final String[] roles) { + final Principal principal, final String[] permissions, final String[] roles) { int timeout = Integer.parseInt(CaosDBServer.getServerProperty(ServerProperties.KEY_SESSION_TIMEOUT_MS)); - return new SessionToken(principal, timeout, curry, permissions, roles); + return new SessionToken(principal, timeout, permissions, roles); } - public static SessionToken generate(Subject subject, String curry) { + public static SessionToken generate(Subject subject) { String[] permissions = new String[] {}; String[] roles = new String[] {}; if (subject.getPrincipal() instanceof SelfValidatingAuthenticationToken) { @@ -83,7 +78,7 @@ public class SessionToken extends SelfValidatingAuthenticationToken { permissions = p.getPermissions().toArray(permissions); roles = p.getRoles().toArray(roles); } - return generate((Principal) subject.getPrincipal(), curry, permissions, roles); + return generate((Principal) subject.getPrincipal(), permissions, roles); } @Override @@ -98,7 +93,6 @@ public class SessionToken extends SelfValidatingAuthenticationToken { this.date, this.timeout, this.salt, - this.curry, calcChecksum((Object[]) this.permissions), calcChecksum((Object[]) this.roles), pepper); diff --git a/src/main/java/caosdb/server/permissions/EntityACL.java b/src/main/java/caosdb/server/permissions/EntityACL.java index 426edaba7ca9ab49cbefedcd58d2c9a265b85ed0..e0bfcf9243eb436f9af0d6a3bacfabb79984538c 100644 --- a/src/main/java/caosdb/server/permissions/EntityACL.java +++ b/src/main/java/caosdb/server/permissions/EntityACL.java @@ -92,7 +92,11 @@ public class EntityACL { } public static final EntityACL getOwnerACLFor(final Subject subject) { - if (AuthenticationUtils.isAnonymous(subject)) { + // TODO handle the case where a valid non-guest user (e.g. me@PAM, + // you@CaosDB) is (just temporarily) authenticated via a + // OneTimeAuthenticationToken + if (AuthenticationUtils.isAnonymous(subject) + || AuthenticationUtils.isFromOneTimeTokenRealm(subject)) { return new EntityACLFactory().create(); } return getOwnerACLFor((Principal) subject.getPrincipal()); diff --git a/src/main/java/caosdb/server/resource/AbstractCaosDBServerResource.java b/src/main/java/caosdb/server/resource/AbstractCaosDBServerResource.java index 1d87c4608e7be3ace4aca09eff4d5e0621cc6b9f..d7897450b2caaa7a70f20ead02ed1bb0c67e192d 100644 --- a/src/main/java/caosdb/server/resource/AbstractCaosDBServerResource.java +++ b/src/main/java/caosdb/server/resource/AbstractCaosDBServerResource.java @@ -245,8 +245,10 @@ public abstract class AbstractCaosDBServerResource extends ServerResource { * @param userInfo */ private void addNameAndRealm(Element userInfo, Subject user) { - userInfo.setAttribute("username", ((Principal) user.getPrincipal()).getUsername()); - userInfo.setAttribute("realm", ((Principal) user.getPrincipal()).getRealm()); + if (!AuthenticationUtils.isAnonymous((Principal) user.getPrincipal())) { + userInfo.setAttribute("username", ((Principal) user.getPrincipal()).getUsername()); + userInfo.setAttribute("realm", ((Principal) user.getPrincipal()).getRealm()); + } } @Get diff --git a/src/main/java/caosdb/server/resource/ScriptingResource.java b/src/main/java/caosdb/server/resource/ScriptingResource.java index 715892b0e76c124947ea917d8625b5d2256a2caa..d3827b4544beb16fd9bbaf37dad795be0e36b129 100644 --- a/src/main/java/caosdb/server/resource/ScriptingResource.java +++ b/src/main/java/caosdb/server/resource/ScriptingResource.java @@ -210,11 +210,11 @@ public class ScriptingResource extends AbstractCaosDBServerResource { public Object generateAuthToken(String call) { String purpose = "scripting:" + call; - Object authtoken = OneTimeAuthenticationToken.generateForPurpose(purpose, getUser(), null); + Object authtoken = OneTimeAuthenticationToken.generateForPurpose(purpose, getUser()); if (authtoken != null || isAnonymous()) { return authtoken; } - return SessionToken.generate(getUser(), null); + return SessionToken.generate(getUser()); } public void checkExecutionPermission(Subject user, String call) { diff --git a/src/main/java/caosdb/server/utils/Utils.java b/src/main/java/caosdb/server/utils/Utils.java index 3be0ea6e9c1ad613a04bb8f5ad5c7b7ee13e2f88..d5bb0903de581597b23261e0bb87caa1e9ea7829 100644 --- a/src/main/java/caosdb/server/utils/Utils.java +++ b/src/main/java/caosdb/server/utils/Utils.java @@ -199,6 +199,7 @@ public class Utils { srand.nextBytes(bytes); // Encode to nice letters + // TODO use StringBuilder and iterate over filename.charArray String filename = (new Base32()).encodeToString(bytes); filename = filename.replaceAll("=+", ""); diff --git a/src/test/java/caosdb/server/authentication/AuthTokenTest.java b/src/test/java/caosdb/server/authentication/AuthTokenTest.java index 504c402983c967366a0ec2ff28efc46f2c1f91df..088d8d0e8de1e062ce02f674d5ac56ff902e5631 100644 --- a/src/test/java/caosdb/server/authentication/AuthTokenTest.java +++ b/src/test/java/caosdb/server/authentication/AuthTokenTest.java @@ -85,14 +85,13 @@ public class AuthTokenTest { @Test public void testSessionToken() throws InterruptedException { - final String curry = "somecurry"; + // Token 1 - wrong checksum, not expired final SessionToken t1 = new SessionToken( new Principal("somerealm", "someuser1"), System.currentTimeMillis(), 60000, "345sdf56sdf", - curry, "wrong checksum", null, null); @@ -100,34 +99,16 @@ public class AuthTokenTest { Assert.assertFalse(t1.isHashValid()); Assert.assertFalse(t1.isValid()); - final SessionToken t2 = - new SessionToken( - new Principal("somerealm", "someuser1"), - System.currentTimeMillis(), - 60000, - "345sdf56sdf", - null, - "wrong checksum", - null, - null); - Assert.assertFalse(t2.isExpired()); - Assert.assertFalse(t2.isHashValid()); - Assert.assertFalse(t2.isValid()); - + // Token 3 - correct checksum, not expired final SessionToken t3 = - new SessionToken(new Principal("somerealm", "someuser2"), 60000, curry, null, null); + new SessionToken(new Principal("somerealm", "someuser2"), 60000, null, null); Assert.assertFalse(t3.isExpired()); Assert.assertTrue(t3.isHashValid()); Assert.assertTrue(t3.isValid()); - final SessionToken t4 = - new SessionToken(new Principal("somerealm", "someuser2"), 60000, null, null, null); - Assert.assertFalse(t4.isExpired()); - Assert.assertTrue(t4.isHashValid()); - Assert.assertTrue(t4.isValid()); - + // Token 5 - correct checksum, soon to be expired final SessionToken t5 = - new SessionToken(new Principal("somerealm", "someuser3"), 2000, curry, null, null); + new SessionToken(new Principal("somerealm", "someuser3"), 2000, null, null); Assert.assertFalse(t5.isExpired()); Assert.assertTrue(t5.isHashValid()); Assert.assertTrue(t5.isValid()); @@ -137,96 +118,45 @@ public class AuthTokenTest { Assert.assertTrue(t5.isHashValid()); Assert.assertFalse(t5.isValid()); + // Token 6 - correct checksum, immediately expired final SessionToken t6 = - new SessionToken(new Principal("somerealm", "someuser3"), 0, null, null, null); + new SessionToken(new Principal("somerealm", "someuser3"), 0, null, null); Assert.assertTrue(t6.isExpired()); Assert.assertTrue(t6.isHashValid()); Assert.assertFalse(t6.isValid()); - Assert.assertEquals(t1.toString(), SessionToken.parse(t1.toString(), curry).toString()); - Assert.assertEquals(t2.toString(), SessionToken.parse(t2.toString(), curry).toString()); - Assert.assertEquals(t3.toString(), SessionToken.parse(t3.toString(), curry).toString()); - Assert.assertEquals(t4.toString(), SessionToken.parse(t4.toString(), curry).toString()); - Assert.assertEquals(t5.toString(), SessionToken.parse(t5.toString(), curry).toString()); - Assert.assertEquals(t6.toString(), SessionToken.parse(t6.toString(), curry).toString()); - Assert.assertEquals(t1.toString(), SessionToken.parse(t1.toString(), null).toString()); - Assert.assertEquals(t2.toString(), SessionToken.parse(t2.toString(), null).toString()); - Assert.assertEquals(t3.toString(), SessionToken.parse(t3.toString(), null).toString()); - Assert.assertEquals(t4.toString(), SessionToken.parse(t4.toString(), null).toString()); - Assert.assertEquals(t5.toString(), SessionToken.parse(t5.toString(), null).toString()); - Assert.assertEquals(t6.toString(), SessionToken.parse(t6.toString(), null).toString()); - - Assert.assertFalse(SessionToken.parse(t1.toString(), curry).isHashValid()); - Assert.assertFalse(SessionToken.parse(t2.toString(), null).isHashValid()); - Assert.assertTrue(SessionToken.parse(t3.toString(), curry).isHashValid()); - Assert.assertTrue(SessionToken.parse(t4.toString(), null).isHashValid()); - Assert.assertTrue(SessionToken.parse(t5.toString(), curry).isHashValid()); - Assert.assertTrue(SessionToken.parse(t6.toString(), null).isHashValid()); - Assert.assertFalse(SessionToken.parse(t1.toString(), null).isHashValid()); - Assert.assertFalse(SessionToken.parse(t2.toString(), curry).isHashValid()); - Assert.assertFalse(SessionToken.parse(t3.toString(), null).isHashValid()); - Assert.assertFalse(SessionToken.parse(t4.toString(), curry).isHashValid()); - Assert.assertFalse(SessionToken.parse(t5.toString(), null).isHashValid()); - Assert.assertFalse(SessionToken.parse(t6.toString(), curry).isHashValid()); + Assert.assertEquals(t1.toString(), SessionToken.parse(t1.toString()).toString()); + Assert.assertEquals(t3.toString(), SessionToken.parse(t3.toString()).toString()); + Assert.assertEquals(t5.toString(), SessionToken.parse(t5.toString()).toString()); + Assert.assertEquals(t6.toString(), SessionToken.parse(t6.toString()).toString()); + + Assert.assertFalse(SessionToken.parse(t1.toString()).isHashValid()); + Assert.assertTrue(SessionToken.parse(t3.toString()).isHashValid()); + Assert.assertTrue(SessionToken.parse(t5.toString()).isHashValid()); + Assert.assertTrue(SessionToken.parse(t6.toString()).isHashValid()); Assert.assertFalse( AuthenticationUtils.parseSessionTokenCookie( - AuthenticationUtils.createSessionTokenCookie(t4), null) - .isExpired()); - Assert.assertTrue( - AuthenticationUtils.parseSessionTokenCookie( - AuthenticationUtils.createSessionTokenCookie(t4), null) - .isHashValid()); - Assert.assertTrue( - AuthenticationUtils.parseSessionTokenCookie( - AuthenticationUtils.createSessionTokenCookie(t4), null) - .isValid()); - Assert.assertFalse( - AuthenticationUtils.parseSessionTokenCookie( - AuthenticationUtils.createSessionTokenCookie(t4), curry) - .isExpired()); - Assert.assertFalse( - AuthenticationUtils.parseSessionTokenCookie( - AuthenticationUtils.createSessionTokenCookie(t4), curry) - .isHashValid()); - Assert.assertFalse( - AuthenticationUtils.parseSessionTokenCookie( - AuthenticationUtils.createSessionTokenCookie(t4), curry) - .isValid()); - Assert.assertFalse( - AuthenticationUtils.parseSessionTokenCookie( - AuthenticationUtils.createSessionTokenCookie(t3), null) - .isExpired()); - Assert.assertFalse( - AuthenticationUtils.parseSessionTokenCookie( - AuthenticationUtils.createSessionTokenCookie(t3), null) - .isHashValid()); - Assert.assertFalse( - AuthenticationUtils.parseSessionTokenCookie( - AuthenticationUtils.createSessionTokenCookie(t3), null) - .isValid()); - Assert.assertFalse( - AuthenticationUtils.parseSessionTokenCookie( - AuthenticationUtils.createSessionTokenCookie(t3), curry) + AuthenticationUtils.createSessionTokenCookie(t3)) .isExpired()); Assert.assertTrue( AuthenticationUtils.parseSessionTokenCookie( - AuthenticationUtils.createSessionTokenCookie(t3), curry) + AuthenticationUtils.createSessionTokenCookie(t3)) .isHashValid()); Assert.assertTrue( AuthenticationUtils.parseSessionTokenCookie( - AuthenticationUtils.createSessionTokenCookie(t3), curry) + AuthenticationUtils.createSessionTokenCookie(t3)) .isValid()); + + // TODO parse invalid tokens } @Test public void testOneTimeTokenSerialization() { - final String curry = null; final OneTimeAuthenticationToken t1 = new OneTimeAuthenticationToken( new Principal("somerealm", "someuser"), 60000, - curry, new String[] {"permissions"}, new String[] {"roles"}, 1L, @@ -237,7 +167,7 @@ public class AuthTokenTest { Assert.assertTrue(t1.isValid()); String serialized = t1.toString(); - SelfValidatingAuthenticationToken parsed = OneTimeAuthenticationToken.parse(serialized, curry); + SelfValidatingAuthenticationToken parsed = OneTimeAuthenticationToken.parse(serialized); Assert.assertEquals(t1, parsed); Assert.assertEquals(serialized, parsed.toString()); @@ -250,12 +180,10 @@ public class AuthTokenTest { @Test(expected = AuthenticationException.class) public void testOneTimeTokenConsume() { - final String curry = null; final OneTimeAuthenticationToken t1 = new OneTimeAuthenticationToken( new Principal("somerealm", "someuser"), 60000, - curry, new String[] {"permissions"}, new String[] {"roles"}, 3L, @@ -278,12 +206,10 @@ public class AuthTokenTest { @Test(expected = AuthenticationException.class) public void testOneTimeTokenConsumeByParsing() { - final String curry = null; final OneTimeAuthenticationToken t1 = new OneTimeAuthenticationToken( new Principal("somerealm", "someuser"), 60000, - curry, new String[] {"permissions"}, new String[] {"roles"}, 3L, @@ -294,21 +220,18 @@ public class AuthTokenTest { String serialized = t1.toString(); try { - SelfValidatingAuthenticationToken parsed1 = - OneTimeAuthenticationToken.parse(serialized, curry); + SelfValidatingAuthenticationToken parsed1 = OneTimeAuthenticationToken.parse(serialized); Assert.assertTrue(parsed1.isValid()); - SelfValidatingAuthenticationToken parsed2 = - OneTimeAuthenticationToken.parse(serialized, curry); + SelfValidatingAuthenticationToken parsed2 = OneTimeAuthenticationToken.parse(serialized); Assert.assertTrue(parsed2.isValid()); - SelfValidatingAuthenticationToken parsed3 = - OneTimeAuthenticationToken.parse(serialized, curry); + SelfValidatingAuthenticationToken parsed3 = OneTimeAuthenticationToken.parse(serialized); Assert.assertTrue(parsed3.isValid()); } catch (AuthenticationException e) { Assert.fail(e.getMessage()); } // throws - OneTimeAuthenticationToken.parse(serialized, curry); + OneTimeAuthenticationToken.parse(serialized); Assert.fail("4th parsing should throw"); } @@ -436,10 +359,12 @@ public class AuthTokenTest { Assert.assertTrue(tempFile.exists()); try (BufferedReader reader = new BufferedReader(new FileReader(tempFile))) { OneTimeAuthenticationToken token = - (OneTimeAuthenticationToken) - SelfValidatingAuthenticationToken.parse(reader.readLine(), null); + (OneTimeAuthenticationToken) SelfValidatingAuthenticationToken.parse(reader.readLine()); assertEquals("Token has anonymous username", "anonymous", token.getPrincipal().getUsername()); - assertEquals("Token has anonymous realm", "anonymous", token.getPrincipal().getRealm()); + assertEquals( + "Token has anonymous realm", + OneTimeAuthenticationToken.REALM_NAME, + token.getPrincipal().getRealm()); assertArrayEquals( "Permissions array has been written and read", new String[] {"permission1"}, @@ -461,7 +386,7 @@ public class AuthTokenTest { anonymous.login(AnonymousAuthenticationToken.getInstance()); OneTimeAuthenticationToken token = - OneTimeAuthenticationToken.generateForPurpose("for anonymous", anonymous, null); + OneTimeAuthenticationToken.generateForPurpose("for anonymous", anonymous); assertEquals("anonymous", token.getPrincipal().getUsername()); } @@ -471,8 +396,7 @@ public class AuthTokenTest { OneTimeAuthenticationToken token = OneTimeAuthenticationToken.generate(config); String serialized = token.toString(); - SelfValidatingAuthenticationToken parsed = - SelfValidatingAuthenticationToken.parse(serialized, null); + SelfValidatingAuthenticationToken parsed = SelfValidatingAuthenticationToken.parse(serialized); SessionTokenRealm sessionTokenRealm = new SessionTokenRealm(); Assert.assertTrue(sessionTokenRealm.supports(token));