Skip to Content.
Sympa Menu

idok-commit - [idok-commit] idok commit r187 - in branches/rest/java/ch/idok/service/server: admin/rest rest

idok-commit AT lists.psi.ch

Subject: Commit emails of the iDok project

List archive

[idok-commit] idok commit r187 - in branches/rest/java/ch/idok/service/server: admin/rest rest


Chronological Thread 
  • From: "AFS account Roman Geus" <geus AT savannah.psi.ch>
  • To: idok-commit AT lists.psi.ch
  • Subject: [idok-commit] idok commit r187 - in branches/rest/java/ch/idok/service/server: admin/rest rest
  • Date: Tue, 26 Aug 2008 17:33:00 +0200
  • List-archive: <https://lists.web.psi.ch/pipermail/idok-commit/>
  • List-id: Commit emails of the iDok project <idok-commit.lists.psi.ch>

Author: geus
Date: Tue Aug 26 17:33:00 2008
New Revision: 187

Log:
Added draft of REST admin service

Added:
branches/rest/java/ch/idok/service/server/admin/rest/

branches/rest/java/ch/idok/service/server/admin/rest/RestAdminServiceResource.java
Modified:
branches/rest/java/ch/idok/service/server/rest/IdokAppConfig.java
branches/rest/java/ch/idok/service/server/rest/RestServer.java

Added:
branches/rest/java/ch/idok/service/server/admin/rest/RestAdminServiceResource.java
==============================================================================
--- (empty file)
+++
branches/rest/java/ch/idok/service/server/admin/rest/RestAdminServiceResource.java
Tue Aug 26 17:33:00 2008
@@ -0,0 +1,363 @@
+package ch.idok.service.server.admin.rest;
+
+import java.io.File;
+import java.io.FileReader;
+import java.security.AccessControlException;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import javax.security.auth.Subject;
+import javax.ws.rs.GET;
+import javax.ws.rs.PUT;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.SecurityContext;
+import javax.ws.rs.core.UriInfo;
+
+import ch.idok.common.errorhandling.DmsException;
+import ch.idok.common.errorhandling.ErrorType;
+import ch.idok.common.util.AuthUtil;
+import ch.idok.common.util.DmsCredentials;
+import ch.idok.common.util.DmsPermission;
+import ch.idok.service.server.admin.Admin;
+import ch.idok.service.server.admin.PermissionAdapter;
+import ch.idok.service.server.admin.PermissionAdapterFactory;
+import ch.idok.service.server.rest.IdokNegotiateFilter;
+import ch.idok.service.server.rest.RestServer;
+
+@Path("admin")
+public class RestAdminServiceResource {
+
+ /**
+ * Adapter responsible for all access to the auth db
+ */
+ static PermissionAdapter adapter;
+
+ static Logger logger;
+
+ /**
+ * Provides both static and dynamic, per-request information, about the
+ * components of a request URI.
+ */
+ @Context
+ UriInfo uriInfo;
+
+ /**
+ * JAX-RS security context
+ */
+ @Context
+ SecurityContext securityContext;
+
+ static public void init(RestServer server) throws DmsException {
+ adapter = PermissionAdapterFactory.getAdapter();
+ logger = server.getLogger();
+ }
+
+ @GET
+ @Produces("text/html")
+ public Response getRoot() {
+ try {
+ logger.entering(this.getClass().getName(), "project");
+
+ DmsCredentials cred = null;
+ if (securityContext.getUserPrincipal() != null) {
+ cred = IdokNegotiateFilter.getDmsCredentials();
+ }
+
+ StringBuilder sb = new StringBuilder();
+ sb
+ .append("<?xml version=\"1.0\"?> <!DOCTYPE html PUBLIC
\"-//W3C//DTD XHTML 1.1//EN\"
\"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd\";> <html
xmlns=\"http://www.w3.org/1999/xhtml\"; xml:lang=\"en\">");
+ sb.append("<head><title>Root resource</title></head>");
+
+ // List of projects
+ sb.append("<p>List of projects:</p><ul>");
+ // Loop over all repositories within the project
+ for (String project : Admin.listProjects()) {
+ // TODO Also display allowed action
+ try {
+ DmsPermission p = new DmsPermission(project, "read");
+ adapter.checkPermission(cred.getSubject(), p);
+ sb.append(String.format(
+ "<li><a class=\"project\"
href=\"%s\">%s</a></li>",
+ getProjectURI(project), project));
+ } catch (AccessControlException e) {
+ }
+ }
+ sb.append("</ul>");
+ sb.append("</html>");
+ return Response.ok().entity(sb).build();
+ } catch (Exception e) {
+ logger.log(Level.FINER, "Error in REST call", e);
+ return Response.serverError().entity("DmsException: " +
e).build();
+ }
+
+ }
+
+ @PUT
+ @Path("")
+ @Produces("text/plain")
+ public Response putRoot() throws Exception {
+ // TODO make configurable
+ final String masterAdminName = "geus";
+
+ try {
+ logger.entering(this.getClass().getName(), "putRoot");
+
+ Subject subject = aa(null);
+ String authUser = AuthUtil.getStrippedName(AuthUtil
+ .getUserPrincipal(subject));
+ if (!(masterAdminName.equals(authUser))) {
+ logger
+ .finer(authUser
+ + " does not have sufficient permissions for
this operation");
+ throw new DmsException(
+ ErrorType.AUTHENTICATION,
+ null,
+ "Permission denied",
+ authUser
+ + " does not have sufficient permissions for
this operation");
+ }
+ adapter.initAuthDB(masterAdminName);
+ // apacheConfUpdaterThread_.forceUpdate();
+ return Response.ok().entity("success").build();
+ } catch (Throwable e) {
+ logger.log(Level.WARNING, e.getMessage(), e);
+ return Response.serverError().entity("DmsException: " +
e).build();
+ }
+ }
+
+ @GET
+ @Path("{project}")
+ @Produces("text/html")
+ public Response getProject(@PathParam("project") String project) {
+ try {
+ logger.entering(this.getClass().getName(), "project", project);
+
+ Admin.validateName(project);
+ Subject subject = aa(new DmsPermission(project, "read"));
+
+ StringBuilder sb = new StringBuilder();
+ sb
+ .append("<?xml version=\"1.0\"?> <!DOCTYPE html PUBLIC
\"-//W3C//DTD XHTML 1.1//EN\"
\"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd\";> <html
xmlns=\"http://www.w3.org/1999/xhtml\"; xml:lang=\"en\">");
+ sb.append(String.format("<head><title>Project %s</title></head>",
+ project));
+
+ // List of repositories
+ sb.append(String.format("<p>Repositories of project %s:</p><ul>",
+ project));
+ // Loop over all repositories within the project
+ for (String repository : Admin.listRepositories(project)) {
+ try {
+ String task = project + "/" + repository;
+ DmsPermission p = new DmsPermission(task, "read");
+ adapter.checkPermission(subject, p);
+ sb
+ .append(String
+ .format(
+ "<li><a class=\"repository\"
href=\"%s\">%s</a></li>",
+ getRepositoryURI(project,
+ repository),
repository));
+ } catch (AccessControlException e) {
+ }
+ }
+ sb.append("</ul>");
+
+ // Quota
+ sb
+ .append(String
+ .format(
+ "<p>Quota of project %s is <span
class=\"quota\">%d</span></p>",
+ project, -1));
+
+ sb.append("</html>");
+ return Response.ok().entity(sb).build();
+ } catch (Exception e) {
+ logger.log(Level.FINER, "Error in REST call", e);
+
+ return Response.serverError().entity("DmsException: " +
e).build();
+ }
+
+ }
+
+ @GET
+ @Path(value="{project}/{repository}", limited=true)
+ @Produces("text/html")
+ public Response getRepository(@PathParam("project") String project,
+ @PathParam("repository") String repository) {
+ try {
+ logger.entering(this.getClass().getName(), "repository",
+ new Object[] { project, repository });
+
+ Admin.validateName(project);
+ Admin.validateName(repository);
+ aa(new DmsPermission(project + "/" + repository, "read"));
+
+ StringBuilder sb = new StringBuilder();
+ sb
+ .append("<?xml version=\"1.0\"?> <!DOCTYPE html PUBLIC
\"-//W3C//DTD XHTML 1.1//EN\"
\"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd\";> <html
xmlns=\"http://www.w3.org/1999/xhtml\"; xml:lang=\"en\">");
+ sb.append(String.format(
+ "<head><title>Repository %s</title></head>",
repository));
+
+ // Parent project
+ sb
+ .append(String
+ .format(
+ "<p>Belongs to project <a
class=\"parent_project\" href=\"%s\">%s</a>.</p>",
+ getProjectURI(project), project));
+
+ // Schemas
+ sb.append(String.format(
+ "<p>Schemas associated with repository %s:</p><ul>",
+ repository));
+ // Loop over all schemas
+ for (String schema : Admin.listSchemas(project, repository)) {
+ sb.append(String.format(
+ "<li><a class=\"schema\" href=\"%s\">%s</a></li>",
+ getSchemaURI(project, repository, schema), schema));
+ }
+ sb.append("</ul>");
+
+ sb.append("</html>");
+ return Response.ok().entity(sb).build();
+ } catch (Exception e) {
+ logger.log(Level.FINER, "Error in REST call", e);
+
+ return Response.serverError().entity("DmsException: " +
e).build();
+ }
+
+ }
+
+ @GET
+ @Path("{project}/{repository}/schema")
+ @Produces("text/html")
+ public Response getSchemas(@PathParam("project") String project,
+ @PathParam("repository") String repository) {
+ try {
+ logger.entering(this.getClass().getName(), "schemas");
+
+ Admin.validateName(project);
+ Admin.validateName(repository);
+ aa(new DmsPermission(project + "/" + repository, "read"));
+
+ StringBuilder sb = new StringBuilder();
+ sb
+ .append("<?xml version=\"1.0\"?> <!DOCTYPE html PUBLIC
\"-//W3C//DTD XHTML 1.1//EN\"
\"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd\";> <html
xmlns=\"http://www.w3.org/1999/xhtml\"; xml:lang=\"en\">");
+ sb.append(String.format(
+ "<head><title>Schemas for repository
%s/%s</title></head>",
+ project, repository));
+
+ // Schemas
+ sb.append(String.format(
+ "<p>Schemas associated with repository %s:</p><ul>",
+ repository));
+ // Loop over all schemas
+ for (String schema : Admin.listSchemas(project, repository)) {
+ sb.append(String.format(
+ "<li><a class=\"schema\" href=\"%s\">%s</a></li>",
+ getSchemaURI(project, repository, schema), schema));
+ }
+ sb.append("</ul>");
+
+ sb.append("</html>");
+ return Response.ok().entity(sb).build();
+ } catch (Exception e) {
+ logger.log(Level.FINER, "Error in REST call", e);
+
+ return Response.serverError().entity("DmsException: " +
e).build();
+ }
+
+ }
+
+ @GET
+ @Path("{project}/{repository}/schema/{schema}")
+ @Produces("text/html")
+ public Response getSchema(@PathParam("project") String project,
+ @PathParam("repository") String repository,
+ @PathParam("schema") String schema) {
+ try {
+ logger.entering(this.getClass().getName(), "schema");
+
+ Admin.validateName(project);
+ Admin.validateName(repository);
+ aa(new DmsPermission(project + "/" + repository, "read"));
+
+ StringBuilder sb = new StringBuilder();
+ sb
+ .append("<?xml version=\"1.0\"?> <!DOCTYPE html PUBLIC
\"-//W3C//DTD XHTML 1.1//EN\"
\"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd\";> <html
xmlns=\"http://www.w3.org/1999/xhtml\"; xml:lang=\"en\">");
+ sb
+ .append(String
+ .format(
+ "<head><title>Schema %s for repository
%s/%s</title></head>",
+ schema, project, repository));
+
+ // Schema file content
+ sb.append("<p>Schema content:</p>");
+ sb.append("<pre>");
+ File schemaFile = Admin.getSchemaFile(project, repository,
schema);
+ FileReader is = new FileReader(schemaFile);
+ int ch = is.read();
+ while (ch != -1) {
+ sb.append(ch);
+ ch = is.read();
+ }
+ sb.append("</pre>");
+
+ sb.append("</html>");
+ return Response.ok().entity(sb).build();
+ } catch (Exception e) {
+ logger.log(Level.FINER, "Error in REST call", e);
+
+ return Response.serverError().entity("DmsException: " +
e).build();
+ }
+
+ }
+
+ /**
+ * Authenticate and authorize
+ *
+ * Checks if the request was successfully authenticated (e.g. by
+ * NegotiateFilter) and if the authenticated user has the requested
permission.
+ *
+ * @param permission
+ * Permission to check for
+ * @return The authenticated Subject
+ * @throws DmsException
+ * if authentication or authorization was not successful
+ */
+ private Subject aa(DmsPermission permission) throws DmsException {
+ DmsCredentials cred = null;
+ if (securityContext.getUserPrincipal() != null) {
+ cred = IdokNegotiateFilter.getDmsCredentials();
+ }
+ if (cred == null)
+ throw new DmsException(ErrorType.AUTHENTICATION, this,
+ "No credentials found", "");
+ Subject subject = cred.getSubject();
+ try {
+ if (permission != null)
+ adapter.checkPermission(subject, permission);
+ } catch (AccessControlException e) {
+ throw new DmsException(ErrorType.AUTHENTICATION, this, String
+ .format("Permission %s denied", permission), "", e);
+ }
+ return subject;
+ }
+
+ private Object getSchemaURI(String project, String repository, String
schema) {
+ return
uriInfo.getBaseUriBuilder().path(this.getClass()).path(project)
+ .path(repository).path("schema").path(schema).toString();
+ }
+
+ private String getProjectURI(String project) {
+ return
uriInfo.getBaseUriBuilder().path(this.getClass()).path(project)
+ .toString();
+ }
+
+ private String getRepositoryURI(String project, String repository) {
+ return project + "/" + repository;
+ }
+
+}

Modified: branches/rest/java/ch/idok/service/server/rest/IdokAppConfig.java
==============================================================================
--- branches/rest/java/ch/idok/service/server/rest/IdokAppConfig.java
(original)
+++ branches/rest/java/ch/idok/service/server/rest/IdokAppConfig.java Tue
Aug 26 17:33:00 2008
@@ -5,6 +5,7 @@

import javax.ws.rs.core.ApplicationConfig;

+import ch.idok.service.server.admin.rest.RestAdminServiceResource;
import ch.idok.service.server.search.rest.RestSearchServiceResource;

public class IdokAppConfig extends ApplicationConfig {
@@ -16,6 +17,7 @@
public Set<Class<?>> getResourceClasses() {
Set<Class<?>> rrcs = new HashSet<Class<?>>();
rrcs.add(RestSearchServiceResource.class);
+ rrcs.add(RestAdminServiceResource.class);
return rrcs;
}


Modified: branches/rest/java/ch/idok/service/server/rest/RestServer.java
==============================================================================
--- branches/rest/java/ch/idok/service/server/rest/RestServer.java
(original)
+++ branches/rest/java/ch/idok/service/server/rest/RestServer.java Tue
Aug 26 17:33:00 2008
@@ -15,6 +15,7 @@
import ch.idok.common.errorhandling.DmsException;
import ch.idok.common.errorhandling.ErrorType;
import ch.idok.service.common.Provider;
+import ch.idok.service.server.admin.rest.RestAdminServiceResource;
import ch.idok.service.server.search.rest.RestSearchServiceResource;

/**
@@ -60,6 +61,7 @@
throws DmsException {
this.serviceProvider = serviceProvider;
RestSearchServiceResource.init(this);
+ RestAdminServiceResource.init(this);
}

/**
@@ -81,7 +83,7 @@

// Create authentication filter
// TODO make realm configurable (should match the Subversion realm)
- SpnegoFilter filter = new SpnegoFilter("iDok login", "DmsNoCache");
+ NegotiateFilter filter = new IdokNegotiateFilter("iDok login",
"DmsNoCache");

// create JAX-RS runtime environment
JaxRsApplication application = new FilteringJaxRsApplication(filter);



  • [idok-commit] idok commit r187 - in branches/rest/java/ch/idok/service/server: admin/rest rest, AFS account Roman Geus, 08/26/2008

Archive powered by MHonArc 2.6.19.

Top of Page