Hi everyone,
I am implementing actually the role-based access control for OpenHAB users.
I am currently implementing the methods to get/put roles and groups from/to the server side. To do this, I need to manage the openhab-core project and the openhab-webui project.
I created the accessControl package at the location org.openhab.core.io.rest.core/src/main/java/org/openhab/core/io/rest/core/internal/accessControl
and created the AccessControlRessource.java
class as shown below:
package org.openhab.core.io.rest.core.internal.accessControl;
import java.io.IOException;
import java.security.Principal;
import java.util.Optional;
import javax.annotation.security.PermitAll;
import javax.annotation.security.RolesAllowed;
import javax.ws.rs.*;
import javax.ws.rs.core.*;
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.openhab.core.auth.GroupRegistry;
import org.openhab.core.auth.Role;
import org.openhab.core.auth.RoleRegistry;
import org.openhab.core.auth.UserRegistry;
import org.openhab.core.io.rest.*;
import org.openhab.core.io.rest.auth.VerifyToken;
import org.openhab.core.io.rest.core.internal.item.ItemResource;
import org.osgi.service.component.annotations.Activate;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Reference;
import org.osgi.service.jaxrs.whiteboard.JaxrsWhiteboardConstants;
import org.osgi.service.jaxrs.whiteboard.propertytypes.JSONRequired;
import org.osgi.service.jaxrs.whiteboard.propertytypes.JaxrsApplicationSelect;
import org.osgi.service.jaxrs.whiteboard.propertytypes.JaxrsName;
import org.osgi.service.jaxrs.whiteboard.propertytypes.JaxrsResource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.tags.Tag;
@Component
@JaxrsResource
@JaxrsName(AccessControlRessource.PATH_ACCESS_CONTROL)
@JaxrsApplicationSelect("(" + JaxrsWhiteboardConstants.JAX_RS_NAME + "=" + RESTConstants.JAX_RS_NAME + ")")
@JSONRequired
@Path(AccessControlRessource.PATH_ACCESS_CONTROL)
// see https://docs.swagger.io/swagger-core/v2.1.12/apidocs/io/swagger/v3/oas/annotations/tags/Tag.html
@Tag(name = AccessControlRessource.PATH_ACCESS_CONTROL)
@NonNullByDefault
public class AccessControlRessource implements RESTResource {
/** The URI path to this resource */
public static final String PATH_ACCESS_CONTROL = "accessControl";
private final Logger logger = LoggerFactory.getLogger(ItemResource.class);
private final UserRegistry userRegistry;
private final RoleRegistry roleRegistry;
@Activate
public AccessControlRessource(final @Reference UserRegistry userRegistry,
final @Reference RoleRegistry roleRegistry) {
this.userRegistry = userRegistry;
this.roleRegistry = roleRegistry;
}
@GET
@PermitAll
@Produces(MediaType.APPLICATION_JSON)
@Operation(operationId = "getTest", summary = "test function", responses = {
@ApiResponse(responseCode = "200", description = "OK", content = @Content(schema = @Schema(implementation = String.class))),
@ApiResponse(responseCode = "404", description = "Item not found") })
public Response getTest(final @Context UriInfo uriInfo, final @Context HttpHeaders httpHeaders) {
System.out.println("That works!!!");
System.out.println(principal.getName());
return Response.ok("IT works").build();
}
/**
*
* @param
* @return
*/
@GET
@RolesAllowed({ Role.USER, Role.ADMIN })
@Path("/role")
@Produces(MediaType.TEXT_PLAIN)
@Operation(operationId = "getRoleTest", summary = "test role function", responses = {
@ApiResponse(responseCode = "200", description = "OK", content = @Content(schema = @Schema(implementation = String.class))),
@ApiResponse(responseCode = "404", description = "Item not found") })
public Response getRoleTest() {
// get item
System.out.println("It works");
// we cannot use JSONResponse.createResponse() bc. MediaType.TEXT_PLAIN
// return JSONResponse.createResponse(Status.OK, item.getState().toString(), null);
return Response.ok("It works!!!").build();
}
}
For now, Iâm just trying to invoke the getTest
function or the getRoleTest
function with the /rest/accessControl
and /rest/accessControl/role
path respectively on the client side, i.e. in the project openhab-webui, by simply calling :
this.$oh.api.get('/rest/accessControl')
this.$oh.api.get('/rest/accessControl/role')
But this does not work and the client responds with the message 406 Not Acceptable
.
I donât know what I missed, because when I call this.$oh.api.get('/rest/items')
for example on the client side, it works fine. The function in the ItemResource.java
to get the items is well invoked. The ItemResource.java is located at org.openhab.core.io.rest.core/src/main/java/org/openhab/core/io/rest/core/internal/item/ItemResource.java
on the server side, i.e. openhab-core.
The function this.$oh.api.get()
is located at bundles/org.openhab.ui/web/src/js/openhab/api.js
in the project openhab-webui and implements the methods of HTTP protocol.
Maybe I did something wrong with the javax annotation. I took inspiration from other classes like ItemResource.java at org.openhab.core.io.rest.core/src/main/java/org/openhab/core/io/rest/core/internal\item
but I donât know what I did wrong. Is there another class I need to modify to invoke the functions of AccessControlRessource.java ?
What did I miss to be able to invoke the function in the AccessControlRessource.java class by calling the get method of the HTTP protocol in the client side (openhab-webui)?
What I want to do next is to manipulate the roles between the client(openhab-webui) and the server (openhab-core ) with the HTTP protocol like the items is manage.
I hope I have made myself clear,
Thank you,
Nicolas Gennart.