diff --git a/src/main/java/caosdb/server/accessControl/CaosDBAuthorizingRealm.java b/src/main/java/caosdb/server/accessControl/CaosDBAuthorizingRealm.java index d715acf9c9cadebf9e5d7dde7b8ab3f3685fe231..be557e49c5aef0bc42f548016549c44dc0202e39 100644 --- a/src/main/java/caosdb/server/accessControl/CaosDBAuthorizingRealm.java +++ b/src/main/java/caosdb/server/accessControl/CaosDBAuthorizingRealm.java @@ -68,7 +68,7 @@ public class CaosDBAuthorizingRealm extends AuthorizingRealm { authzInfo.addRoles(principalRoles); } - if (authzInfo.getRoles() != null) { + if (authzInfo.getRoles() != null && !authzInfo.getRoles().isEmpty()) { authzInfo.addObjectPermission( role_permission_resolver.resolvePermissionsInRole(authzInfo.getRoles())); } diff --git a/src/main/java/caosdb/server/accessControl/Config.java b/src/main/java/caosdb/server/accessControl/Config.java new file mode 100644 index 0000000000000000000000000000000000000000..d433a1e90df035e805e46cf5452c1330811ce061 --- /dev/null +++ b/src/main/java/caosdb/server/accessControl/Config.java @@ -0,0 +1,86 @@ +package caosdb.server.accessControl; + +public class Config { + private String[] permissions = {}; + private String[] roles = {}; + private String purpose = null; + private OneTimeTokenToFile output = null; + private int maxAttempts = 1; + private int timeout = OneTimeAuthenticationToken.DEFAULT_TIMEOUT_MS; + private int attemptsTimeout = OneTimeAuthenticationToken.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; + } + + public void setTimeout(int timeout) { + this.timeout = timeout; + } + + public void setAttemptsTimeoutSeconds(int seconds) { + this.setAttemptsTimeout(seconds * 1000); + } + + public void setExpiresAfterSeconds(int seconds) { + this.setTimeout(seconds * 1000); + } + + public void setMaxAttempts(int maxAttempts) { + this.maxAttempts = maxAttempts; + } + + public int getMaxAttempts() { + return maxAttempts; + } + + public String[] getPermissions() { + return permissions; + } + + public String getPurpose() { + return purpose; + } + + public void setPermissions(String[] permissions) { + this.permissions = permissions; + } + + public String[] getRoles() { + return roles; + } + + public void setRoles(String[] roles) { + this.roles = roles; + } + + public void setPurpose(String purpose) { + this.purpose = purpose; + } + + public OneTimeTokenToFile getOutput() { + return output; + } + + public void setOutput(OneTimeTokenToFile output) { + this.output = output; + } + + public int getAttemptsTimeout() { + return attemptsTimeout; + } + + public void setAttemptsTimeout(int attemptsTimeout) { + this.attemptsTimeout = attemptsTimeout; + } +} diff --git a/src/main/java/caosdb/server/accessControl/ConsumedInfoCleanupJob.java b/src/main/java/caosdb/server/accessControl/ConsumedInfoCleanupJob.java index 97652d6f24e74efb1686fe816d0aa83b7b9c2d9f..1f62fa0a8fc72604d885c24123c3d0c17cb49a0a 100644 --- a/src/main/java/caosdb/server/accessControl/ConsumedInfoCleanupJob.java +++ b/src/main/java/caosdb/server/accessControl/ConsumedInfoCleanupJob.java @@ -24,6 +24,6 @@ public class ConsumedInfoCleanupJob implements Job { @Override public void execute(JobExecutionContext context) throws JobExecutionException { - ConsumedInfo.cleanupConsumedInfo(); + OneTimeTokenConsumedInfo.cleanupConsumedInfo(); } } diff --git a/src/main/java/caosdb/server/accessControl/OneTimeAuthenticationToken.java b/src/main/java/caosdb/server/accessControl/OneTimeAuthenticationToken.java index 886a7ba33e1ec5a528aa2f9cdb787c8f53168d7f..464ae410f353d4c2890386a0d074fc19ed904c83 100644 --- a/src/main/java/caosdb/server/accessControl/OneTimeAuthenticationToken.java +++ b/src/main/java/caosdb/server/accessControl/OneTimeAuthenticationToken.java @@ -31,101 +31,14 @@ import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; -import java.io.PrintWriter; import java.util.HashMap; import java.util.Iterator; import java.util.LinkedList; import java.util.List; import java.util.Map; -import org.apache.shiro.authc.AuthenticationException; import org.apache.shiro.subject.Subject; import org.eclipse.jetty.util.ajax.JSON; -import org.quartz.CronScheduleBuilder; -import org.quartz.Job; -import org.quartz.JobBuilder; -import org.quartz.JobDataMap; -import org.quartz.JobDetail; -import org.quartz.JobExecutionContext; -import org.quartz.JobExecutionException; import org.quartz.SchedulerException; -import org.quartz.Trigger; -import org.quartz.TriggerBuilder; - -class ConsumedInfo { - - 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(); - } - } - } - } - - 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<>(); - - public ConsumedInfo(OneTimeAuthenticationToken oneTimeAuthenticationToken) { - this.oneTimeAuthenticationToken = oneTimeAuthenticationToken; - } - - public static String getKey(OneTimeAuthenticationToken token) { - return token.checksum; - } - - private int getNoOfAttempts() { - return attempts.size(); - } - - private long getMaxAttempts() { - return oneTimeAuthenticationToken.getMaxAttempts(); - } - - private long getAttemptTimeout() { - if (attempts.size() == 0) { - return Long.MAX_VALUE; - } - long firstAttemptTime = attempts.get(0); - return firstAttemptTime + oneTimeAuthenticationToken.getAttemptsTimeout(); - } - - public void consume() { - synchronized (attempts) { - if (getNoOfAttempts() >= getMaxAttempts()) { - throw new AuthenticationException("One-time token was consumed too often."); - } else if (getAttemptTimeout() < System.currentTimeMillis()) { - throw new AuthenticationException("One-time token attempts timeout expired."); - } - // TODO log? - attempts.add(System.currentTimeMillis()); - } - } - - public boolean isExpired() { - return oneTimeAuthenticationToken.isExpired(); - } -} public class OneTimeAuthenticationToken extends SelfValidatingAuthenticationToken { @@ -162,7 +75,7 @@ public class OneTimeAuthenticationToken extends SelfValidatingAuthenticationToke } public void consume() { - ConsumedInfo.consume(this); + OneTimeTokenConsumedInfo.consume(this); } public OneTimeAuthenticationToken( @@ -265,151 +178,6 @@ public class OneTimeAuthenticationToken extends SelfValidatingAuthenticationToke static Map<String, Config> purposes = new HashMap<>(); - public static class Output implements Job { - private String file = null; - private String schedule = null; - - public Output() {} - - public static void output(OneTimeAuthenticationToken t, String file) throws IOException { - try (PrintWriter writer = new PrintWriter(file, "utf-8")) { - writer.println(t.toString()); - } - } - - public String getFile() { - return file; - } - - public void setFile(String file) { - this.file = file; - } - - public String getSchedule() { - return schedule; - } - - public void setSchedule(String schedule) { - this.schedule = schedule; - } - - public void init(Config config) throws IOException, SchedulerException { - - if (this.schedule != null) { - generate(config); // test config - JobDataMap map = new JobDataMap(); - map.put("config", config); - map.put("file", file); - JobDetail outputJob = JobBuilder.newJob(Output.class).setJobData(map).build(); - Trigger trigger = - TriggerBuilder.newTrigger() - .withIdentity(config.toString()) - .withSchedule(CronScheduleBuilder.cronSchedule(this.schedule)) - .build(); - CaosDBServer.scheduleJob(outputJob, trigger); - } else { - output(generate(config), file); - } - } - - @Override - public void execute(JobExecutionContext context) throws JobExecutionException { - Config config = (Config) context.getMergedJobDataMap().get("config"); - String file = context.getMergedJobDataMap().getString("file"); - try { - output(generate(config), file); - } catch (IOException e) { - // TODO log - e.printStackTrace(); - } - } - } - - public static class Config { - private String[] permissions = {}; - private String[] roles = {}; - private String purpose = null; - private Output output = null; - 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; - } - - public void setTimeout(int timeout) { - this.timeout = timeout; - } - - public void setAttemptsTimeoutSeconds(int seconds) { - this.setAttemptsTimeout(seconds * 1000); - } - - public void setExpiresAfterSeconds(int seconds) { - this.setTimeout(seconds * 1000); - } - - public void setMaxAttempts(int maxAttempts) { - this.maxAttempts = maxAttempts; - } - - public int getMaxAttempts() { - return maxAttempts; - } - - public String[] getPermissions() { - return permissions; - } - - public String getPurpose() { - return purpose; - } - - public void setPermissions(String[] permissions) { - this.permissions = permissions; - } - - public String[] getRoles() { - return roles; - } - - public void setRoles(String[] roles) { - this.roles = roles; - } - - public void setPurpose(String purpose) { - this.purpose = purpose; - } - - public Output getOutput() { - return output; - } - - public void setOutput(Output output) { - this.output = output; - } - - public int getAttemptsTimeout() { - return attemptsTimeout; - } - - public void setAttemptsTimeout(int attemptsTimeout) { - this.attemptsTimeout = attemptsTimeout; - } - } - public static Map<String, Config> getPurposeMap() { return purposes; } diff --git a/src/main/java/caosdb/server/accessControl/OneTimeTokenConsumedInfo.java b/src/main/java/caosdb/server/accessControl/OneTimeTokenConsumedInfo.java new file mode 100644 index 0000000000000000000000000000000000000000..a7122c2b28ed38baaf60c8da6b404b1fcf97c349 --- /dev/null +++ b/src/main/java/caosdb/server/accessControl/OneTimeTokenConsumedInfo.java @@ -0,0 +1,83 @@ +package caosdb.server.accessControl; + +import java.util.HashMap; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import org.apache.shiro.authc.AuthenticationException; + +class OneTimeTokenConsumedInfo { + + private static Map<String, OneTimeTokenConsumedInfo> consumedOneTimeTokens = new HashMap<>(); + + public static void cleanupConsumedInfo() { + synchronized (consumedOneTimeTokens) { + for (Iterator<Map.Entry<String, OneTimeTokenConsumedInfo>> it = + consumedOneTimeTokens.entrySet().iterator(); + it.hasNext(); ) { + Map.Entry<String, OneTimeTokenConsumedInfo> next = it.next(); + if (next.getValue().isExpired()) { + it.remove(); + } + } + } + } + + public static void consume(OneTimeAuthenticationToken oneTimeAuthenticationToken) { + if (oneTimeAuthenticationToken.isValid()) { + String key = OneTimeTokenConsumedInfo.getKey(oneTimeAuthenticationToken); + OneTimeTokenConsumedInfo consumedInfo = null; + synchronized (consumedOneTimeTokens) { + consumedInfo = consumedOneTimeTokens.get(key); + if (consumedInfo == null) { + consumedInfo = new OneTimeTokenConsumedInfo(oneTimeAuthenticationToken); + consumedOneTimeTokens.put(key, consumedInfo); + } + } + consumedInfo.consume(); + } + } + + private OneTimeAuthenticationToken oneTimeAuthenticationToken; + private List<Long> attempts = new LinkedList<>(); + + public OneTimeTokenConsumedInfo(OneTimeAuthenticationToken oneTimeAuthenticationToken) { + this.oneTimeAuthenticationToken = oneTimeAuthenticationToken; + } + + public static String getKey(OneTimeAuthenticationToken token) { + return token.checksum; + } + + private int getNoOfAttempts() { + return attempts.size(); + } + + private long getMaxAttempts() { + return oneTimeAuthenticationToken.getMaxAttempts(); + } + + private long getAttemptTimeout() { + if (attempts.size() == 0) { + return Long.MAX_VALUE; + } + long firstAttemptTime = attempts.get(0); + return firstAttemptTime + oneTimeAuthenticationToken.getAttemptsTimeout(); + } + + public void consume() { + synchronized (attempts) { + if (getNoOfAttempts() >= getMaxAttempts()) { + throw new AuthenticationException("One-time token was consumed too often."); + } else if (getAttemptTimeout() < System.currentTimeMillis()) { + throw new AuthenticationException("One-time token attempts timeout expired."); + } + attempts.add(System.currentTimeMillis()); + } + } + + public boolean isExpired() { + return oneTimeAuthenticationToken.isExpired(); + } +} diff --git a/src/main/java/caosdb/server/accessControl/OneTimeTokenRealm.java b/src/main/java/caosdb/server/accessControl/OneTimeTokenRealm.java deleted file mode 100644 index 1f7d4da4a45a75368fc0d76ae35ad06ad80da92e..0000000000000000000000000000000000000000 --- a/src/main/java/caosdb/server/accessControl/OneTimeTokenRealm.java +++ /dev/null @@ -1,55 +0,0 @@ -/// * -// * ** header v3.0 -// * This file is a part of the CaosDB Project. -// * -// * Copyright (C) 2018 Research Group Biomedical Physics, -// * Max-Planck-Institute for Dynamics and Self-Organization Göttingen -// * -// * This program is free software: you can redistribute it and/or modify -// * it under the terms of the GNU Affero General Public License as -// * published by the Free Software Foundation, either version 3 of the -// * License, or (at your option) any later version. -// * -// * This program is distributed in the hope that it will be useful, -// * but WITHOUT ANY WARRANTY; without even the implied warranty of -// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// * GNU Affero General Public License for more details. -// * -// * You should have received a copy of the GNU Affero General Public License -// * along with this program. If not, see <https://www.gnu.org/licenses/>. -// * -// * ** end header -// */ -// package caosdb.server.accessControl; -// -// import caosdb.server.accessControl.CaosDBAuthorizingRealm.PermissionAuthenticationInfo; -// import org.apache.shiro.authc.AuthenticationException; -// import org.apache.shiro.authc.AuthenticationInfo; -// import org.apache.shiro.authc.AuthenticationToken; -// import org.apache.shiro.authc.credential.AllowAllCredentialsMatcher; -// -// public class OneTimeTokenRealm extends SessionTokenRealm { -// -// @Override -// protected AuthenticationInfo doGetAuthenticationInfo(final AuthenticationToken token) -// throws AuthenticationException { -// -// final AuthenticationInfo info = super.doGetAuthenticationInfo(token); -// if (info != null) { -// return new PermissionAuthenticationInfo( -// info.getPrincipals(), -// ((OneTimeAuthenticationToken) token).getPermissions(), -// ((OneTimeAuthenticationToken) token).getRoles()); -// } -// -// return null; -// } -// -// public OneTimeTokenRealm() { -// setAuthenticationTokenClass(OneTimeAuthenticationToken.class); -// setCredentialsMatcher(new AllowAllCredentialsMatcher()); -// setCachingEnabled(false); -// setAuthenticationCachingEnabled(false); -// // setAuthorizationCachingEnabled(false); -// } -// } diff --git a/src/main/java/caosdb/server/accessControl/OneTimeTokenToFile.java b/src/main/java/caosdb/server/accessControl/OneTimeTokenToFile.java new file mode 100644 index 0000000000000000000000000000000000000000..ea56899a827289e1b9b440ca67a26e414d50221a --- /dev/null +++ b/src/main/java/caosdb/server/accessControl/OneTimeTokenToFile.java @@ -0,0 +1,75 @@ +package caosdb.server.accessControl; + +import caosdb.server.CaosDBServer; +import java.io.IOException; +import java.io.PrintWriter; +import org.quartz.CronScheduleBuilder; +import org.quartz.Job; +import org.quartz.JobBuilder; +import org.quartz.JobDataMap; +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 OneTimeTokenToFile implements Job { + private String file = null; + private String schedule = null; + + public OneTimeTokenToFile() {} + + public static void output(OneTimeAuthenticationToken t, String file) throws IOException { + try (PrintWriter writer = new PrintWriter(file, "utf-8")) { + writer.println(t.toString()); + } + } + + public String getFile() { + return file; + } + + public void setFile(String file) { + this.file = file; + } + + public String getSchedule() { + return schedule; + } + + public void setSchedule(String schedule) { + this.schedule = schedule; + } + + public void init(Config config) throws IOException, SchedulerException { + + if (this.schedule != null) { + OneTimeAuthenticationToken.generate(config); // test config + JobDataMap map = new JobDataMap(); + map.put("config", config); + map.put("file", file); + JobDetail outputJob = JobBuilder.newJob(OneTimeTokenToFile.class).setJobData(map).build(); + Trigger trigger = + TriggerBuilder.newTrigger() + .withIdentity(config.toString()) + .withSchedule(CronScheduleBuilder.cronSchedule(this.schedule)) + .build(); + CaosDBServer.scheduleJob(outputJob, trigger); + } else { + output(OneTimeAuthenticationToken.generate(config), file); + } + } + + @Override + public void execute(JobExecutionContext context) throws JobExecutionException { + Config config = (Config) context.getMergedJobDataMap().get("config"); + String file = context.getMergedJobDataMap().getString("file"); + try { + output(OneTimeAuthenticationToken.generate(config), file); + } catch (IOException e) { + // TODO log + e.printStackTrace(); + } + } +} diff --git a/src/test/java/caosdb/server/authentication/AuthTokenTest.java b/src/test/java/caosdb/server/authentication/AuthTokenTest.java index 088d8d0e8de1e062ce02f674d5ac56ff902e5631..b8b1da51cc78202f2e487662bc6a8260df4fa61b 100644 --- a/src/test/java/caosdb/server/authentication/AuthTokenTest.java +++ b/src/test/java/caosdb/server/authentication/AuthTokenTest.java @@ -29,8 +29,8 @@ import caosdb.server.CaosDBServer; import caosdb.server.ServerProperties; import caosdb.server.accessControl.AnonymousAuthenticationToken; import caosdb.server.accessControl.AuthenticationUtils; +import caosdb.server.accessControl.Config; import caosdb.server.accessControl.OneTimeAuthenticationToken; -import caosdb.server.accessControl.OneTimeAuthenticationToken.Config; import caosdb.server.accessControl.Principal; import caosdb.server.accessControl.SelfValidatingAuthenticationToken; import caosdb.server.accessControl.SessionToken; diff --git a/src/test/java/caosdb/server/permissions/EntityACLTest.java b/src/test/java/caosdb/server/permissions/EntityACLTest.java index d62cb625c8319e676614bf6770eea2f9794daaee..1953896719c5cf5eb202cf48c186a8192c4136db 100644 --- a/src/test/java/caosdb/server/permissions/EntityACLTest.java +++ b/src/test/java/caosdb/server/permissions/EntityACLTest.java @@ -24,17 +24,9 @@ package caosdb.server.permissions; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; - -import caosdb.server.CaosDBServer; -import caosdb.server.accessControl.AnonymousAuthenticationToken; -import caosdb.server.accessControl.AuthenticationUtils; -import caosdb.server.accessControl.OneTimeAuthenticationToken; -import caosdb.server.accessControl.OneTimeAuthenticationToken.Config; -import caosdb.server.resource.AbstractCaosDBServerResource; -import caosdb.server.resource.AbstractCaosDBServerResource.XMLParser; -import caosdb.server.utils.Utils; import java.io.IOException; import java.util.BitSet; +import java.util.HashSet; import java.util.LinkedList; import org.apache.shiro.SecurityUtils; import org.apache.shiro.subject.Subject; @@ -43,6 +35,21 @@ import org.jdom2.JDOMException; import org.junit.Assert; import org.junit.BeforeClass; import org.junit.Test; +import caosdb.server.CaosDBServer; +import caosdb.server.accessControl.AnonymousAuthenticationToken; +import caosdb.server.accessControl.AuthenticationUtils; +import caosdb.server.accessControl.Config; +import caosdb.server.accessControl.OneTimeAuthenticationToken; +import caosdb.server.accessControl.Role; +import caosdb.server.database.BackendTransaction; +import caosdb.server.database.access.Access; +import caosdb.server.database.backend.interfaces.RetrievePermissionRulesImpl; +import caosdb.server.database.backend.interfaces.RetrieveRoleImpl; +import caosdb.server.database.exceptions.TransactionException; +import caosdb.server.database.misc.TransactionBenchmark; +import caosdb.server.resource.AbstractCaosDBServerResource; +import caosdb.server.resource.AbstractCaosDBServerResource.XMLParser; +import caosdb.server.utils.Utils; public class EntityACLTest { @@ -54,11 +61,53 @@ public class EntityACLTest { return value; } + /** a no-op mock-up which resolved all rules to an empty set of permissions. */ + public static class RetrievePermissionRulesMockup implements RetrievePermissionRulesImpl { + + public RetrievePermissionRulesMockup(Access a) {} + + @Override + public void setTransactionBenchmark(TransactionBenchmark b) {} + + @Override + public TransactionBenchmark getBenchmark() { + return null; + } + + @Override + public HashSet<PermissionRule> retrievePermissionRule(String role) throws TransactionException { + return new HashSet<>(); + } + } + + /** a mock-up which returns null */ + public static class RetrieveRoleMockup implements RetrieveRoleImpl { + + public RetrieveRoleMockup(Access a) {} + + @Override + public void setTransactionBenchmark(TransactionBenchmark b) {} + + @Override + public TransactionBenchmark getBenchmark() { + return null; + } + + @Override + public Role retrieve(String role) throws TransactionException { + return null; + } + } + @BeforeClass public static void init() throws IOException { CaosDBServer.initServerProperties(); CaosDBServer.initShiro(); assertNotNull(EntityACL.GLOBAL_PERMISSIONS); + + BackendTransaction.setImpl( + RetrievePermissionRulesImpl.class, RetrievePermissionRulesMockup.class); + BackendTransaction.setImpl(RetrieveRoleImpl.class, RetrieveRoleMockup.class); } @Test diff --git a/src/test/java/caosdb/server/resource/TestAbstractCaosDBServerResource.java b/src/test/java/caosdb/server/resource/TestAbstractCaosDBServerResource.java index 81baabd4797842f1cbbc61f990d6ea580553de85..e9a7cffc66e4c18551ea3375a87489e2b15dc279 100644 --- a/src/test/java/caosdb/server/resource/TestAbstractCaosDBServerResource.java +++ b/src/test/java/caosdb/server/resource/TestAbstractCaosDBServerResource.java @@ -2,18 +2,12 @@ package caosdb.server.resource; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; - -import caosdb.server.CaosDBException; -import caosdb.server.CaosDBServer; -import caosdb.server.ServerProperties; -import caosdb.server.accessControl.AnonymousAuthenticationToken; -import caosdb.server.accessControl.AnonymousRealm; -import caosdb.server.database.backend.implementation.MySQL.ConnectionException; import java.io.IOException; import java.nio.file.Files; import java.nio.file.Paths; import java.security.NoSuchAlgorithmException; import java.sql.SQLException; +import java.util.HashSet; import org.apache.shiro.mgt.DefaultSecurityManager; import org.apache.shiro.subject.Subject; import org.apache.shiro.subject.support.DelegatingSubject; @@ -24,14 +18,70 @@ import org.junit.Test; import org.junit.rules.TemporaryFolder; import org.restlet.data.Reference; import org.restlet.representation.Representation; +import caosdb.server.CaosDBException; +import caosdb.server.CaosDBServer; +import caosdb.server.ServerProperties; +import caosdb.server.accessControl.AnonymousAuthenticationToken; +import caosdb.server.accessControl.AnonymousRealm; +import caosdb.server.accessControl.Role; +import caosdb.server.database.BackendTransaction; +import caosdb.server.database.access.Access; +import caosdb.server.database.backend.implementation.MySQL.ConnectionException; +import caosdb.server.database.backend.interfaces.RetrievePermissionRulesImpl; +import caosdb.server.database.backend.interfaces.RetrieveRoleImpl; +import caosdb.server.database.exceptions.TransactionException; +import caosdb.server.database.misc.TransactionBenchmark; +import caosdb.server.permissions.PermissionRule; public class TestAbstractCaosDBServerResource { @Rule public TemporaryFolder tempFolder = new TemporaryFolder(); + /** a no-op mock-up which resolved all rules to an empty set of permissions. */ + public static class RetrievePermissionRulesMockup implements RetrievePermissionRulesImpl { + + public RetrievePermissionRulesMockup(Access a) {} + + @Override + public void setTransactionBenchmark(TransactionBenchmark b) {} + + @Override + public TransactionBenchmark getBenchmark() { + return null; + } + + @Override + public HashSet<PermissionRule> retrievePermissionRule(String role) throws TransactionException { + return new HashSet<>(); + } + } + + /** a no-op mock-up which returns null */ + public static class RetrieveRoleMockup implements RetrieveRoleImpl { + + public RetrieveRoleMockup(Access a) {} + + @Override + public void setTransactionBenchmark(TransactionBenchmark b) {} + + @Override + public TransactionBenchmark getBenchmark() { + return null; + } + + @Override + public Role retrieve(String role) throws TransactionException { + return null; + } + } + @BeforeClass public static void initServerProperties() throws IOException { CaosDBServer.initServerProperties(); + + BackendTransaction.setImpl( + RetrievePermissionRulesImpl.class, RetrievePermissionRulesMockup.class); + BackendTransaction.setImpl(RetrieveRoleImpl.class, RetrieveRoleMockup.class); } @Test diff --git a/src/test/java/caosdb/server/utils/WebinterfaceUtilsTest.java b/src/test/java/caosdb/server/utils/WebinterfaceUtilsTest.java index 22dc38c7636ba26060cc58d14f5d4cf5b5774400..075c8d998acdfc7f897f9429de468034a4dc022e 100644 --- a/src/test/java/caosdb/server/utils/WebinterfaceUtilsTest.java +++ b/src/test/java/caosdb/server/utils/WebinterfaceUtilsTest.java @@ -29,7 +29,9 @@ public class WebinterfaceUtilsTest { String ref = utils.getWebinterfaceURI("sub"); String contextRoot = CaosDBServer.getServerProperty(ServerProperties.KEY_CONTEXT_ROOT); contextRoot = - contextRoot != null ? "/" + contextRoot.replaceFirst("^/", "").replaceFirst("/$", "") : ""; + contextRoot != null && contextRoot.length() > 0 + ? "/" + contextRoot.replaceFirst("^/", "").replaceFirst("/$", "") + : ""; assertEquals("https://host:2345" + contextRoot + "/webinterface/" + buildNumber + "/sub", ref); }