charitha 8 years ago
commit ce5d63925a

@ -34,8 +34,8 @@ import javax.ws.rs.core.Response;
@API(name = "Configuration Management", version = "1.0.0", context = "/api/device-mgt/v1.0/configuration", tags = {"devicemgt_admin"}) @API(name = "Configuration Management", version = "1.0.0", context = "/api/device-mgt/v1.0/configuration", tags = {"devicemgt_admin"})
@Path("/configuration") @Path("/configuration")
@Api(value = "Configuration Management", description = "General Tenant Configuration management capabilities are exposed " + @Api(value = "Configuration Management", description = "The general platform configuration management capabilities are exposed " +
"through this API") "through this API.")
@Produces(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON) @Consumes(MediaType.APPLICATION_JSON)
public interface ConfigurationManagementService { public interface ConfigurationManagementService {
@ -44,14 +44,16 @@ public interface ConfigurationManagementService {
@ApiOperation( @ApiOperation(
produces = MediaType.APPLICATION_JSON, produces = MediaType.APPLICATION_JSON,
httpMethod = "GET", httpMethod = "GET",
value = "Get the general platform configurations.", value = "Getting General Platform Configurations",
notes = "Get the general platform level configuration details.", notes = "WSO2 EMM monitors policies to verify that the devices comply with the policies enforced on them. " +
"General platform configurations include the settings on how often the the device need to be monitored. " +
"Using this REST API you can get the general platform level configurations.",
tags = "Configuration Management") tags = "Configuration Management")
@ApiResponses( @ApiResponses(
value = { value = {
@ApiResponse( @ApiResponse(
code = 200, code = 200,
message = "OK. \n Successfully fetched general platform configuration.", message = "OK. \n Successfully fetched the general platform configurations.",
response = PlatformConfiguration.class, response = PlatformConfiguration.class,
responseContainer = "List", responseContainer = "List",
responseHeaders = { responseHeaders = {
@ -70,22 +72,23 @@ public interface ConfigurationManagementService {
), ),
@ApiResponse( @ApiResponse(
code = 304, code = 304,
message = "Not Modified. \n Empty body because the client has already the latest version of " + message = "Not Modified. \n Empty body because the client already has the latest version of the requested resource."),
"the requested resource."),
@ApiResponse( @ApiResponse(
code = 406, code = 406,
message = "Not Acceptable.\n The requested media type is not supported"), message = "Not Acceptable.\n The requested media type is not supported."),
@ApiResponse( @ApiResponse(
code = 500, code = 500,
message = "Internal Server Error. \n Server error occurred while fetching the general " + message = "Internal Server Error. \n Server error occurred while fetching the general " +
"platform configuration.", "platform configurations.",
response = ErrorResponse.class) response = ErrorResponse.class)
}) })
@Permission(name = "View Configurations", permission = "/device-mgt/platform-configurations/view") @Permission(name = "View Configurations", permission = "/device-mgt/platform-configurations/view")
Response getConfiguration( Response getConfiguration(
@ApiParam( @ApiParam(
name = "If-Modified-Since", name = "If-Modified-Since",
value = "Validates if the requested variant has not been modified since the time specified", value = "Checks if the requested variant was modified, since the specified date-time.\n" +
"Provide the value in the following format: EEE, d MMM yyyy HH:mm:ss Z." +
"Example: Mon, 05 Jan 2014 15:10:00 +0200",
required = false) required = false)
@HeaderParam("If-Modified-Since") @HeaderParam("If-Modified-Since")
String ifModifiedSince); String ifModifiedSince);
@ -95,14 +98,16 @@ public interface ConfigurationManagementService {
consumes = MediaType.APPLICATION_JSON, consumes = MediaType.APPLICATION_JSON,
produces = MediaType.APPLICATION_JSON, produces = MediaType.APPLICATION_JSON,
httpMethod = "PUT", httpMethod = "PUT",
value = "Update General Platform Configurations.", value = "Updating General Platform Configurations",
notes = "This resource is used to update the general platform configuration.", notes = "WSO2 EMM monitors policies to verify that the devices comply with the policies enforced on them." +
"General platform configurations include the settings on how often the the device need to be monitored." +
"Using this REST API you can update the general platform level configurations.",
tags = "Configuration Management") tags = "Configuration Management")
@ApiResponses( @ApiResponses(
value = { value = {
@ApiResponse( @ApiResponse(
code = 200, code = 200,
message = "OK. \n General platform configuration has been updated successfully", message = "OK. \n Successfully updated the general platform configurations.",
responseHeaders = { responseHeaders = {
@ResponseHeader( @ResponseHeader(
name = "Content-Type", name = "Content-Type",
@ -120,18 +125,18 @@ public interface ConfigurationManagementService {
message = "Bad Request. \n Invalid request or validation error."), message = "Bad Request. \n Invalid request or validation error."),
@ApiResponse( @ApiResponse(
code = 415, code = 415,
message = "Unsupported media type. \n The entity of the request was in a not supported format."), message = "Unsupported media type. \n The format of the requested entity was not supported."),
@ApiResponse( @ApiResponse(
code = 500, code = 500,
message = "Internal Server Error. \n " + message = "Internal Server Error. \n " +
"Server error occurred while modifying general platform configuration.", "Server error occurred while modifying the general platform configurations.",
response = ErrorResponse.class) response = ErrorResponse.class)
}) })
@Permission(name = "Manage configurations", permission = "/device-mgt/platform-configurations/manage") @Permission(name = "Manage configurations", permission = "/device-mgt/platform-configurations/manage")
Response updateConfiguration( Response updateConfiguration(
@ApiParam( @ApiParam(
name = "configuration", name = "configuration",
value = "The required properties to be updated in the platform configuration.", value = "The properties required to update the platform configurations.",
required = true) required = true)
PlatformConfiguration configuration); PlatformConfiguration configuration);

@ -1,81 +1,118 @@
/*
* Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
*
* WSO2 Inc. licenses this file to you 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.
*
*/
package org.wso2.carbon.device.mgt.jaxrs.service.api; package org.wso2.carbon.device.mgt.jaxrs.service.api;
import io.swagger.annotations.Api; import io.swagger.annotations.Api;
import org.wso2.carbon.apimgt.annotations.api.API;
import org.wso2.carbon.apimgt.annotations.api.Permission;
import javax.ws.rs.GET; import javax.ws.rs.*;
import javax.ws.rs.Path; import javax.ws.rs.core.MediaType;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.Response; import javax.ws.rs.core.Response;
//@Path("/dashboard") /**
//@Api(value = "Dashboard", description = "Dashboard related operations are described here.") * Device Analytics Dashboard related REST-APIs. This can be used to obtain device related analytics.
*/
@API(name = "Device Analytics Dashboard",
version = "1.0.0", context = "/api/device-mgt/v1.0/dashboard", tags = {"devicemgt_admin"})
@Path("/dashboard")
@Api(value = "Device Analytics Dashboard",
description = "Device Analytics Dashboard related information APIs are described here.")
@Produces(MediaType.APPLICATION_JSON)
@SuppressWarnings("NonJaxWsWebServices") @SuppressWarnings("NonJaxWsWebServices")
public interface Dashboard { public interface Dashboard {
// String CONNECTIVITY_STATUS = "connectivity-status"; String CONNECTIVITY_STATUS = "connectivity-status";
// String POTENTIAL_VULNERABILITY = "potential-vulnerability"; String POTENTIAL_VULNERABILITY = "potential-vulnerability";
// String NON_COMPLIANT_FEATURE_CODE = "non-compliant-feature-code"; String NON_COMPLIANT_FEATURE_CODE = "non-compliant-feature-code";
// String PLATFORM = "platform"; String PLATFORM = "platform";
// String OWNERSHIP = "ownership"; String OWNERSHIP = "ownership";
// // Constants related to pagination // Constants related to pagination
// String PAGINATION_ENABLED = "pagination-enabled"; String PAGINATION_ENABLED = "pagination-enabled";
// String START_INDEX = "start"; String START_INDEX = "start";
// String RESULT_COUNT = "length"; String RESULT_COUNT = "length";
//
// @GET @GET
// @Path("device-count-overview") @Path("device-count-overview")
// Response getOverviewDeviceCounts(); @Permission(name = "View Dashboard", permission = "/device-mgt/dashboard/view")
// Response getOverviewDeviceCounts();
// @GET
// @Path("device-counts-by-potential-vulnerabilities") @GET
// Response getDeviceCountsByPotentialVulnerabilities(); @Path("device-counts-by-potential-vulnerabilities")
// @Permission(name = "View Dashboard", permission = "/device-mgt/dashboard/view")
// @GET Response getDeviceCountsByPotentialVulnerabilities();
// @Path("non-compliant-device-counts-by-features")
// Response getNonCompliantDeviceCountsByFeatures(@QueryParam(START_INDEX) int startIndex, @GET
// @QueryParam(RESULT_COUNT) int resultCount); @Path("non-compliant-device-counts-by-features")
// @Permission(name = "View Dashboard", permission = "/device-mgt/dashboard/view")
// @GET Response getNonCompliantDeviceCountsByFeatures(@QueryParam(START_INDEX) int startIndex,
// @Path("device-counts-by-groups") @QueryParam(RESULT_COUNT) int resultCount);
// Response getDeviceCountsByGroups(@QueryParam(CONNECTIVITY_STATUS) String connectivityStatus,
// @QueryParam(POTENTIAL_VULNERABILITY) String potentialVulnerability, @GET
// @QueryParam(PLATFORM) String platform, @Path("device-counts-by-groups")
// @QueryParam(OWNERSHIP) String ownership); @Permission(name = "View Dashboard", permission = "/device-mgt/dashboard/view")
// Response getDeviceCountsByGroups(@QueryParam(CONNECTIVITY_STATUS) String connectivityStatus,
// @GET @QueryParam(POTENTIAL_VULNERABILITY) String potentialVulnerability,
// @Path("feature-non-compliant-device-counts-by-groups") @QueryParam(PLATFORM) String platform,
// Response getFeatureNonCompliantDeviceCountsByGroups(@QueryParam(NON_COMPLIANT_FEATURE_CODE) String nonCompliantFeatureCode, @QueryParam(OWNERSHIP) String ownership);
// @QueryParam(PLATFORM) String platform,
// @QueryParam(OWNERSHIP) String ownership); @GET
// @GET @Path("feature-non-compliant-device-counts-by-groups")
// @Path("filtered-device-count-over-total") @Permission(name = "View Dashboard", permission = "/device-mgt/dashboard/view")
// Response getFilteredDeviceCountOverTotal(@QueryParam(CONNECTIVITY_STATUS) String connectivityStatus, Response getFeatureNonCompliantDeviceCountsByGroups(@QueryParam(NON_COMPLIANT_FEATURE_CODE) String nonCompliantFeatureCode,
// @QueryParam(POTENTIAL_VULNERABILITY) String potentialVulnerability, @QueryParam(PLATFORM) String platform,
// @QueryParam(PLATFORM) String platform, @QueryParam(OWNERSHIP) String ownership);
// @QueryParam(OWNERSHIP) String ownership); @GET
// @Path("filtered-device-count-over-total")
// @GET @Permission(name = "View Dashboard", permission = "/device-mgt/dashboard/view")
// @Path("feature-non-compliant-device-count-over-total") Response getFilteredDeviceCountOverTotal(@QueryParam(CONNECTIVITY_STATUS) String connectivityStatus,
// Response getFeatureNonCompliantDeviceCountOverTotal(@QueryParam(NON_COMPLIANT_FEATURE_CODE) String nonCompliantFeatureCode, @QueryParam(POTENTIAL_VULNERABILITY) String potentialVulnerability,
// @QueryParam(PLATFORM) String platform, @QueryParam(PLATFORM) String platform,
// @QueryParam(OWNERSHIP) String ownership); @QueryParam(OWNERSHIP) String ownership);
//
// @GET @GET
// @Path("devices-with-details") @Path("feature-non-compliant-device-count-over-total")
// Response getDevicesWithDetails(@QueryParam(CONNECTIVITY_STATUS) String connectivityStatus, @Permission(name = "View Dashboard", permission = "/device-mgt/dashboard/view")
// @QueryParam(POTENTIAL_VULNERABILITY) String potentialVulnerability, Response getFeatureNonCompliantDeviceCountOverTotal(@QueryParam(NON_COMPLIANT_FEATURE_CODE) String nonCompliantFeatureCode,
// @QueryParam(PLATFORM) String platform, @QueryParam(PLATFORM) String platform,
// @QueryParam(OWNERSHIP) String ownership, @QueryParam(OWNERSHIP) String ownership);
// @QueryParam(PAGINATION_ENABLED) String paginationEnabled,
// @QueryParam(START_INDEX) int startIndex, @GET
// @QueryParam(RESULT_COUNT) int resultCount); @Path("devices-with-details")
// @Permission(name = "View Dashboard", permission = "/device-mgt/dashboard/view")
// @GET Response getDevicesWithDetails(@QueryParam(CONNECTIVITY_STATUS) String connectivityStatus,
// @Path("feature-non-compliant-devices-with-details") @QueryParam(POTENTIAL_VULNERABILITY) String potentialVulnerability,
// Response getFeatureNonCompliantDevicesWithDetails(@QueryParam(NON_COMPLIANT_FEATURE_CODE) String nonCompliantFeatureCode, @QueryParam(PLATFORM) String platform,
// @QueryParam(PLATFORM) String platform, @QueryParam(OWNERSHIP) String ownership,
// @QueryParam(OWNERSHIP) String ownership, @QueryParam(PAGINATION_ENABLED) String paginationEnabled,
// @QueryParam(PAGINATION_ENABLED) String paginationEnabled, @QueryParam(START_INDEX) int startIndex,
// @QueryParam(START_INDEX) int startIndex, @QueryParam(RESULT_COUNT) int resultCount);
// @QueryParam(RESULT_COUNT) int resultCount);
@GET
@Path("feature-non-compliant-devices-with-details")
@Permission(name = "View Dashboard", permission = "/device-mgt/dashboard/view")
Response getFeatureNonCompliantDevicesWithDetails(@QueryParam(NON_COMPLIANT_FEATURE_CODE) String nonCompliantFeatureCode,
@QueryParam(PLATFORM) String platform,
@QueryParam(OWNERSHIP) String ownership,
@QueryParam(PAGINATION_ENABLED) String paginationEnabled,
@QueryParam(START_INDEX) int startIndex,
@QueryParam(RESULT_COUNT) int resultCount);
} }

@ -44,15 +44,15 @@ public interface RoleManagementService {
@ApiOperation( @ApiOperation(
produces = MediaType.APPLICATION_JSON, produces = MediaType.APPLICATION_JSON,
httpMethod = "GET", httpMethod = "GET",
value = "Get the list of roles.", value = "Getting the List of Roles",
notes = "If you wish to get the details of all the roles in EMM, you can do so using this REST API. All " + notes = "WSO2 EMM supports role-based access control (RBAC) and role management. Using this API you can the list of roles that are in WSO2 EMM.\n" +
"internal roles, roles created for Service-providers and application related roles are omitted.", "Note: Internal roles, roles created for service-providers, and application related roles will not be given in the output.",
tags = "Role Management") tags = "Role Management")
@ApiResponses( @ApiResponses(
value = { value = {
@ApiResponse( @ApiResponse(
code = 200, code = 200,
message = "OK. \n Successfully fetched the requested list of roles.", message = "OK. \n Successfully fetched the list of roles in WSO2 EMM.",
response = RoleList.class, response = RoleList.class,
responseHeaders = { responseHeaders = {
@ResponseHeader( @ResponseHeader(
@ -69,41 +69,45 @@ public interface RoleManagementService {
}), }),
@ApiResponse( @ApiResponse(
code = 304, code = 304,
message = "Not Modified. \n Empty body because the client has already the latest version of the requested resource."), message = "Not Modified. \n Empty body because the client already has the latest version of the requested resource."),
@ApiResponse( @ApiResponse(
code = 406, code = 406,
message = "Not Acceptable.\n The requested media type is not supported"), message = "Not Acceptable.\n The requested media type is not supported"),
@ApiResponse( @ApiResponse(
code = 500, code = 500,
message = "Internal Server Error. \n Server error occurred while fetching requested list of roles.", message = "Internal Server Error. \n Server error occurred while fetching list of roles.",
response = ErrorResponse.class) response = ErrorResponse.class)
}) })
@Permission(name = "View Roles", permission = "/device-mgt/roles/view") @Permission(name = "View Roles", permission = "/device-mgt/roles/view")
Response getRoles( Response getRoles(
@ApiParam( @ApiParam(
name = "filter", name = "filter",
value = "Role name or a part of it to search.", value = "Provide a character or a few characters in the role name.",
required = false) required = false)
@QueryParam("filter") String filter, @QueryParam("filter") String filter,
@ApiParam( @ApiParam(
name = "user-store", name = "user-store",
value = "From which user store the roles must be fetched.", value = "The name of the UserStore you wish to get the list of roles.",
required = false) required = false)
@QueryParam("user-store") String userStoreName, @QueryParam("user-store") String userStoreName,
@ApiParam( @ApiParam(
name = "If-Modified-Since", name = "If-Modified-Since",
value = "Validates if the requested variant has not been modified since the time specified", value = "Checks if the requested variant was modified, since the specified date-time." +
"Provide the value in the following format: EEE, d MMM yyyy HH:mm:ss Z.\n" +
"Example: Mon, 05 Jan 2014 15:10:00 +0200",
required = false) required = false)
@HeaderParam("If-Modified-Since") String ifModifiedSince, @HeaderParam("If-Modified-Since") String ifModifiedSince,
@ApiParam( @ApiParam(
name = "offset", name = "offset",
value = "Starting point within the complete list of items qualified.", value = "The starting pagination index for the complete list qualified items.",
required = false) required = false,
defaultValue = "0")
@QueryParam("offset") int offset, @QueryParam("offset") int offset,
@ApiParam( @ApiParam(
name = "limit", name = "limit",
value = "Maximum size of resource array to return.", value = "Provide how many roles details you require from the starting pagination index/offset.",
required = false) required = false,
defaultValue = "5")
@QueryParam("limit") int limit); @QueryParam("limit") int limit);
@GET @GET
@ -111,10 +115,10 @@ public interface RoleManagementService {
@ApiOperation( @ApiOperation(
produces = MediaType.APPLICATION_JSON, produces = MediaType.APPLICATION_JSON,
httpMethod = "GET", httpMethod = "GET",
value = "Getting permission details of a role.", value = "Getting Permission Details of a Role",
notes = "In an organization an individual is associated a with set of responsibilities based on their " + notes = "An individual is associated a with set of responsibilities based on their " +
"role. In EMM you are able to configure permissions based on the responsibilities carried " + "role. In WSO2 EMM you are able to configure permissions based on the responsibilities carried " +
"out by a role. Therefore if you wish to retrieve the permission details of a role, you can do " + "out by various roles. Therefore, if you wish to retrieve the permission details of a role, you can do " +
"so using this REST API.", "so using this REST API.",
response = UIPermissionNode.class, response = UIPermissionNode.class,
responseContainer = "List", responseContainer = "List",
@ -124,7 +128,7 @@ public interface RoleManagementService {
value = { value = {
@ApiResponse( @ApiResponse(
code = 200, code = 200,
message = "OK. \n Successfully fetched the permission list of the given role.", message = "OK. \n Successfully fetched the permissions details for the specified role.",
response = UIPermissionNode.class, response = UIPermissionNode.class,
responseContainer = "List", responseContainer = "List",
responseHeaders = { responseHeaders = {
@ -142,14 +146,14 @@ public interface RoleManagementService {
}), }),
@ApiResponse( @ApiResponse(
code = 304, code = 304,
message = "Not Modified. \n Empty body because the client has already the latest version of the requested resource."), message = "Not Modified. \n Empty body because the client already has the latest version of the requested resource.\n"),
@ApiResponse( @ApiResponse(
code = 400, code = 400,
message = "Bad Request. \n Invalid request or validation error.", message = "Bad Request. \n Invalid request or validation error.",
response = ErrorResponse.class), response = ErrorResponse.class),
@ApiResponse( @ApiResponse(
code = 404, code = 404,
message = "Not Found. \n Role does not exist.", message = "Not Found. \n The specified role does not exist.",
response = ErrorResponse.class), response = ErrorResponse.class),
@ApiResponse( @ApiResponse(
code = 406, code = 406,
@ -157,19 +161,22 @@ public interface RoleManagementService {
response = ErrorResponse.class), response = ErrorResponse.class),
@ApiResponse( @ApiResponse(
code = 500, code = 500,
message = "Internal Server ErrorResponse. \n Server error occurred while fetching the permission list of the requested role.", message = "Internal Server ErrorResponse. \n Server error occurred while fetching the permission list for the requested role.",
response = ErrorResponse.class) response = ErrorResponse.class)
}) })
@Permission(name = "View Roles", permission = "/device-mgt/roles/view") @Permission(name = "View Roles", permission = "/device-mgt/roles/view")
Response getPermissionsOfRole( Response getPermissionsOfRole(
@ApiParam( @ApiParam(
name = "roleName", name = "roleName",
value = "Name of the role.", value = "The name of the role.",
required = true) required = true,
defaultValue = "Engineer")
@PathParam("roleName") String roleName, @PathParam("roleName") String roleName,
@ApiParam( @ApiParam(
name = "If-Modified-Since", name = "If-Modified-Since",
value = "Validates if the requested variant has not been modified since the time specified", value = "Checks if the requested variant was modified, since the specified date-time." +
"Provide the value in the following format: EEE, d MMM yyyy HH:mm:ss Z.\n" +
"Example: Mon, 05 Jan 2014 15:10:00 +0200",
required = false) required = false)
@HeaderParam("If-Modified-Since") String ifModifiedSince); @HeaderParam("If-Modified-Since") String ifModifiedSince);
@ -178,15 +185,15 @@ public interface RoleManagementService {
@ApiOperation( @ApiOperation(
produces = MediaType.APPLICATION_JSON, produces = MediaType.APPLICATION_JSON,
httpMethod = "GET", httpMethod = "GET",
value = "Get details of a role.", value = "Getting Details of a Role",
notes = "If you wish to get the details of a role in EMM, you can do so using this REST API.", notes = "Get the permissions associated with a role and role specific details using this REST API.",
response = RoleInfo.class, response = RoleInfo.class,
tags = "Role Management") tags = "Role Management")
@ApiResponses( @ApiResponses(
value = { value = {
@ApiResponse( @ApiResponse(
code = 200, code = 200,
message = "OK. \n Successfully fetched the requested role.", message = "OK. \n Successfully fetched the details of the role.",
response = RoleInfo.class, response = RoleInfo.class,
responseHeaders = { responseHeaders = {
@ResponseHeader( @ResponseHeader(
@ -203,15 +210,14 @@ public interface RoleManagementService {
}), }),
@ApiResponse( @ApiResponse(
code = 304, code = 304,
message = "Not Modified. \n Empty body because the client has already the latest version of" + message = "Not Modified. \n Empty body because the client already has the latest version of the requested resource."),
" the requested resource."),
@ApiResponse( @ApiResponse(
code = 400, code = 400,
message = "Bad Request. \n Invalid request or validation error.", message = "Bad Request. \n Invalid request or validation error.",
response = ErrorResponse.class), response = ErrorResponse.class),
@ApiResponse( @ApiResponse(
code = 404, code = 404,
message = "Not Found. \n Role does not exist.", message = "Not Found. \n The specified role does not exist.",
response = ErrorResponse.class), response = ErrorResponse.class),
@ApiResponse( @ApiResponse(
code = 406, code = 406,
@ -219,7 +225,7 @@ public interface RoleManagementService {
response = ErrorResponse.class), response = ErrorResponse.class),
@ApiResponse( @ApiResponse(
code = 500, code = 500,
message = "Internal Server Error. \n Server error occurred while fetching the " + message = "Internal Server Error. \n Server error occurred while fetching the details of" +
"requested role.", "requested role.",
response = ErrorResponse.class) response = ErrorResponse.class)
}) })
@ -227,12 +233,15 @@ public interface RoleManagementService {
Response getRole( Response getRole(
@ApiParam( @ApiParam(
name = "roleName", name = "roleName",
value = "Name of the role.", value = "The name of the role.",
required = true) required = true,
defaultValue = "admin")
@PathParam("roleName") String roleName, @PathParam("roleName") String roleName,
@ApiParam( @ApiParam(
name = "If-Modified-Since", name = "If-Modified-Since",
value = "Validates if the requested variant has not been modified since the time specified", value = "Checks if the requested variant was modified, since the specified date-time." +
"Provide the value in the following format: EEE, d MMM yyyy HH:mm:ss Z.\n" +
"Example: Mon, 05 Jan 2014 15:10:00 +0200",
required = false) required = false)
@HeaderParam("If-Modified-Since") String ifModifiedSince); @HeaderParam("If-Modified-Since") String ifModifiedSince);
@ -241,17 +250,17 @@ public interface RoleManagementService {
consumes = MediaType.APPLICATION_JSON, consumes = MediaType.APPLICATION_JSON,
produces = MediaType.APPLICATION_JSON, produces = MediaType.APPLICATION_JSON,
httpMethod = "POST", httpMethod = "POST",
value = "Add a role.", value = "Adding a Role",
notes = "You are able to add a new role to EMM using the REST API.", notes = "WSO2 EMM supports role-based access control (RBAC) and role management. Add a new role to WSO2 EMM using this REST API.",
tags = "Role Management") tags = "Role Management")
@ApiResponses(value = { @ApiResponses(value = {
@ApiResponse( @ApiResponse(
code = 201, code = 201,
message = "Created. \n Role has successfully been created", message = "Created. \n Successfully created the role.",
responseHeaders = { responseHeaders = {
@ResponseHeader( @ResponseHeader(
name = "Content-Location", name = "Content-Location",
description = "The URL of the role added."), description = "The URL to the newly added role."),
@ResponseHeader( @ResponseHeader(
name = "Content-Type", name = "Content-Type",
description = "The content type of the body"), description = "The content type of the body"),
@ -265,7 +274,7 @@ public interface RoleManagementService {
"Used by caches, or in conditional requests.")}), "Used by caches, or in conditional requests.")}),
@ApiResponse( @ApiResponse(
code = 303, code = 303,
message = "See Other. \n Source can be retrieved from the URL specified at the Location header.", message = "See Other. \n The source can be retrieved from the URL specified in the location header.",
responseHeaders = { responseHeaders = {
@ResponseHeader( @ResponseHeader(
name = "Content-Location", name = "Content-Location",
@ -276,7 +285,7 @@ public interface RoleManagementService {
response = ErrorResponse.class), response = ErrorResponse.class),
@ApiResponse( @ApiResponse(
code = 415, code = 415,
message = "Unsupported media type. \n The entity of the request was in a not supported format.", message = "Unsupported media type. \n The format of the requested entity was not supported.",
response = ErrorResponse.class), response = ErrorResponse.class),
@ApiResponse( @ApiResponse(
code = 500, code = 500,
@ -287,7 +296,7 @@ public interface RoleManagementService {
Response addRole( Response addRole(
@ApiParam( @ApiParam(
name = "role", name = "role",
value = "Details about the role to be added.", value = "The properties required to add a new role.",
required = true) RoleInfo role); required = true) RoleInfo role);
@PUT @PUT
@ -296,14 +305,14 @@ public interface RoleManagementService {
consumes = MediaType.APPLICATION_JSON, consumes = MediaType.APPLICATION_JSON,
produces = MediaType.APPLICATION_JSON, produces = MediaType.APPLICATION_JSON,
httpMethod = "PUT", httpMethod = "PUT",
value = "Update a role.", value = "Updating Role Details",
notes = "There will be situations where you will need to update the role details, such as the permissions" + notes = "There will be situations where you need to update the role details, such as the permissions" +
" or the role name. In such situation you can update the role details.", " or the role name. Update the role details using this REST API.",
tags = "Role Management") tags = "Role Management")
@ApiResponses(value = { @ApiResponses(value = {
@ApiResponse( @ApiResponse(
code = 200, code = 200,
message = "OK. \n Role has been updated successfully", message = "OK. \n Successfully updated the specified role.",
responseHeaders = { responseHeaders = {
@ResponseHeader( @ResponseHeader(
name = "Content-Type", name = "Content-Type",
@ -314,7 +323,7 @@ public interface RoleManagementService {
"Used by caches, or in conditional requests."), "Used by caches, or in conditional requests."),
@ResponseHeader( @ResponseHeader(
name = "Last-Modified", name = "Last-Modified",
description = "Date and time the resource has been modified the last time.\n" + description = "Date and time the resource was last modified.\n" +
"Used by caches, or in conditional requests.")}), "Used by caches, or in conditional requests.")}),
@ApiResponse( @ApiResponse(
code = 400, code = 400,
@ -322,11 +331,11 @@ public interface RoleManagementService {
response = ErrorResponse.class), response = ErrorResponse.class),
@ApiResponse( @ApiResponse(
code = 404, code = 404,
message = "Not Found. \n Role to be deleted does not exist.", message = "Not Found. \n The specified role does not exist.",
response = ErrorResponse.class), response = ErrorResponse.class),
@ApiResponse( @ApiResponse(
code = 415, code = 415,
message = "Unsupported media type. \n The entity of the request was in a not supported format.", message = "Unsupported media type. \n The format of the requested entity was not supported.\n",
response = ErrorResponse.class), response = ErrorResponse.class),
@ApiResponse( @ApiResponse(
code = 500, code = 500,
@ -337,33 +346,34 @@ public interface RoleManagementService {
Response updateRole( Response updateRole(
@ApiParam( @ApiParam(
name = "roleName", name = "roleName",
value = "Name of the role.", value = "The name of the role.",
required = true) required = true,
defaultValue = "engineer")
@PathParam("roleName") String roleName, @PathParam("roleName") String roleName,
@ApiParam( @ApiParam(
name = "role", name = "role",
value = "Details about the role to be added.", value = "The properties required to update a role.",
required = true) RoleInfo role); required = true) RoleInfo role);
@DELETE @DELETE
@Path("/{roleName}") @Path("/{roleName}")
@ApiOperation( @ApiOperation(
httpMethod = "DELETE", httpMethod = "DELETE",
value = "Delete a role.", value = "Deleting a Role",
notes = "In a situation when your Organization identifies that a specific role is no longer required you " + notes = "Roles become obsolete over time due to various reasons. In a situation where your Organization identifies that a specific role is no longer required, you " +
"will need to remove the role details from EMM.", "can delete a role using this REST API.",
tags = "Role Management") tags = "Role Management")
@ApiResponses(value = { @ApiResponses(value = {
@ApiResponse( @ApiResponse(
code = 200, code = 200,
message = "OK. \n Role has successfully been removed"), message = "OK. \n Successfully removed the specified role."),
@ApiResponse( @ApiResponse(
code = 400, code = 400,
message = "Bad Request. \n Invalid request or validation error.", message = "Bad Request. \n Invalid request or validation error.",
response = ErrorResponse.class), response = ErrorResponse.class),
@ApiResponse( @ApiResponse(
code = 404, code = 404,
message = "Not Found. \n Role to be deleted does not exist.", message = "Not Found. \n The specified role does not exist.",
response = ErrorResponse.class), response = ErrorResponse.class),
@ApiResponse( @ApiResponse(
code = 500, code = 500,
@ -374,8 +384,9 @@ public interface RoleManagementService {
Response deleteRole( Response deleteRole(
@ApiParam( @ApiParam(
name = "roleName", name = "roleName",
value = "Name of the role to de deleted.", value = "The name of the role that needs to de deleted.",
required = true) required = true,
defaultValue = "engineer")
@PathParam("roleName") String roleName); @PathParam("roleName") String roleName);
@PUT @PUT
@ -384,19 +395,19 @@ public interface RoleManagementService {
consumes = MediaType.APPLICATION_JSON, consumes = MediaType.APPLICATION_JSON,
produces = MediaType.APPLICATION_JSON, produces = MediaType.APPLICATION_JSON,
httpMethod = "PUT", httpMethod = "PUT",
value = "Add users to a role.", value = "Adding Users to a Role",
notes = "Defining the users to a role at the point of creating a new role is optional, " + notes = "Defining users to a role at the point of creating a new role is optional. " +
"therefore you are able to update the users that belong to a given role after you have created " + "You can update the users that belong to a given role after you have created " +
"a role using this REST API." + "a role using this REST API.\n" +
"Example: Your Organization hires 30 new engineers. Updating the role details for each user can " + "Example: Your Organization hires 30 new engineers. Updating the role details for each user can " +
"be cumbersome, therefore you can define all the new employees that belong to the engineering " + "be cumbersome. Therefore, you can define all the new employees that belong to the engineering " +
"role using this API.", "role using this API.",
tags = "Role Management") tags = "Role Management")
@ApiResponses( @ApiResponses(
value = { value = {
@ApiResponse( @ApiResponse(
code = 200, code = 200,
message = "OK. \n User list of the role has been updated successfully", message = "OK. \n Successfully added the users to the specified role.",
responseHeaders = { responseHeaders = {
@ResponseHeader( @ResponseHeader(
name = "Content-Type", name = "Content-Type",
@ -415,17 +426,17 @@ public interface RoleManagementService {
response = ErrorResponse.class), response = ErrorResponse.class),
@ApiResponse( @ApiResponse(
code = 404, code = 404,
message = "Not Found. \n Resource to be deleted does not exist.", message = "Not Found. \n The specified role does not exist.",
response = ErrorResponse.class), response = ErrorResponse.class),
@ApiResponse( @ApiResponse(
code = 415, code = 415,
message = "Unsupported media type. \n The entity of the request was in a not " + message = "Unsupported media type. \n The format of the requested entity was not supported.\n" +
"supported format.", "supported format.",
response = ErrorResponse.class), response = ErrorResponse.class),
@ApiResponse( @ApiResponse(
code = 500, code = 500,
message = "Internal Server Error. \n " + message = "Internal Server Error. \n " +
"Server error occurred while updating the user list of the role.", "Server error occurred while adding the user to the specified role.",
response = ErrorResponse.class) response = ErrorResponse.class)
}) })
@Permission(name = "Manage Roles", permission = "/device-mgt/roles/manage") @Permission(name = "Manage Roles", permission = "/device-mgt/roles/manage")
@ -437,7 +448,10 @@ public interface RoleManagementService {
@PathParam("roleName") String roleName, @PathParam("roleName") String roleName,
@ApiParam( @ApiParam(
name = "users", name = "users",
value = "List of usernames to be added.", value = "Define the users that belong to the role.\n" +
required = true) List<String> users); "Multiple users can be added to a role by using comma separated values. ",
required = true,
defaultValue = "[jim]"
) List<String> users);
} }

@ -142,6 +142,11 @@ public interface UserManagementService {
value = "Username of the user to be fetched.", value = "Username of the user to be fetched.",
required = true) required = true)
@PathParam("username") String username, @PathParam("username") String username,
@ApiParam(
name = "domain",
value = "Domain name of the user store.",
required = false)
@QueryParam("domain") String domain,
@ApiParam( @ApiParam(
name = "If-Modified-Since", name = "If-Modified-Since",
value = "Validates if the requested variant has not been modified since the time specified", value = "Validates if the requested variant has not been modified since the time specified",
@ -199,6 +204,11 @@ public interface UserManagementService {
value = "Username of the user to be updated.", value = "Username of the user to be updated.",
required = true) required = true)
@PathParam("username") String username, @PathParam("username") String username,
@ApiParam(
name = "domain",
value = "Domain name of the user store.",
required = false)
@QueryParam("domain") String domain,
@ApiParam( @ApiParam(
name = "userData", name = "userData",
value = "User related details.", value = "User related details.",
@ -230,7 +240,12 @@ public interface UserManagementService {
@Permission(name = "Manage Users", permission = "/device-mgt/users/manage") @Permission(name = "Manage Users", permission = "/device-mgt/users/manage")
Response removeUser( Response removeUser(
@ApiParam(name = "username", value = "Username of the user to be deleted.", required = true) @ApiParam(name = "username", value = "Username of the user to be deleted.", required = true)
@PathParam("username") String username); @PathParam("username") String username,
@ApiParam(
name = "domain",
value = "Domain name of the user store.",
required = false)
@QueryParam("domain") String domain);
@GET @GET
@Path("/{username}/roles") @Path("/{username}/roles")
@ -279,7 +294,12 @@ public interface UserManagementService {
@Permission(name = "View Users", permission = "/device-mgt/users/view") @Permission(name = "View Users", permission = "/device-mgt/users/view")
Response getRolesOfUser( Response getRolesOfUser(
@ApiParam(name = "username", value = "Username of the user.", required = true) @ApiParam(name = "username", value = "Username of the user.", required = true)
@PathParam("username") String username); @PathParam("username") String username,
@ApiParam(
name = "domain",
value = "Domain name of the user store.",
required = false)
@QueryParam("domain") String domain);
@GET @GET
@ApiOperation( @ApiOperation(

@ -49,14 +49,14 @@ public interface ApplicationManagementAdminService {
consumes = MediaType.APPLICATION_JSON, consumes = MediaType.APPLICATION_JSON,
produces = MediaType.APPLICATION_JSON, produces = MediaType.APPLICATION_JSON,
httpMethod = "POST", httpMethod = "POST",
value = "Application installation API.(Internal API)", value = "Installing an Application (Internal API)",
notes = "This is an internal API used for application installation on a device.", notes = "This is an internal API that can be used to install an application on a device.",
response = Activity.class, response = Activity.class,
tags = "Application Management Administrative Service") tags = "Application Management Administrative Service")
@ApiResponses(value = { @ApiResponses(value = {
@ApiResponse( @ApiResponse(
code = 202, code = 202,
message = "OK. \n Install application operation will be delivered to the given devices", message = "Accepted. \n The install application operation will be delivered to the specified devices",
response = Activity.class), response = Activity.class),
@ApiResponse( @ApiResponse(
code = 400, code = 400,
@ -64,15 +64,15 @@ public interface ApplicationManagementAdminService {
response = ErrorResponse.class), response = ErrorResponse.class),
@ApiResponse( @ApiResponse(
code = 404, code = 404,
message = "Not Found. \n Resource to be processed does not exist."), message = "Not Found. \n The specified resource does not exist."),
@ApiResponse( @ApiResponse(
code = 415, code = 415,
message = "Unsupported media type. \n The entity of the request was in a not supported format."), message = "Unsupported media type. \n The format of the requested entity was not supported."),
@ApiResponse( @ApiResponse(
code = 500, code = 500,
message = "Internal Server Error. \n " + message = "Internal Server Error. \n " +
"Server error occurred while bulk issuing application installation operations upon " + "Server error occurred while executing the application install operation in bulk" +
"a given set of devices.", " for a specified set of devices.",
response = ErrorResponse.class) response = ErrorResponse.class)
}) })
@Permission(name = "Install/Uninstall applications", permission = "/device-mgt/applications/manage") @Permission(name = "Install/Uninstall applications", permission = "/device-mgt/applications/manage")
@ -88,14 +88,14 @@ public interface ApplicationManagementAdminService {
consumes = MediaType.APPLICATION_JSON, consumes = MediaType.APPLICATION_JSON,
produces = MediaType.APPLICATION_JSON, produces = MediaType.APPLICATION_JSON,
httpMethod = "POST", httpMethod = "POST",
value = "Application un-installation API.(Internal API)", value = "Uninstalling an Application (Internal API)\n",
notes = "This is an internal API used for application un-installation on a device.", notes = "This is an internal API that can be used to uninstall an application.",
response = Activity.class, response = Activity.class,
tags = "Application Management Administrative Service") tags = "Application Management Administrative Service")
@ApiResponses(value = { @ApiResponses(value = {
@ApiResponse( @ApiResponse(
code = 202, code = 202,
message = "OK. \n Uninstall application operation will be delivered to the provided devices", message = "Accepted. \n The uninstall application operation will be delivered to the provided devices",
response = Activity.class), response = Activity.class),
@ApiResponse( @ApiResponse(
code = 400, code = 400,
@ -103,15 +103,14 @@ public interface ApplicationManagementAdminService {
response = ErrorResponse.class), response = ErrorResponse.class),
@ApiResponse( @ApiResponse(
code = 404, code = 404,
message = "Not Found. \n Resource to be processed does not exist."), message = "Not Found. \n The specified resource does not exist."),
@ApiResponse( @ApiResponse(
code = 415, code = 415,
message = "Unsupported media type. \n The entity of the request was in a not supported format."), message = "Unsupported media type. \n The entity of the request was in a not supported format."),
@ApiResponse( @ApiResponse(
code = 500, code = 500,
message = "Internal Server Error. \n " + message = "Internal Server Error. \n Server error occurred while executing the application install operation in bulk" +
"Server error occurred while bulk issuing application un-installation operations upon " + " for a specified set of devices.",
"a given set of devices.",
response = ErrorResponse.class) response = ErrorResponse.class)
}) })
@Permission(name = "Install/Uninstall applications", permission = "/device-mgt/applications/manage") @Permission(name = "Install/Uninstall applications", permission = "/device-mgt/applications/manage")

@ -78,6 +78,11 @@ public interface UserManagementAdminService {
@PathParam("username") @PathParam("username")
@Size(max = 45) @Size(max = 45)
String username, String username,
@ApiParam(
name = "domain",
value = "Domain name of the user store.",
required = false)
@QueryParam("domain") String domain,
@ApiParam( @ApiParam(
name = "credentials", name = "credentials",
value = "Credential.", value = "Credential.",

@ -105,8 +105,11 @@ public class UserManagementServiceImpl implements UserManagementService {
@GET @GET
@Path("/{username}") @Path("/{username}")
@Override @Override
public Response getUser(@PathParam("username") String username, public Response getUser(@PathParam("username") String username, @QueryParam("domain") String domain,
@HeaderParam("If-Modified-Since") String ifModifiedSince) { @HeaderParam("If-Modified-Since") String ifModifiedSince) {
if (domain != null && !domain.isEmpty()) {
username = domain + '/' + username;
}
try { try {
UserStoreManager userStoreManager = DeviceMgtAPIUtils.getUserStoreManager(); UserStoreManager userStoreManager = DeviceMgtAPIUtils.getUserStoreManager();
if (!userStoreManager.isExistingUser(username)) { if (!userStoreManager.isExistingUser(username)) {
@ -131,7 +134,10 @@ public class UserManagementServiceImpl implements UserManagementService {
@PUT @PUT
@Path("/{username}") @Path("/{username}")
@Override @Override
public Response updateUser(@PathParam("username") String username, UserInfo userInfo) { public Response updateUser(@PathParam("username") String username, @QueryParam("domain") String domain, UserInfo userInfo) {
if (domain != null && !domain.isEmpty()) {
username = domain + '/' + username;
}
try { try {
UserStoreManager userStoreManager = DeviceMgtAPIUtils.getUserStoreManager(); UserStoreManager userStoreManager = DeviceMgtAPIUtils.getUserStoreManager();
if (!userStoreManager.isExistingUser(username)) { if (!userStoreManager.isExistingUser(username)) {
@ -205,7 +211,10 @@ public class UserManagementServiceImpl implements UserManagementService {
@DELETE @DELETE
@Path("/{username}") @Path("/{username}")
@Override @Override
public Response removeUser(@PathParam("username") String username) { public Response removeUser(@PathParam("username") String username, @QueryParam("domain") String domain) {
if (domain != null && !domain.isEmpty()) {
username = domain + '/' + username;
}
try { try {
UserStoreManager userStoreManager = DeviceMgtAPIUtils.getUserStoreManager(); UserStoreManager userStoreManager = DeviceMgtAPIUtils.getUserStoreManager();
if (!userStoreManager.isExistingUser(username)) { if (!userStoreManager.isExistingUser(username)) {
@ -233,7 +242,10 @@ public class UserManagementServiceImpl implements UserManagementService {
@GET @GET
@Path("/{username}/roles") @Path("/{username}/roles")
@Override @Override
public Response getRolesOfUser(@PathParam("username") String username) { public Response getRolesOfUser(@PathParam("username") String username, @QueryParam("domain") String domain) {
if (domain != null && !domain.isEmpty()) {
username = domain + '/' + username;
}
try { try {
UserStoreManager userStoreManager = DeviceMgtAPIUtils.getUserStoreManager(); UserStoreManager userStoreManager = DeviceMgtAPIUtils.getUserStoreManager();
if (!userStoreManager.isExistingUser(username)) { if (!userStoreManager.isExistingUser(username)) {

@ -37,7 +37,10 @@ public class UserManagementAdminServiceImpl implements UserManagementAdminServic
@Override @Override
public Response resetUserPassword(@PathParam("username") public Response resetUserPassword(@PathParam("username")
@Size(max = 45) @Size(max = 45)
String user, PasswordResetWrapper credentials) { String user, @QueryParam("domain") String domain, PasswordResetWrapper credentials) {
if (domain != null && !domain.isEmpty()) {
user = domain + '/' + user;
}
return CredentialManagementResponseBuilder.buildResetPasswordResponse(user, credentials); return CredentialManagementResponseBuilder.buildResetPasswordResponse(user, credentials);
} }

@ -25,8 +25,8 @@ import io.swagger.annotations.ApiModelProperty;
import java.util.List; import java.util.List;
@ApiModel(value = "Activity", description = "An activity instance carries a unique identifier that can be " + @ApiModel(value = "Activity", description = "Each activity instance has a unique identifier that can be " +
"used to identify a particular operation instance uniquely") "used to identify an operation instance.")
public class Activity { public class Activity {
public enum Type { public enum Type {
@ -35,21 +35,21 @@ public class Activity {
@ApiModelProperty( @ApiModelProperty(
name = "activityId", name = "activityId",
value = "Activity identifier", value = "The unique activity identifier",
required = true) required = true)
@JsonProperty("activityId") @JsonProperty("activityId")
private String activityId; private String activityId;
@ApiModelProperty( @ApiModelProperty(
name = "code", name = "code",
value = "Activity code", value = "The activity code",
required = true) required = true)
@JsonProperty("code") @JsonProperty("code")
private String code; private String code;
@ApiModelProperty( @ApiModelProperty(
name = "type", name = "type",
value = "Activity type", value = "The type of the activity, such as CONFIG, MESSAGE, INFO, COMMAND, PROFILE, POLICY.",
required = true, required = true,
allowableValues = "CONFIG, MESSAGE, INFO, COMMAND, PROFILE, POLICY") allowableValues = "CONFIG, MESSAGE, INFO, COMMAND, PROFILE, POLICY")
@JsonProperty("type") @JsonProperty("type")
@ -57,14 +57,14 @@ public class Activity {
@ApiModelProperty( @ApiModelProperty(
name = "createdTimeStamp", name = "createdTimeStamp",
value = "Timestamp recorded when the activity took place", value = "The recorded timestamp of when the activity took place.",
required = true) required = true)
@JsonProperty("createdTimestamp") @JsonProperty("createdTimestamp")
private String createdTimeStamp; private String createdTimeStamp;
@ApiModelProperty( @ApiModelProperty(
name = "activityStatuses", name = "activityStatuses",
value = "Collection of statuses corresponding to the activity", value = "The collection of statuses for a given activity.",
required = true) required = true)
@JsonProperty("activityStatuses") @JsonProperty("activityStatuses")
private List<ActivityStatus> activityStatus; private List<ActivityStatus> activityStatus;

@ -51,7 +51,12 @@ if (uriMatcher.match("/{context}/api/operation/paginate")) {
} else { } else {
response["status"] = restAPIResponse["status"]; response["status"] = restAPIResponse["status"];
if (restAPIResponse["responseText"]) { if (restAPIResponse["responseText"]) {
var responseText = "";
try {
response["content"] = parse(restAPIResponse["responseText"]); response["content"] = parse(restAPIResponse["responseText"]);
} catch (e) {
responseText = restAPIResponse["responseText"];
}
} }
} }
} }

@ -177,10 +177,18 @@ var userModule = function () {
*/ */
publicMethods.getUser = function (username) { publicMethods.getUser = function (username) {
var carbonUser = privateMethods.getCarbonUser(); var carbonUser = privateMethods.getCarbonUser();
var domain;
if (username.indexOf('/') > 0) {
domain = username.substr(0, username.indexOf('/'));
username = username.substr(username.indexOf('/') + 1);
}
try { try {
utility.startTenantFlow(carbonUser); utility.startTenantFlow(carbonUser);
var url = devicemgtProps["httpsURL"] + devicemgtProps["backendRestEndpoints"]["deviceMgt"] + "/users/" + var url = devicemgtProps["httpsURL"] + devicemgtProps["backendRestEndpoints"]["deviceMgt"] + "/users/" +
encodeURIComponent(username); encodeURIComponent(username);
if (domain) {
url += '?domain=' + domain;
}
var response = privateMethods.callBackend(url, constants["HTTP_GET"]); var response = privateMethods.callBackend(url, constants["HTTP_GET"]);
response["content"] = parse(response.content); response["content"] = parse(response.content);
response["userDomain"] = carbonUser.domain; response["userDomain"] = carbonUser.domain;
@ -199,10 +207,18 @@ var userModule = function () {
*/ */
publicMethods.getRolesByUsername = function (username) { publicMethods.getRolesByUsername = function (username) {
var carbonUser = privateMethods.getCarbonUser(); var carbonUser = privateMethods.getCarbonUser();
var domain;
if (username.indexOf('/') > 0) {
domain = username.substr(0, username.indexOf('/'));
username = username.substr(username.indexOf('/') + 1);
}
try { try {
utility.startTenantFlow(carbonUser); utility.startTenantFlow(carbonUser);
var url = devicemgtProps["httpsURL"] + devicemgtProps["backendRestEndpoints"]["deviceMgt"] + "/users/" + var url = devicemgtProps["httpsURL"] + devicemgtProps["backendRestEndpoints"]["deviceMgt"] + "/users/" +
encodeURIComponent(username) + "/roles"; encodeURIComponent(username) + "/roles";
if (domain) {
url += '?domain=' + domain;
}
var response = privateMethods.callBackend(url, constants["HTTP_GET"]); var response = privateMethods.callBackend(url, constants["HTTP_GET"]);
if (response.status == "success") { if (response.status == "success") {
response.content = parse(response.content).roles; response.content = parse(response.content).roles;

@ -45,12 +45,13 @@ var invokers = function () {
* If the token pair is not set in the session, this will return null. * If the token pair is not set in the session, this will return null.
*/ */
privateMethods.getAccessToken = function () { privateMethods.getAccessToken = function () {
if (session) {
var tokenPair = session.get(constants["TOKEN_PAIR"]); var tokenPair = session.get(constants["TOKEN_PAIR"]);
if (tokenPair) { if (tokenPair) {
return parse(tokenPair)["accessToken"]; return parse(tokenPair)["accessToken"];
} else {
return null;
} }
}
return null;
}; };
/** /**
@ -80,7 +81,7 @@ var invokers = function () {
if (devicemgtProps["isOAuthEnabled"]) { if (devicemgtProps["isOAuthEnabled"]) {
var accessToken = privateMethods.getAccessToken(); var accessToken = privateMethods.getAccessToken();
if (!accessToken) { if (accessToken == null) {
userModule.logout(function () { userModule.logout(function () {
response.sendRedirect(devicemgtProps["appContext"] + "login"); response.sendRedirect(devicemgtProps["appContext"] + "login");
}); });

@ -83,7 +83,7 @@ function hidePopup() {
* initial mode and with out select mode. * initial mode and with out select mode.
*/ */
function InitiateViewOption() { function InitiateViewOption() {
$(location).attr('href', $(this).data("url")); // $(location).attr('href', $(this).data("url"));
} }
function loadRoles() { function loadRoles() {

@ -235,8 +235,8 @@ $(document).ready(function () {
roles = []; roles = [];
} }
addUserFormData.roles = roles; addUserFormData.roles = roles;
username = username.substr(username.indexOf('/') + 1);
var addUserAPI = deviceMgtBasePath + "/users/" + username; var addUserAPI = deviceMgtBasePath + "/users/" + username + "?domain=" + domain;
invokerUtil.put( invokerUtil.put(
addUserAPI, addUserAPI,

@ -162,9 +162,15 @@ function resetPassword(username) {
} else { } else {
var resetPasswordFormData = {}; var resetPasswordFormData = {};
resetPasswordFormData.newPassword = unescape(confirmedPassword); resetPasswordFormData.newPassword = unescape(confirmedPassword);
var domain;
var resetPasswordServiceURL = apiBasePath + "/admin/users/"+ username +"/credentials"; if (username.indexOf('/') > 0) {
domain = username.substr(0, username.indexOf('/'));
username = username.substr(username.indexOf('/') + 1);
}
var resetPasswordServiceURL = apiBasePath + "/admin/users/" + username + "/credentials";
if (domain) {
resetPasswordServiceURL += '?domain=' + domain;
}
invokerUtil.post( invokerUtil.post(
resetPasswordServiceURL, resetPasswordServiceURL,
resetPasswordFormData, resetPasswordFormData,
@ -198,7 +204,15 @@ function resetPassword(username) {
* on User Listing page in WSO2 MDM Console. * on User Listing page in WSO2 MDM Console.
*/ */
function removeUser(username) { function removeUser(username) {
var domain;
if (username.indexOf('/') > 0) {
domain = username.substr(0, username.indexOf('/'));
username = username.substr(username.indexOf('/') + 1);
}
var removeUserAPI = apiBasePath + "/users/" + username; var removeUserAPI = apiBasePath + "/users/" + username;
if (domain) {
removeUserAPI += '?domain=' + domain;
}
$(modalPopupContent).html($('#remove-user-modal-content').html()); $(modalPopupContent).html($('#remove-user-modal-content').html());
showPopup(); showPopup();
@ -207,7 +221,11 @@ function removeUser(username) {
removeUserAPI, removeUserAPI,
function (data, textStatus, jqXHR) { function (data, textStatus, jqXHR) {
if (jqXHR.status == 200) { if (jqXHR.status == 200) {
if (domain) {
$("#user-" + domain + "\\/" + username).remove();
} else {
$("#user-" + username).remove(); $("#user-" + username).remove();
}
// update modal-content with success message // update modal-content with success message
$(modalPopupContent).html($('#remove-user-success-content').html()); $(modalPopupContent).html($('#remove-user-success-content').html());
$("a#remove-user-success-link").click(function () { $("a#remove-user-success-link").click(function () {
@ -281,9 +299,11 @@ function loadUsers() {
{ {
class: "remove-padding icon-only content-fill", class: "remove-padding icon-only content-fill",
data: null, data: null,
defaultContent: '<div class="thumbnail icon">' + render: function (data, type, row, meta) {
return '<div class="thumbnail icon viewEnabledIcon" data-url="' + context +'/user/view?username=' + data.filter + '">' +
'<i class="square-element text fw fw-user" style="font-size: 74px;"></i>' + '<i class="square-element text fw fw-user" style="font-size: 74px;"></i>' +
'</div>' '</div>';
}
}, },
{ {
class: "fade-edge", class: "fade-edge",
@ -318,7 +338,7 @@ function loadUsers() {
class: "text-right content-fill text-left-on-grid-view no-wrap", class: "text-right content-fill text-left-on-grid-view no-wrap",
data: null, data: null,
render: function (data, type, row, meta) { render: function (data, type, row, meta) {
return '&nbsp;<a href="/emm/user/edit?username=' + data.filter + '" data-username="' + data.filter + '" ' + var editbtn= '&nbsp;<a data-toggle="tooltip" data-placement="bottom" title="Edit User"href="' + context + '/user/edit?username=' + data.filter + '" data-username="' + data.filter + '" ' +
'data-click-event="edit-form" ' + 'data-click-event="edit-form" ' +
'class="btn padding-reduce-on-grid-view edit-user-link"> ' + 'class="btn padding-reduce-on-grid-view edit-user-link"> ' +
'<span class="fw-stack"> ' + '<span class="fw-stack"> ' +
@ -328,8 +348,9 @@ function loadUsers() {
'<span class="hidden-xs hidden-on-grid-view">' + '<span class="hidden-xs hidden-on-grid-view">' +
'&nbsp;&nbsp;Edit' + '&nbsp;&nbsp;Edit' +
'</span>' + '</span>' +
'</a>' + '</a>';
'<a href="#" data-username="' + data.filter + '" data-userid="' + data.filter + '" ' +
var resetPasswordbtn = '<a data-toggle="tooltip" data-placement="bottom" title="Reset Password" href="#" data-username="' + data.filter + '" data-userid="' + data.filter + '" ' +
'data-click-event="edit-form" ' + 'data-click-event="edit-form" ' +
'onclick="javascript:resetPassword(\'' + data.filter + '\')" ' + 'onclick="javascript:resetPassword(\'' + data.filter + '\')" ' +
'class="btn padding-reduce-on-grid-view remove-user-link">' + 'class="btn padding-reduce-on-grid-view remove-user-link">' +
@ -340,8 +361,9 @@ function loadUsers() {
'<span class="hidden-xs hidden-on-grid-view">' + '<span class="hidden-xs hidden-on-grid-view">' +
'&nbsp;&nbsp;Reset Password' + '&nbsp;&nbsp;Reset Password' +
'</span>' + '</span>' +
'</a>' + '</a>';
'<a href="#" data-username="' + data.filter + '" data-userid="' + data.filter + '" ' +
var removebtn = '<a data-toggle="tooltip" data-placement="bottom" title="Remove User" href="#" data-username="' + data.filter + '" data-userid="' + data.filter + '" ' +
'data-click-event="remove-form" ' + 'data-click-event="remove-form" ' +
'onclick="javascript:removeUser(\'' + data.filter + '\')" ' + 'onclick="javascript:removeUser(\'' + data.filter + '\')" ' +
'class="btn padding-reduce-on-grid-view remove-user-link">' + 'class="btn padding-reduce-on-grid-view remove-user-link">' +
@ -353,6 +375,19 @@ function loadUsers() {
'&nbsp;&nbsp;Remove' + '&nbsp;&nbsp;Remove' +
'</span>' + '</span>' +
'</a>'; '</a>';
var returnbtnSet = '';
if($("#can-edit").length > 0) {
returnbtnSet = returnbtnSet + editbtn;
}
if($("#can-reset-password").length > 0) {
returnbtnSet = returnbtnSet + resetPasswordbtn;
}
if($("#can-remove").length > 0) {
returnbtnSet = returnbtnSet + removebtn;
}
return returnbtnSet;
} }
} }
@ -365,14 +400,16 @@ function loadUsers() {
$('#user-grid').datatables_extended_serverside_paging(null, '/api/device-mgt/v1.0/users', dataFilter, columns, fnCreatedRow, null, options); $('#user-grid').datatables_extended_serverside_paging(null, '/api/device-mgt/v1.0/users', dataFilter, columns, fnCreatedRow, null, options);
$(loadingContentView).hide(); $(loadingContentView).hide();
} }
$(document).ready(function () { $(document).ready(function () {
loadUsers(); loadUsers();
$(".viewEnabledIcon").click(function () { $(function () {
InitiateViewOption(); $('[data-toggle="tooltip"]').tooltip()
}); });
if (!$("#can-invite").val()) { if (!$("#can-invite").val()) {
$("#invite-user-button").remove(); $("#invite-user-button").remove();
} }
}); });

@ -25,7 +25,7 @@ $.fn.datatables_extended = function(settings){
// EMM related function // EMM related function
if (InitiateViewOption) { if (InitiateViewOption) {
$(".viewEnabledIcon").bind("click", InitiateViewOption); $(document).on('click','.viewEnabledIcon',InitiateViewOption);
} }
//--- End of EMM related codes //--- End of EMM related codes

@ -35,7 +35,7 @@ $.fn.datatables_extended_serverside_paging = function (settings , url, dataFilte
// EMM related function // EMM related function
if (InitiateViewOption) { if (InitiateViewOption) {
$(".viewEnabledIcon").bind("click", InitiateViewOption); $(document).on('click','.viewEnabledIcon',InitiateViewOption);
} }
var deviceType; var deviceType;
@ -239,14 +239,14 @@ $.fn.datatables_extended_serverside_paging = function (settings , url, dataFilte
$(button).addClass("active").html('Cancel'); $(button).addClass("active").html('Cancel');
$(button).parent().next().children("button").removeClass("disabled"); $(button).parent().next().children("button").removeClass("disabled");
// EMM related code // EMM related code
$(".viewEnabledIcon").unbind("click"); $(document).off('click','.viewEnabledIcon');
//--- End of EMM related codes //--- End of EMM related codes
} else if ($(button).html() == 'Cancel') { } else if ($(button).html() == 'Cancel') {
thisTable.removeClass("table-selectable"); thisTable.removeClass("table-selectable");
$(button).addClass("active").html('Select'); $(button).addClass("active").html('Select');
$(button).parent().next().children().addClass("disabled"); $(button).parent().next().children().addClass("disabled");
// EMM related function // EMM related function
$(".viewEnabledIcon").bind("click", InitiateViewOption); $(document).on('click','.viewEnabledIcon',InitiateViewOption);
//--- End of EMM related codes //--- End of EMM related codes
} }
}); });

@ -22,7 +22,7 @@
<!-- content --> <!-- content -->
<div id="config-save-form" class="container col-centered wr-content"> <div id="config-save-form" class="container col-centered wr-content">
<br> <br>
Device Notifications <h4> Device Notifications </h4>
<br> <br>
<br> <br>
<div class="wr-advance-operations"> <div class="wr-advance-operations">

@ -65,6 +65,15 @@ function loadNotifications() {
function showAdvanceOperation(operation, button) { function showAdvanceOperation(operation, button) {
$(button).addClass('selected'); $(button).addClass('selected');
$(button).siblings().removeClass('selected'); $(button).siblings().removeClass('selected');
if ($(button).attr("id") == 'allNotifications') {
$("#ast-container").html('<div class="panel-body">You do not have any unread notifications </div>');
} else if ($(button).attr("id") == 'unReadNotifications') {
$("#ast-container").html('<div class="panel-body">You do not have any notifications </div>');
} else {
$("#ast-container").html('<div class="panel-body">You do not have any notifications </div>');
}
var hiddenOperation = ".wr-hidden-operations-content > div"; var hiddenOperation = ".wr-hidden-operations-content > div";
$(hiddenOperation + '[data-operation="' + operation + '"]').show(); $(hiddenOperation + '[data-operation="' + operation + '"]').show();
$(hiddenOperation + '[data-operation="' + operation + '"]').siblings().hide(); $(hiddenOperation + '[data-operation="' + operation + '"]').siblings().hide();
@ -82,7 +91,7 @@ $(document).ready(function () {
loadNotifications(); loadNotifications();
$("#ast-container").on("click", ".new-notification", function(e) { $("#ast-container").on("click", ".new-notification", function (e) {
var notificationId = $(this).data("id"); var notificationId = $(this).data("id");
// var redirectUrl = $(this).data("url"); // var redirectUrl = $(this).data("url");
var query = deviceMgtAPIBaseURI + "/notifications" + "/" + notificationId + "/mark-checked"; var query = deviceMgtAPIBaseURI + "/notifications" + "/" + notificationId + "/mark-checked";

@ -57,7 +57,7 @@
<tr data-type="selectable" data-id="{{id}}"> <tr data-type="selectable" data-id="{{id}}">
<td data-display="{{description}}" data-grid-label="Description">{{description}}</td> <td data-display="{{description}}" data-grid-label="Description">{{description}}</td>
<td style="text-align: center;"> <td style="text-align: center;">
<a href="{{appContext}}/device/{{deviceType}}?id={{deviceIdentifier}}" data-click-event="remove-form"> <a href="device/{{deviceType}}?id={{deviceIdentifier}}" data-click-event="remove-form">
<span class="fw-stack"> <span class="fw-stack">
<i class="fw fw-ring fw-stack-2x"></i> <i class="fw fw-ring fw-stack-2x"></i>
<i class="fw fw-view fw-stack-1x"></i> <i class="fw fw-view fw-stack-1x"></i>

@ -37,6 +37,11 @@
<a id="generalConfigLink" href="javascript:void(0)" onclick="showAdvanceOperation('general', this)" class="selected"> <a id="generalConfigLink" href="javascript:void(0)" onclick="showAdvanceOperation('general', this)" class="selected">
<span class="wr-hidden-operations-icon fw-stack"> <span class="wr-hidden-operations-icon fw-stack">
<i class="fw fw-settings fw-stack-2x"></i> <i class="fw fw-settings fw-stack-2x"></i>
<span class="fw-stack fw-move-right fw-move-bottom">
<i class="fw fw-circle fw-stack-2x fw-stroke fw-inverse"></i>
<i class="fw fw-circle fw-stack-2x"></i>
<i class="fw fw-mobile fw-stack-1x fw-inverse"></i>
</span>
</span> </span>
General Configurations General Configurations
</a> </a>
@ -44,6 +49,11 @@
<a id="{{name}}ConfigLink" href="javascript:void(0)" onclick="showAdvanceOperation('{{name}}', this)"> <a id="{{name}}ConfigLink" href="javascript:void(0)" onclick="showAdvanceOperation('{{name}}', this)">
<span class="wr-hidden-operations-icon fw-stack"> <span class="wr-hidden-operations-icon fw-stack">
<i class="fw fw-settings fw-stack-2x"></i> <i class="fw fw-settings fw-stack-2x"></i>
<span class="fw-stack fw-move-right fw-move-bottom">
<i class="fw fw-circle fw-stack-2x fw-stroke fw-inverse"></i>
<i class="fw fw-circle fw-stack-2x"></i>
<i class="fw fw-{{name}} fw-stack-1x fw-inverse"></i>
</span>
</span> </span>
{{label}} Configurations {{label}} Configurations
</a> </a>
@ -79,9 +89,7 @@
placeholder="[ Required Field ]"> placeholder="[ Required Field ]">
</div> </div>
<div class="wr-input-control wr-btn-grp"> <div class="wr-input-control wr-btn-grp">
<button id="save-general-btn" class="wr-btn"> <button id="save-general-btn" class="wr-btn">Save</button>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Save&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</button>
</div> </div>
</div> </div>
</div> </div>
@ -107,12 +115,8 @@
<b>"Exit"</b> to complete the process and go back to the dashboard. <b>"Exit"</b> to complete the process and go back to the dashboard.
<hr/> <hr/>
<button class="wr-btn" <button class="wr-btn"
onclick="window.location.href='{{@app.context}}/platform-configuration'">Go onclick="window.location.href='{{@app.context}}/platform-configuration'">Go back to configurations</button>
back <button class="wr-btn" onclick="window.location.href='{{@app.context}}'">Exit</button>
to
configurations
</button>
<button class="wr-btn" onclick="window.location.href='{{@app.context}}'">&nbsp;&nbsp;&nbsp;&nbsp;Exit&nbsp;&nbsp;&nbsp;&nbsp;</button>
</div> </div>
</div> </div>
<!-- /content --> <!-- /content -->

@ -66,9 +66,7 @@ $(document).ready(function () {
var changePasswordFormData = {}; var changePasswordFormData = {};
changePasswordFormData["oldPassword"] = unescape((currentPassword)); changePasswordFormData["oldPassword"] = unescape((currentPassword));
changePasswordFormData["newPassword"] = unescape((newPassword)); changePasswordFormData["newPassword"] = unescape((newPassword));
var changePasswordAPI = "/api/device-mgt/v1.0/users/credentials";
var changePasswordAPI = "/api/device-mgt/v1.0/users/" + user + "/credentials";
invokerUtil.put( invokerUtil.put(
changePasswordAPI, changePasswordAPI,
changePasswordFormData, changePasswordFormData,

@ -46,7 +46,7 @@
</li> </li>
<div id="change-password-window" class="hide"> <div id="change-password-window" class="hide">
<input type="hidden" id="user" value="{{username}}"> <input type="hidden" id="user" value="{{@user.username}}">
<div class="modal-header"> <div class="modal-header">
<h4 class="pull-left modal-title"> <h4 class="pull-left modal-title">
<span class="fw-stack"> <span class="fw-stack">

@ -16,10 +16,6 @@
* under the License. * under the License.
*/ */
.wr-content {
padding-left: 33px;
padding-right: 33px;
}
.wr-input-control .helper { .wr-input-control .helper {
font-weight: 100; font-weight: 100;

@ -167,7 +167,7 @@ pre {
position: absolute; position: absolute;
right: 0; right: 0;
height: 10000px; height: 10000px;
width: 60px; width: 20px;
} }
body.inverse .fade-edge:after { body.inverse .fade-edge:after {
@ -181,7 +181,7 @@ body.inverse .fade-edge:after {
position: absolute; position: absolute;
right: 0; right: 0;
height: 10000px; height: 10000px;
width: 60px; width: 20px;
} }
.visible-block { .visible-block {
@ -4552,6 +4552,15 @@ a.wr-side-panel-toggle-btn.selected {
background: #f4f4f4; background: #f4f4f4;
} }
.wr-advance-operations .wr-hidden-operations-nav a.selected span span > i{
color: #526A84;
}
.wr-advance-operations .wr-hidden-operations-nav a.selected span span > i.fw.fw-circle.fw-stack-2x{
color: #fff;
}
.wr-advance-operations .wr-hidden-operations-nav a.selected span span > i.fw.fw-circle.fw-stack-2x.fw-stroke.fw-inverse{
color: #526A84;
}
.wr-advance-operations .wr-hidden-operations-nav a.selected, .wr-hidden-operations .wr-hidden-operations-nav a.selected:hover { .wr-advance-operations .wr-hidden-operations-nav a.selected, .wr-hidden-operations .wr-hidden-operations-nav a.selected:hover {
color: #ffffff; color: #ffffff;
background: #526A84; background: #526A84;
@ -5515,7 +5524,7 @@ ul.listing li.grouped-input ul.grouped-child-input.disabled {
position: absolute; position: absolute;
right: 0; right: 0;
height: 10000px; height: 10000px;
width: 60px; width: 20px;
} }
body.inverse .fade-edge:after { body.inverse .fade-edge:after {
content: ""; content: "";
@ -5528,7 +5537,7 @@ body.inverse .fade-edge:after {
position: absolute; position: absolute;
right: 0; right: 0;
height: 10000px; height: 10000px;
width: 60px; width: 20px;
} }
/* ======================================================================== /* ========================================================================
@ -5752,7 +5761,7 @@ body.inverse .fade-edge:after {
position: absolute; position: absolute;
right: 0; right: 0;
height: 10000px; height: 10000px;
width: 60px; width: 20px;
} }
.table.table-selectable > tbody > tr:hover { .table.table-selectable > tbody > tr:hover {
cursor: pointer; cursor: pointer;
@ -6495,3 +6504,6 @@ select > option:hover {
/*background:url('http://cdn-sg1.pgimgs.com/images/pg/close-button.png') no-repeat center center;*/ /*background:url('http://cdn-sg1.pgimgs.com/images/pg/close-button.png') no-repeat center center;*/
} }
.label-bold{
font-weight:400;
}

@ -19,6 +19,9 @@
<a href="{{#defineZone "productUri"}}{{@app.context}}/{{/defineZone}}"> <a href="{{#defineZone "productUri"}}{{@app.context}}/{{/defineZone}}">
<img src="{{@unit.publicUri}}/img/logo.png" alt="{{defineZone "productName"}}" <img src="{{@unit.publicUri}}/img/logo.png" alt="{{defineZone "productName"}}"
title="{{defineZone "productName"}}" class="logo" /> title="{{defineZone "productName"}}" class="logo" />
<h1>{{#defineZone "productName"}}Unified UI Template App{{/defineZone}}</h1> <h1>
<span class="hidden-xs">{{#defineZone "productName"}}Unified UI Template App{{/defineZone}}</span>
<span class="visible-xs-inline">{{#defineZone "productNameResponsive"}}UUI Tmpl. App{{/defineZone}}</span>
</h1>
</a> </a>
{{/zone}} {{/zone}}

@ -27,12 +27,7 @@
{{@user.username}}<span class="caret"></span> {{@user.username}}<span class="caret"></span>
</span> </span>
</a> </a>
<ul class="dropdown-menu dropdown-menu-right float-remove-xs position-static-xs text-center-xs remove-margin-xs slideInDown" <ul class="dropdown-menu dropdown-menu-right slideInDown" role="menu">
role="menu">
<li class="dropdown-header visible-xs">
{{@user.username}}<span class="caret"></span>
</li>
<li class="divider visible-xs"></li>
{{#defineZone "userMenu-items"}} {{#defineZone "userMenu-items"}}
<li> <li>
<a href="{{@app.context}}/signout">Sign Out</a> <a href="{{@app.context}}/signout">Sign Out</a>

@ -18,10 +18,10 @@
{{#zone "header"}} {{#zone "header"}}
<header class="header header-default"> <header class="header header-default">
<div class="container-fluid"> <div class="container-fluid">
<div class="pull-left brand float-remove-xs text-center-xs"> <div class="pull-left brand">
{{defineZone "brand"}} {{defineZone "brand"}}
</div> </div>
<div class="pull-right auth float-remove-xs text-center-xs"> <div class="pull-right auth">
{{defineZone "userMenu"}} {{defineZone "userMenu"}}
</div> </div>
</div> </div>

@ -2791,6 +2791,7 @@ header .brand {
} }
header .brand img.logo { header .brand img.logo {
height: 24px; height: 24px;
margin-top:0px;
} }
header .brand a { header .brand a {
display: inline-block; display: inline-block;
@ -2822,6 +2823,9 @@ header .nav .open > a:focus {
} }
header .nav .dropdown-menu { header .nav .dropdown-menu {
background: black; background: black;
padding:0px;
margin:0px;
top:50px;
} }
header .nav .dropdown-menu a { header .nav .dropdown-menu a {
color: #fff; color: #fff;
@ -2954,7 +2958,7 @@ tbody.collapse.in {
} }
.dropdown-menu > li > a { .dropdown-menu > li > a {
display: block; display: block;
padding: 3px 20px; padding: 8px 20px;
clear: both; clear: both;
font-weight: normal; font-weight: normal;
line-height: 1.42857; line-height: 1.42857;
@ -3050,6 +3054,12 @@ tbody.collapse.in {
right: auto; right: auto;
} }
} }
@media (max-width : 480px) {
.navbar-right .dropdown-menu-right {
left: auto;
right: 0;
}
}
.btn-group, .btn-group,
.btn-group-vertical { .btn-group-vertical {
position: relative; position: relative;

Loading…
Cancel
Save