package com.devicehive.resource;
/*
* #%L
* DeviceHive Java Server Common business logic
* %%
* Copyright (C) 2016 DataArt
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* #L%
*/
import com.devicehive.json.strategies.JsonPolicyDef;
import com.devicehive.model.updates.UserUpdate;
import com.devicehive.vo.NetworkVO;
import com.devicehive.vo.UserVO;
import io.swagger.annotations.*;
import org.springframework.security.access.prepost.PreAuthorize;
import javax.ws.rs.*;
import javax.ws.rs.container.AsyncResponse;
import javax.ws.rs.container.Suspended;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
@Path("/user")
@Api(tags = {"User"}, description = "Represents a user to this API.", consumes="application/json")
@Produces({"application/json"})
public interface UserResource {
/**
* This method will generate following output <p/> <code> [ { "id": 2, "login": "login", "role": 0, "status": 0,
* "lastLogin": "1970-01-01 03:00:00.0" }, { "id": 3, "login": "login1", "role": 1, "status": 2, "lastLogin":
* "1970-01-01 03:00:00.0" } ] </code>
*
* @param login user login ignored, when loginPattern is specified
* @param loginPattern login pattern (LIKE %VALUE%) user login will be ignored, if not null
* @param role User's role ADMIN - 0, CLIENT - 1
* @param status ACTIVE - 0 (normal state, user can logon) , LOCKED_OUT - 1 (locked for multiple login
* failures), DISABLED - 2 , DELETED - 3;
* @param sortField either of "login", "loginAttempts", "role", "status", "lastLogin"
* @param sortOrderSt either ASC or DESC
* @param take like SQL LIMIT
* @param skip like SQL OFFSET
* @return List of User
*/
@GET
@PreAuthorize("isAuthenticated() and hasPermission(null, 'MANAGE_USER')")
@ApiOperation(value = "List users", notes = "Gets list of users.")
@ApiResponses({
@ApiResponse(code = 200, message = "If successful, this method returns array of User resources in the response body.", response = UserVO.class, responseContainer = "List"),
@ApiResponse(code = 400, message = "If request parameters invalid"),
@ApiResponse(code = 401, message = "If request is not authorized"),
@ApiResponse(code = 403, message = "If principal doesn't have permissions")
})
void list(
@ApiParam(name = "login", value = "Filter by user login.")
@QueryParam("login")
String login,
@ApiParam(name = "loginPattern", value = "Filter by user login pattern.")
@QueryParam("loginPattern")
String loginPattern,
@ApiParam(name = "role", value = "Filter by user role. 0 is Administrator, 1 is Client.")
@QueryParam("role")
Integer role,
@ApiParam(name = "status", value = "Filter by user status. 0 is Active, 1 is Locked Out, 2 is Disabled.")
@QueryParam("status")
Integer status,
@ApiParam(name = "sortField", value = "Result list sort field.", allowableValues = "ID,Login")
@QueryParam("sortField")
String sortField,
@ApiParam(name = "sortOrder", value = "Result list sort order. Available values are ASC and DESC.", allowableValues = "ASC,DESC")
@QueryParam("sortOrder")
String sortOrderSt,
@ApiParam(name = "take", value = "Number of records to take from the result list.", defaultValue = "20")
@QueryParam("take")
Integer take,
@ApiParam(name = "skip", value = "Number of records to skip from the result list.", defaultValue = "0")
@QueryParam("skip")
Integer skip,
@Suspended final AsyncResponse asyncResponse);
/**
* Method will generate following output: <p/> <code> { "id": 2, "login": "login", "status": 0, "networks": [ {
* "network": { "id": 5, "key": "network key", "name": "name of network", "description": "short description of
* network" } } ], "lastLogin": "1970-01-01 03:00:00.0" } </code> <p/> If success, response with status 200, if user
* is not found 400
*
* @param userId user id
*/
@GET
@Path("/{id}")
@PreAuthorize("isAuthenticated() and hasPermission(null, 'GET_CURRENT_USER')")
@ApiOperation(value = "Get user", notes = "Gets information about user and its assigned networks.\n" +
"Only administrators are allowed to get information about any user. User-level accounts can only retrieve information about themselves.")
@ApiResponses({
@ApiResponse(code = 200, message = "If successful, this method returns a User resource in the response body.", response = UserVO.class),
@ApiResponse(code = 400, message = "If request is malformed"),
@ApiResponse(code = 401, message = "If request is not authorized"),
@ApiResponse(code = 403, message = "If principal doesn't have permissions"),
@ApiResponse(code = 404, message = "If user is not found")
})
Response getUser(
@ApiParam(name = "id", value = "User identifier.", required = true)
@PathParam("id")
Long userId);
@GET
@Path("/current")
@PreAuthorize("isAuthenticated() and hasPermission(null, 'GET_CURRENT_USER')")
@ApiOperation(value = "Get current user", notes = "Get information about the current user.")
@ApiResponses({
@ApiResponse(code = 200, message = "If successful, this method returns a User resource in the response body.", response = UserVO.class),
@ApiResponse(code = 401, message = "If request is not authorized"),
@ApiResponse(code = 403, message = "If principal doesn't have permissions"),
@ApiResponse(code = 409, message = "If user is not signed in")
})
Response getCurrent();
/**
* One needs to provide user resource in request body (all parameters are mandatory): <p/> <code> { "login":"login"
* "role":0 "status":0 "password":"qwerty" } </code> <p/> In case of success server will provide following response
* with code 201 <p/> <code> { "id": 1, "lastLogin": null } </code>
*
* @return Empty body, status 201 if success, 403 if forbidden, 400 otherwise
*/
@POST
@Consumes(MediaType.APPLICATION_JSON)
@PreAuthorize("isAuthenticated() and hasPermission(null, 'MANAGE_USER')")
@JsonPolicyDef(JsonPolicyDef.Policy.USERS_LISTED)
@ApiOperation(value = "Create user", notes = "Creates new user.")
@ApiResponses({
@ApiResponse(code = 201, message = "If successful, this method returns a User resource in the response body.", response = UserVO.class),
@ApiResponse(code = 400, message = "If request is malformed"),
@ApiResponse(code = 401, message = "If request is not authorized"),
@ApiResponse(code = 403, message = "If principal doesn't have permissions")
})
Response insertUser(
@ApiParam(value = "User body", defaultValue = "{}", required = true)
UserUpdate userToCreate);
/**
* Updates user. One should specify following json to update user (none of parameters are mandatory, bot neither of
* them can be null): <p/> <code> { "login": "login", "role": 0, "status": 0, "password": "password" } </code> <p/>
* role: Administrator - 0, Client - 1 status: ACTIVE - 0 (normal state, user can logon) , LOCKED_OUT - 1 (locked
* for multiple login failures), DISABLED - 2 , DELETED - 3;
*
* @param userId - id of user being edited
* @return empty response, status 201 if succeeded, 403 if action is forbidden, 400 otherwise
*/
@PUT
@Path("/{id}")
@Consumes(MediaType.APPLICATION_JSON)
@PreAuthorize("isAuthenticated() and hasPermission(null, 'MANAGE_USER')")
@ApiOperation(value = "Update user")
@ApiResponses({
@ApiResponse(code = 404, message = "If user not found")
})
Response updateUser(
@ApiParam(value = "User body", defaultValue = "{}", required = true)
UserUpdate user,
@ApiParam(name = "id", value = "User identifier.", required = true)
@PathParam("id")
Long userId);
@PUT
@Path("/current")
@Consumes(MediaType.APPLICATION_JSON)
@PreAuthorize("isAuthenticated() and hasPermission(null, 'UPDATE_CURRENT_USER')")
@ApiOperation(value = "Update current user", notes = "Updates an existing user. \n" +
"Only administrators are allowed to update any property of any user. User-level accounts can only change their own password in case:\n" +
"1. They already have a password.\n" +
"2. They provide a valid current password in the 'oldPassword' property.")
@ApiResponses({
@ApiResponse(code = 204, message = "If successful, this method returns an empty response body."),
@ApiResponse(code = 400, message = "If request is malformed"),
@ApiResponse(code = 401, message = "If request is not authorized"),
@ApiResponse(code = 403, message = "If principal doesn't have permissions")
})
Response updateCurrentUser(
@ApiParam(value = "User body", defaultValue = "{}", required = true)
UserUpdate user);
/**
* Deletes user by id
*
* @param userId id of user to delete
* @return empty response. state 204 in case of success, 404 if not found
*/
@DELETE
@Path("/{id}")
@PreAuthorize("isAuthenticated() and hasPermission(null, 'MANAGE_USER')")
@ApiOperation(value = "Delete user", notes = "Deletes an existing user.")
@ApiResponses({
@ApiResponse(code = 204, message = "If successful, this method returns an empty response body."),
@ApiResponse(code = 401, message = "If request is not authorized"),
@ApiResponse(code = 403, message = "If principal doesn't have permissions"),
@ApiResponse(code = 404, message = "If access key is not found")
})
Response deleteUser(
@ApiParam(name = "id", value = "User identifier.", required = true)
@PathParam("id")
long userId);
/**
* Method returns following body in case of success (status 200): <code> { "id": 5, "key": "network_key", "name":
* "network name", "description": "short description of net" } </code> in case, there is no such network, or user,
* or user doesn't have access
*
* @param id user id
* @param networkId network id
*/
@GET
@Path("/{id}/network/{networkId}")
@PreAuthorize("isAuthenticated() and hasPermission(null, 'GET_NETWORK')")
@ApiOperation(value = "Get user's network", notes = "Gets information about user/network association.")
@ApiResponses({
@ApiResponse(code = 200, message = "If successful, this method returns a Network resource in the response body.", response = NetworkVO.class),
@ApiResponse(code = 401, message = "If request is not authorized"),
@ApiResponse(code = 403, message = "If principal doesn't have permissions"),
@ApiResponse(code = 404, message = "If user or network not found")
})
Response getNetwork(
@ApiParam(name = "id", value = "User identifier.", required = true)
@PathParam("id")
long id,
@ApiParam(name = "networkId", value = "Network identifier.", required = true)
@PathParam("networkId")
long networkId);
/**
* Request body must be empty. Returns Empty body.
*
* @param id user id
* @param networkId network id
*/
@PUT
@Path("/{id}/network/{networkId}")
@PreAuthorize("isAuthenticated() and hasPermission(null, 'MANAGE_NETWORK')")
@ApiOperation(value = "Assign network", notes = "Associates network with the user.")
@ApiResponses({
@ApiResponse(code = 204, message = "If successful, this method returns an empty response body."),
@ApiResponse(code = 401, message = "If request is not authorized"),
@ApiResponse(code = 403, message = "If principal doesn't have permissions"),
@ApiResponse(code = 404, message = "If user or network not found")
})
Response assignNetwork(
@ApiParam(name = "id", value = "User identifier.", required = true)
@PathParam("id")
long id,
@ApiParam(name = "networkId", value = "Network identifier.", required = true)
@PathParam("networkId")
long networkId);
/**
* Removes user permissions on network
*
* @param id user id
* @param networkId network id
* @return Empty body. Status 204 in case of success, 404 otherwise
*/
@DELETE
@Path("/{id}/network/{networkId}")
@PreAuthorize("isAuthenticated() and hasPermission(null, 'MANAGE_NETWORK')")
@ApiOperation(value = "Unassign network", notes = "Removes association between network and user.")
@ApiResponses({
@ApiResponse(code = 204, message = "If successful, this method returns an empty response body."),
@ApiResponse(code = 401, message = "If request is not authorized"),
@ApiResponse(code = 403, message = "If principal doesn't have permissions"),
@ApiResponse(code = 404, message = "If user or network not found.")
})
Response unassignNetwork(
@ApiParam(name = "id", value = "User identifier.", required = true)
@PathParam("id")
long id,
@ApiParam(name = "networkId", value = "Network identifier.", required = true)
@PathParam("networkId")
long networkId);
}