diff --git a/src/main/java/caosdb/server/accessControl/UserSources.java b/src/main/java/caosdb/server/accessControl/UserSources.java index 44a540da0cb58dadc17ddec7ab596389bf45b3e0..3aea63cb744874d65845b9c82359a76518dfcd3d 100644 --- a/src/main/java/caosdb/server/accessControl/UserSources.java +++ b/src/main/java/caosdb/server/accessControl/UserSources.java @@ -120,6 +120,12 @@ public class UserSources extends HashMap<String, UserSource> { } } + /** + * Return the roles of a given user. + * @param realm + * @param username + * @return + */ public static Set<String> resolve(String realm, final String username) { if (realm == null) { diff --git a/src/main/java/caosdb/server/resource/AbstractCaosDBServerResource.java b/src/main/java/caosdb/server/resource/AbstractCaosDBServerResource.java index 27d81e72f34a48f50253d23b8e22c35781bce037..a9a485459af75cf630d569024a4b0263b8cf82ff 100644 --- a/src/main/java/caosdb/server/resource/AbstractCaosDBServerResource.java +++ b/src/main/java/caosdb/server/resource/AbstractCaosDBServerResource.java @@ -28,6 +28,7 @@ import static java.net.URLDecoder.decode; import caosdb.server.CaosDBException; import caosdb.server.accessControl.AuthenticationUtils; import caosdb.server.accessControl.Principal; +import caosdb.server.accessControl.UserSources; import caosdb.server.database.backend.implementation.MySQL.ConnectionException; import caosdb.server.entity.Message; import caosdb.server.utils.ServerMessages; @@ -74,7 +75,7 @@ public abstract class AbstractCaosDBServerResource extends ServerResource { private Long timestamp = null; private static final XMLParser xmlparser = new XMLParser(); protected String sRID = null; - protected String cRID = null; + private String cRID = null; private String[] requestedItems = null; private ArrayList<Integer> requestedIDs = new ArrayList<Integer>(); private ArrayList<String> requestedNames = new ArrayList<String>(); @@ -109,7 +110,7 @@ public abstract class AbstractCaosDBServerResource extends ServerResource { final Series<Header> headers = getRequest().getHeaders(); - this.cRID = headers.getFirstValue("crequestid"); + this.setCRID(headers.getFirstValue("crequestid")); String specifier = (String) getRequestAttributes().get("specifier"); if (specifier != null && !specifier.equals("")) { @@ -157,21 +158,63 @@ public abstract class AbstractCaosDBServerResource extends ServerResource { protected Element generateRootElement() { final Element retRoot = new Element("Response"); - if (getUser() != null - && getUser().isAuthenticated() - && !getUser().getPrincipal().equals(AuthenticationUtils.ANONYMOUS_USER.getPrincipal())) { - retRoot.setAttribute("username", ((Principal) getUser().getPrincipal()).getUsername()); - retRoot.setAttribute("realm", ((Principal) getUser().getPrincipal()).getRealm()); - } + addUserInfo(retRoot, getUser()); retRoot.setAttribute("srid", getSRID()); - if (this.cRID != null) { - retRoot.setAttribute("crid", this.cRID); + if (this.getCRID() != null) { + retRoot.setAttribute("crid", this.getCRID()); } retRoot.setAttribute("timestamp", getTimestamp().toString()); retRoot.setAttribute("baseuri", getRootRef().toString()); return retRoot; } + /** + * Add the user info to the Response Element. + * @param retRoot + * @param user + */ + private void addUserInfo(Element retRoot, Subject user) { + + if (user != null && user.isAuthenticated()){ + Element userInfo = new Element("UserInfo"); + if(!user.getPrincipal().equals(AuthenticationUtils.ANONYMOUS_USER.getPrincipal())) { + // TODO: deprecated + addNameAndRealm(retRoot, user); + + // this is the new, correct way + addNameAndRealm(userInfo, user); + } + + addRoles(userInfo, user); + } + } + + /** + * Add all roles of the current user to the user info, like this: + * `<UserInfo><Roles><Role>role1</Role><Role>role2</Role>...</Roles></UserInfo>` + * + * @param userInfo + * @param user + */ + private void addRoles(Element userInfo, Subject user) { + Element roles = new Element("Roles"); + for(String role : UserSources.resolve(user.getPrincipals())){ + Element r = new Element("Role"); + r.addContent(role); + roles.addContent(r); + } + userInfo.addContent(roles); + } + + /** + * Add the username and the realm of the current user to the user info (as attributes). + * @param userInfo + */ + private void addNameAndRealm(Element userInfo, Subject user) { + userInfo.setAttribute("username", ((Principal) user.getPrincipal()).getUsername()); + userInfo.setAttribute("realm", ((Principal) user.getPrincipal()).getRealm()); + } + @Get public Representation httpGet() { try { @@ -354,6 +397,14 @@ public abstract class AbstractCaosDBServerResource extends ServerResource { return root; } + public String getCRID() { + return cRID; + } + + public void setCRID(String cRID) { + this.cRID = cRID; + } + public static class XMLParser { private final LinkedList<SAXBuilder> pool = new LinkedList<SAXBuilder>(); private final int max = 25; diff --git a/src/main/java/caosdb/server/resource/TestCaseFileSystemResource.java b/src/main/java/caosdb/server/resource/TestCaseFileSystemResource.java index d239d570db89aa6c86b015a70474fb36c0080dcb..903ef0d5aca9a91eaeaff3693b7f77ef51e6cc46 100644 --- a/src/main/java/caosdb/server/resource/TestCaseFileSystemResource.java +++ b/src/main/java/caosdb/server/resource/TestCaseFileSystemResource.java @@ -58,8 +58,8 @@ public class TestCaseFileSystemResource extends FileSystemResource { retRoot.setAttribute("realm", ((Principal) getUser().getPrincipal()).getRealm()); } retRoot.setAttribute("srid", getSRID()); - if (this.cRID != null) { - retRoot.setAttribute("crid", this.cRID); + if (this.getCRID() != null) { + retRoot.setAttribute("crid", this.getCRID()); } retRoot.setAttribute("timestamp", getTimestamp().toString()); retRoot.setAttribute("baseuri", getRootRef().toString() + "/TestCase/"); diff --git a/src/main/java/caosdb/server/resource/TestCaseResource.java b/src/main/java/caosdb/server/resource/TestCaseResource.java index ed7e546147bd717ebe92821e39abe4e256b470fb..e8aef1f00e57335185b7b204c8de081570e6e188 100644 --- a/src/main/java/caosdb/server/resource/TestCaseResource.java +++ b/src/main/java/caosdb/server/resource/TestCaseResource.java @@ -84,8 +84,8 @@ public class TestCaseResource extends AbstractCaosDBServerResource { retRoot.setAttribute("username", "TestUser"); retRoot.setAttribute("realm", "PAM"); retRoot.setAttribute("srid", getSRID()); - if (this.cRID != null) { - retRoot.setAttribute("crid", this.cRID); + if (this.getCRID() != null) { + retRoot.setAttribute("crid", this.getCRID()); } retRoot.setAttribute("timestamp", getTimestamp().toString()); retRoot.setAttribute("baseuri", getRootRef().toString() + "/TestCase/"); diff --git a/src/test/java/caosdb/server/resource/TestAbstractCaosDBServerResource.java b/src/test/java/caosdb/server/resource/TestAbstractCaosDBServerResource.java new file mode 100644 index 0000000000000000000000000000000000000000..034ac59d255824e9adb4afedfecd7b48c3d7d8df --- /dev/null +++ b/src/test/java/caosdb/server/resource/TestAbstractCaosDBServerResource.java @@ -0,0 +1,74 @@ +package caosdb.server.resource; + +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertEquals; +import java.io.IOException; +import java.security.NoSuchAlgorithmException; +import java.sql.SQLException; +import org.apache.shiro.SecurityUtils; +import org.apache.shiro.authc.SimpleAccount; +import org.apache.shiro.mgt.DefaultSecurityManager; +import org.apache.shiro.session.mgt.DelegatingSession; +import org.apache.shiro.subject.Subject; +import org.apache.shiro.subject.support.DelegatingSubject; +import org.jdom2.Element; +import org.junit.Test; +import org.restlet.data.Reference; +import org.restlet.representation.Representation; +import caosdb.server.CaosDBException; +import caosdb.server.accessControl.AnonymousAuthenticationToken; +import caosdb.server.accessControl.AnonymousRealm; +import caosdb.server.accessControl.CaosDBAuthorizingRealm; +import caosdb.server.database.backend.implementation.MySQL.ConnectionException; + +public class TestAbstractCaosDBServerResource { + + @Test + public void testReponseRootElement(){ + final Subject user = new DelegatingSubject(new DefaultSecurityManager(new AnonymousRealm())); + user.login(AnonymousAuthenticationToken.getInstance()); + AbstractCaosDBServerResource s = new AbstractCaosDBServerResource() { + + @Override + protected Representation httpGetInChildClass() throws ConnectionException, IOException, + SQLException, CaosDBException, NoSuchAlgorithmException, Exception { + // TODO Auto-generated method stub + return null; + } + + @Override + public String getSRID() { + return "TEST-SRID"; + } + + @Override + public String getCRID() { + return "TEST-CRID"; + } + + @Override + public Long getTimestamp() { + return 0L; + } + + @Override + public Reference getRootRef() { + return new Reference("https://example.com/root/"); + } + + @Override + public Subject getUser() { + // TODO Auto-generated method stub + return user; + } + }; + Element response = s.generateRootElement(); + assertNotNull(response); + assertEquals("TEST-SRID", response.getAttribute("srid").getValue()); + assertEquals("TEST-CRID", response.getAttribute("crid").getValue()); + assertEquals("0", response.getAttribute("timestamp").getValue()); + assertEquals("https://example.com/root/", response.getAttributeValue("baseuri")); + Element userInfo = response.getChild("UserInfo"); + assertNotNull(userInfo); + } +}