Merge branch 'master' of https://gitlab.com/entgra/carbon-device-mgt into application-mgt-new

feature/appm-store/pbac
Charitha Goonetilleke 5 years ago
commit 4e9628dff4

@ -27,6 +27,8 @@ import org.wso2.carbon.apimgt.application.extension.api.util.RegistrationProfile
import org.wso2.carbon.apimgt.application.extension.constants.ApiApplicationConstants; import org.wso2.carbon.apimgt.application.extension.constants.ApiApplicationConstants;
import org.wso2.carbon.apimgt.application.extension.dto.ApiApplicationKey; import org.wso2.carbon.apimgt.application.extension.dto.ApiApplicationKey;
import org.wso2.carbon.apimgt.application.extension.exception.APIManagerException; import org.wso2.carbon.apimgt.application.extension.exception.APIManagerException;
import org.wso2.carbon.apimgt.integration.client.OAuthRequestInterceptor;
import org.wso2.carbon.apimgt.integration.client.store.StoreClient;
import org.wso2.carbon.base.MultitenantConstants; import org.wso2.carbon.base.MultitenantConstants;
import org.wso2.carbon.context.PrivilegedCarbonContext; import org.wso2.carbon.context.PrivilegedCarbonContext;
import org.wso2.carbon.device.mgt.common.exceptions.DeviceManagementException; import org.wso2.carbon.device.mgt.common.exceptions.DeviceManagementException;
@ -94,9 +96,8 @@ public class ApiApplicationRegistrationServiceImpl implements ApiApplicationRegi
return Response.status(Response.Status.NOT_ACCEPTABLE).entity("APIs(Tags) are not allowed to this user." return Response.status(Response.Status.NOT_ACCEPTABLE).entity("APIs(Tags) are not allowed to this user."
).build(); ).build();
} }
PrivilegedCarbonContext.getThreadLocalCarbonContext().setUsername(PrivilegedCarbonContext.
getThreadLocalCarbonContext().getUserRealm().getRealmConfiguration().getAdminUserName());
String username = APIUtil.getAuthenticatedUser(); String username = APIUtil.getAuthenticatedUser();
APIManagementProviderService apiManagementProviderService = APIUtil.getAPIManagementProviderService(); APIManagementProviderService apiManagementProviderService = APIUtil.getAPIManagementProviderService();
String validityPeriod; String validityPeriod;
if (registrationProfile.getValidityPeriod() == null) { if (registrationProfile.getValidityPeriod() == null) {
@ -106,6 +107,22 @@ public class ApiApplicationRegistrationServiceImpl implements ApiApplicationRegi
} }
String applicationName = registrationProfile.getApplicationName(); String applicationName = registrationProfile.getApplicationName();
if (username.equals(registrationProfile.getUsername())) {
synchronized (ApiApplicationRegistrationServiceImpl.class) {
StoreClient storeClient = new StoreClient(new OAuthRequestInterceptor(registrationProfile.getUsername(),
registrationProfile.getPassword()));
ApiApplicationKey apiApplicationKey = apiManagementProviderService.generateAndRetrieveApplicationKeys(
applicationName, registrationProfile.getTags(),
ApiApplicationConstants.DEFAULT_TOKEN_TYPE, username,
registrationProfile.isAllowedToAllDomains(), validityPeriod, storeClient);
return Response.status(Response.Status.CREATED).entity(apiApplicationKey.toString()).build();
}
}
PrivilegedCarbonContext.getThreadLocalCarbonContext().setUsername(PrivilegedCarbonContext.
getThreadLocalCarbonContext().getUserRealm().getRealmConfiguration().getAdminUserName());
synchronized (ApiApplicationRegistrationServiceImpl.class) { synchronized (ApiApplicationRegistrationServiceImpl.class) {
ApiApplicationKey apiApplicationKey = apiManagementProviderService.generateAndRetrieveApplicationKeys( ApiApplicationKey apiApplicationKey = apiManagementProviderService.generateAndRetrieveApplicationKeys(
applicationName, registrationProfile.getTags(), applicationName, registrationProfile.getTags(),

@ -32,6 +32,10 @@ import javax.xml.bind.annotation.XmlRootElement;
public class RegistrationProfile { public class RegistrationProfile {
@XmlElement(required = true) @XmlElement(required = true)
private String applicationName; private String applicationName;
@XmlElement
private String username;
@XmlElement
private String password;
@XmlElement(required = true) @XmlElement(required = true)
private String tags[]; private String tags[];
@XmlElement(required = true) @XmlElement(required = true)
@ -70,4 +74,20 @@ public class RegistrationProfile {
public void setValidityPeriod(String validityPeriod) { public void setValidityPeriod(String validityPeriod) {
this.validityPeriod = validityPeriod; this.validityPeriod = validityPeriod;
} }
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
} }

@ -20,6 +20,7 @@ package org.wso2.carbon.apimgt.application.extension;
import org.wso2.carbon.apimgt.application.extension.dto.ApiApplicationKey; import org.wso2.carbon.apimgt.application.extension.dto.ApiApplicationKey;
import org.wso2.carbon.apimgt.application.extension.exception.APIManagerException; import org.wso2.carbon.apimgt.application.extension.exception.APIManagerException;
import org.wso2.carbon.apimgt.integration.client.store.StoreClient;
/** /**
* This comprise on operation that is been done with api manager from CDMF. This service needs to be implemented in APIM. * This comprise on operation that is been done with api manager from CDMF. This service needs to be implemented in APIM.
@ -49,6 +50,28 @@ public interface APIManagementProviderService {
String keyType, String username, boolean isAllowedAllDomains, String keyType, String username, boolean isAllowedAllDomains,
String validityTime) throws APIManagerException; String validityTime) throws APIManagerException;
/**
* Generate and retreive application keys. if the application does exist then
* create it and subscribe to apis that are grouped with the tags.
*
* @param apiApplicationName name of the application.
* @param tags tags of the apis that application needs to be subscribed.
* @param keyType of the application.
* @param username to whom the application is created
* @param isAllowedAllDomains application is allowed to all the tenants
* @param validityTime validity period of the application
* @param storeClient Specified store client
* @return consumerkey and secrete of the created application.
* @throws APIManagerException
*/
ApiApplicationKey generateAndRetrieveApplicationKeys(String apiApplicationName,
String tags[],
String keyType,
String username,
boolean isAllowedAllDomains,
String validityTime,
StoreClient storeClient) throws APIManagerException;
/** /**
* Remove APIM Application. * Remove APIM Application.
*/ */

@ -94,11 +94,18 @@ public class APIManagementProviderServiceImpl implements APIManagementProviderSe
@Override @Override
public synchronized ApiApplicationKey generateAndRetrieveApplicationKeys(String applicationName, String tags[], public synchronized ApiApplicationKey generateAndRetrieveApplicationKeys(String applicationName, String tags[],
String keyType, String username, String keyType, String username,
boolean isAllowedAllDomains, String validityTime) boolean isAllowedAllDomains, String validityTime,
throws APIManagerException { StoreClient sClient) throws APIManagerException {
StoreClient storeClient =
APIApplicationManagerExtensionDataHolder.getInstance().getIntegrationClientService() StoreClient storeClient;
if (sClient == null) {
storeClient = APIApplicationManagerExtensionDataHolder.getInstance().getIntegrationClientService()
.getStoreClient(); .getStoreClient();
} else {
storeClient = sClient;
}
String tenantDomain = PrivilegedCarbonContext.getThreadLocalCarbonContext() String tenantDomain = PrivilegedCarbonContext.getThreadLocalCarbonContext()
.getTenantDomain(); .getTenantDomain();
try { try {
@ -211,4 +218,16 @@ public class APIManagementProviderServiceImpl implements APIManagementProviderSe
} }
} }
/**
* {@inheritDoc}
*/
@Override
public synchronized ApiApplicationKey generateAndRetrieveApplicationKeys(String applicationName, String tags[],
String keyType, String username,
boolean isAllowedAllDomains,
String validityTime)
throws APIManagerException {
return this.generateAndRetrieveApplicationKeys(applicationName, tags, keyType, username,
isAllowedAllDomains, validityTime, null);
}
} }

@ -36,6 +36,12 @@ public class IntegrationClientServiceImpl implements IntegrationClientService {
publisherClient = new PublisherClient(oAuthRequestInterceptor); publisherClient = new PublisherClient(oAuthRequestInterceptor);
} }
public IntegrationClientServiceImpl(OAuthRequestInterceptor oAuthRequestInterceptor) {
this.oAuthRequestInterceptor = oAuthRequestInterceptor;
storeClient = new StoreClient(oAuthRequestInterceptor);
publisherClient = new PublisherClient(oAuthRequestInterceptor);
}
public static IntegrationClientServiceImpl getInstance() { public static IntegrationClientServiceImpl getInstance() {
if (instance == null) { if (instance == null) {
synchronized (IntegrationClientService.class) { synchronized (IntegrationClientService.class) {

@ -56,7 +56,7 @@ public class OAuthRequestInterceptor implements RequestInterceptor {
private static final String APIM_SUBSCRIBE_SCOPE = "apim:subscribe"; private static final String APIM_SUBSCRIBE_SCOPE = "apim:subscribe";
private static final long DEFAULT_REFRESH_TIME_OFFSET_IN_MILLIS = 100000; private static final long DEFAULT_REFRESH_TIME_OFFSET_IN_MILLIS = 100000;
private DCRClient dcrClient; private DCRClient dcrClient;
private static OAuthApplication oAuthApplication; private OAuthApplication oAuthApplication;
private static Map<String, AccessTokenInfo> tenantUserTokenMap = new ConcurrentHashMap<>(); private static Map<String, AccessTokenInfo> tenantUserTokenMap = new ConcurrentHashMap<>();
private static final Log log = LogFactory.getLog(OAuthRequestInterceptor.class); private static final Log log = LogFactory.getLog(OAuthRequestInterceptor.class);
@ -67,8 +67,15 @@ public class OAuthRequestInterceptor implements RequestInterceptor {
String username = APIMConfigReader.getInstance().getConfig().getUsername(); String username = APIMConfigReader.getInstance().getConfig().getUsername();
String password = APIMConfigReader.getInstance().getConfig().getPassword(); String password = APIMConfigReader.getInstance().getConfig().getPassword();
dcrClient = Feign.builder().client(new OkHttpClient(Utils.getSSLClient())).logger(new Slf4jLogger()) dcrClient = Feign.builder().client(new OkHttpClient(Utils.getSSLClient())).logger(new Slf4jLogger())
.logLevel(Logger.Level.FULL).requestInterceptor(new BasicAuthRequestInterceptor(username, .logLevel(Logger.Level.FULL).requestInterceptor(new BasicAuthRequestInterceptor(username, password))
password)) .contract(new JAXRSContract()).encoder(new GsonEncoder()).decoder(new GsonDecoder())
.target(DCRClient.class, Utils.replaceProperties(
APIMConfigReader.getInstance().getConfig().getDcrEndpoint()));
}
public OAuthRequestInterceptor(String username, String password) {
dcrClient = Feign.builder().client(new OkHttpClient(Utils.getSSLClient())).logger(new Slf4jLogger())
.logLevel(Logger.Level.FULL).requestInterceptor(new BasicAuthRequestInterceptor(username, password))
.contract(new JAXRSContract()).encoder(new GsonEncoder()).decoder(new GsonDecoder()) .contract(new JAXRSContract()).encoder(new GsonEncoder()).decoder(new GsonDecoder())
.target(DCRClient.class, Utils.replaceProperties( .target(DCRClient.class, Utils.replaceProperties(
APIMConfigReader.getInstance().getConfig().getDcrEndpoint())); APIMConfigReader.getInstance().getConfig().getDcrEndpoint()));
@ -82,7 +89,11 @@ public class OAuthRequestInterceptor implements RequestInterceptor {
clientProfile.setClientName(APPLICATION_NAME); clientProfile.setClientName(APPLICATION_NAME);
clientProfile.setCallbackUrl(""); clientProfile.setCallbackUrl("");
clientProfile.setGrantType(GRANT_TYPES); clientProfile.setGrantType(GRANT_TYPES);
clientProfile.setOwner(APIMConfigReader.getInstance().getConfig().getUsername()); String username = PrivilegedCarbonContext.getThreadLocalCarbonContext().getUsername();
if (username == null || username.isEmpty()) {
username = APIMConfigReader.getInstance().getConfig().getUsername();
}
clientProfile.setOwner(username);
clientProfile.setSaasApp(true); clientProfile.setSaasApp(true);
oAuthApplication = dcrClient.register(clientProfile); oAuthApplication = dcrClient.register(clientProfile);
} }
@ -100,8 +111,7 @@ public class OAuthRequestInterceptor implements RequestInterceptor {
JWTClient jwtClient = APIIntegrationClientDataHolder.getInstance().getJwtClientManagerService() JWTClient jwtClient = APIIntegrationClientDataHolder.getInstance().getJwtClientManagerService()
.getJWTClient(); .getJWTClient();
tenantBasedAccessTokenInfo = jwtClient.getAccessToken(oAuthApplication.getClientId(), tenantBasedAccessTokenInfo = jwtClient.getAccessToken(oAuthApplication.getClientId(),
oAuthApplication.getClientSecret(), username, oAuthApplication.getClientSecret(), username, REQUIRED_SCOPE);
REQUIRED_SCOPE);
tenantBasedAccessTokenInfo.setExpiresIn( tenantBasedAccessTokenInfo.setExpiresIn(
System.currentTimeMillis() + (tenantBasedAccessTokenInfo.getExpiresIn() * 1000)); System.currentTimeMillis() + (tenantBasedAccessTokenInfo.getExpiresIn() * 1000));
if (tenantBasedAccessTokenInfo.getScopes() == null) { if (tenantBasedAccessTokenInfo.getScopes() == null) {

@ -54,7 +54,7 @@ public class APIPublisherServiceTest extends BaseAPIPublisherTest {
@BeforeTest @BeforeTest
public void initialConfigs() throws Exception { public void initialConfigs() throws Exception {
initializeOAuthApplication(); //initializeOAuthApplication();
WebappPublisherConfig.init(); WebappPublisherConfig.init();
} }

@ -115,6 +115,7 @@ public class UserManagementServiceImpl implements UserManagementService {
private static final Log log = LogFactory.getLog(UserManagementServiceImpl.class); private static final Log log = LogFactory.getLog(UserManagementServiceImpl.class);
private static final String DEFAULT_DEVICE_USER = "Internal/devicemgt-user"; private static final String DEFAULT_DEVICE_USER = "Internal/devicemgt-user";
private static final String DEFAULT_SUBSCRIBER = "Internal/subscriber";
// Permissions that are given for a normal device user. // Permissions that are given for a normal device user.
private static final Permission[] PERMISSIONS_FOR_DEVICE_USER = { private static final Permission[] PERMISSIONS_FOR_DEVICE_USER = {
@ -158,9 +159,31 @@ public class UserManagementServiceImpl implements UserManagementService {
List<String> tmpRoles = new ArrayList<>(); List<String> tmpRoles = new ArrayList<>();
String[] userInfoRoles = userInfo.getRoles(); String[] userInfoRoles = userInfo.getRoles();
tmpRoles.add(DEFAULT_DEVICE_USER); tmpRoles.add(DEFAULT_DEVICE_USER);
boolean subscriberFound = false;
if (userInfoRoles != null) { if (userInfoRoles != null) {
//check if subscriber role is coming in the payload
for (String r : userInfoRoles) {
if (DEFAULT_SUBSCRIBER.equals(r)) {
subscriberFound = true;
break;
}
}
tmpRoles.addAll(Arrays.asList(userInfoRoles)); tmpRoles.addAll(Arrays.asList(userInfoRoles));
} }
if (!subscriberFound) {
// Add Internal/subscriber role to new users
if (userStoreManager.isExistingRole(DEFAULT_SUBSCRIBER)) {
tmpRoles.add(DEFAULT_SUBSCRIBER);
} else {
log.warn("User: " + userInfo.getUsername() + " will not be able to enroll devices as '" +
DEFAULT_SUBSCRIBER + "' is missing in the system");
}
}
String[] roles = new String[tmpRoles.size()]; String[] roles = new String[tmpRoles.size()];
tmpRoles.toArray(roles); tmpRoles.toArray(roles);

@ -40,8 +40,12 @@ public class GroupManagementAdminServiceImpl implements GroupManagementAdminServ
try { try {
RequestValidationUtil.validatePaginationParameters(offset, limit); RequestValidationUtil.validatePaginationParameters(offset, limit);
GroupPaginationRequest request = new GroupPaginationRequest(offset, limit); GroupPaginationRequest request = new GroupPaginationRequest(offset, limit);
if (name != null){
request.setGroupName(name.toUpperCase()); request.setGroupName(name.toUpperCase());
}
if (owner != null) {
request.setOwner(owner.toUpperCase()); request.setOwner(owner.toUpperCase());
}
PaginationResult deviceGroupsResult = DeviceMgtAPIUtils.getGroupManagementProviderService() PaginationResult deviceGroupsResult = DeviceMgtAPIUtils.getGroupManagementProviderService()
.getGroups(request); .getGroups(request);
DeviceGroupList deviceGroupList = new DeviceGroupList(); DeviceGroupList deviceGroupList = new DeviceGroupList();

@ -98,14 +98,15 @@
<div class="row"> <div class="row">
<div class="dontfloat feature-wrapper" name ="deviceFeature"> <div class="dontfloat feature-wrapper" name ="deviceFeature">
<div class="col-xs-3"> <div class="col-xs-3">
<input type="text" class="form-control" id="feature-name" placeholder="name" value="{{this.name}}"/> <input type="text" class="form-control feature-name" placeholder="name" value="{{this.name}}"/>
</div> </div>
<div class="col-xs-4"> <div class="col-xs-4">
<input type="text" class="form-control" id="feature-code" placeholder="code" value="{{this.code}}"/> <input type="text" class="form-control feature-code" placeholder="code" value="{{this.code}}"/>
</div> </div>
<div class="col-xs-4"> <div class="col-xs-4">
<textarea aria-describedby="basic-addon1" type="text" id="feature-description" <textarea aria-describedby="basic-addon1" type="text"
placeholder="description" data-error-msg="invalid feature description" class="form-control" rows="1" cols="30">{{this.description}}</textarea> placeholder="description" data-error-msg="invalid feature description"
class="form-control feature-description" rows="1" cols="30">{{this.description}}</textarea>
</div> </div>
<button type="button" class="wr-btn wr-btn-horizontal remove_feature_button"><i class="fa fa-minus"></i></button> <button type="button" class="wr-btn wr-btn-horizontal remove_feature_button"><i class="fa fa-minus"></i></button>
</div> </div>
@ -115,16 +116,16 @@
<div class="row"> <div class="row">
<div class="dontfloat feature-wrapper" name="deviceFeature"> <div class="dontfloat feature-wrapper" name="deviceFeature">
<div class="col-xs-3"> <div class="col-xs-3">
<input type="text" class="form-control" id="feature-name" placeholder="name"/> <input type="text" class="form-control feature-name" placeholder="name"/>
</div> </div>
<div class="col-xs-4"> <div class="col-xs-4">
<input type="text" class="form-control" id="feature-code" placeholder="code"/> <input type="text" class="form-control feature-code" placeholder="code"/>
</div> </div>
<div class="col-xs-4"> <div class="col-xs-4">
<textarea aria-describedby="basic-addon1" type="text" id="feature-description" <textarea aria-describedby="basic-addon1" type="text"
placeholder="description" placeholder="description"
data-error-msg="invalid feature description" data-error-msg="invalid feature description"
class="form-control" rows="1" cols="30"></textarea> class="form-control feature-description" rows="1" cols="30"></textarea>
</div> </div>
<button type="button" class="wr-btn wr-btn-horizontal add_feature_button"><i class="fa fa-plus"></i></button> <button type="button" class="wr-btn wr-btn-horizontal add_feature_button"><i class="fa fa-plus"></i></button>
</div> </div>
@ -221,7 +222,7 @@
</div> </div>
<br> <br>
<button id="add-devicetype-btn" class="wr-btn">Update</button> <button id="edit-devicetype-btn" class="wr-btn">Update</button>
<div id="devicetype-create-success-msg" class="alert hidden" role="alert"> <div id="devicetype-create-success-msg" class="alert hidden" role="alert">
<i class="icon fw fw-success"></i><span></span> <i class="icon fw fw-success"></i><span></span>
</div> </div>

@ -123,27 +123,28 @@ $(document).ready(function () {
var addFeatureButton = $('.add_feature_button'); //Add button selector var addFeatureButton = $('.add_feature_button'); //Add button selector
var featureWrapper = $('.feature_field_wrapper'); //Input field wrapper var featureWrapper = $('.feature_field_wrapper'); //Input field wrapper
$(addFeatureButton).click(function(){ //Once add button is clicked $(addFeatureButton).click(function(){ //Once add button is clicked
var featureFieldHtml = '<div class="row"><div class="dontfloat feature-wrapper" name ="deviceFeature"> <div class="col-xs-3"> <input type="text"' + var featureFieldHtml = '<div class="row"><div class="dontfloat feature-wrapper" name ="deviceFeature"> ' +
' class="form-control" id="feature-name" placeholder="name"/> </div> <div class="col-xs-4"> ' + '<div class="col-xs-3"> <input type="text"' +
'<input type="text" class="form-control" id="feature-code" placeholder="code"/> </div> ' + ' class="form-control feature-name" placeholder="name"/> </div> <div class="col-xs-4"> ' +
'<input type="text" class="form-control feature-code" placeholder="code"/> </div> ' +
'<div class="col-xs-4"> <textarea aria-describedby="basic-addon1" type="text" ' + '<div class="col-xs-4"> <textarea aria-describedby="basic-addon1" type="text" ' +
'id="feature-description" placeholder="description"data-error-msg="invalid ' + 'class="feature-description" placeholder="description"data-error-msg="invalid ' +
'feature description"class="form-control" rows="1" cols="30"></textarea> </div> ' + 'feature description" class="form-control" rows="1" cols="30"></textarea> </div> ' +
'<button type="button" class="wr-btn wr-btn-horizontal wr-btn-secondary remove_feature_button"><i class="fa fa-minus"></i></button> </div></div>' '<button type="button" class="wr-btn wr-btn-horizontal wr-btn-secondary remove_feature_button">' +
'<i class="fa fa-minus"></i></button> </div></div>';
$(featureWrapper).append(featureFieldHtml); // Add field html $(featureWrapper).append(featureFieldHtml); // Add field html
}); });
$(featureWrapper).on('click', '.remove_feature_button', function(e){ //Once remove button is clicked $(featureWrapper).on('click', '.remove_feature_button', function(e){ //Once remove button is clicked
e.preventDefault(); e.preventDefault();
$(this).parent('div').remove(); //Remove field html $(this).parent('div').remove(); //Remove field html
op--; //Decrement field counter
}); });
/** /**
* Following click function would execute * Following click function would execute
* when a user clicks on "Add Device type" button. * when a user clicks on "Add Device type" button.
*/ */
$("button#add-devicetype-btn").click(function () { $("button#edit-devicetype-btn").click(function () {
var errorMsgWrapper = "#devicetype-create-error-msg"; var errorMsgWrapper = "#devicetype-create-error-msg";
var errorMsg = "#devicetype-create-error-msg span"; var errorMsg = "#devicetype-create-error-msg span";
@ -155,13 +156,19 @@ $(document).ready(function () {
if (!deviceTypeName || deviceTypeName.trim() == "" ) { if (!deviceTypeName || deviceTypeName.trim() == "" ) {
$(errorMsg).text("Device Type Name Cannot be empty."); $(errorMsg).text("Device Type Name Cannot be empty.");
$(errorMsgWrapper).removeClass("hidden"); $(errorMsgWrapper).removeClass("hidden");
$([document.documentElement, document.body]).animate({
scrollTop: $(".page-sub-title").offset().top
}, 500);
return; return;
} }
if (!deviceTypeDescription || deviceTypeDescription.trim() == "" ) { if (!deviceTypeDescription || deviceTypeDescription.trim() == "") {
$(errorMsg).text("Device Type Description Cannot be empty."); $(errorMsg).text("Device Type Description Cannot be empty.");
$(errorMsgWrapper).removeClass("hidden"); $(errorMsgWrapper).removeClass("hidden");
return $([document.documentElement, document.body]).animate({
scrollTop: $(".page-sub-title").offset().top
}, 500);
return;
} }
deviceType.name = deviceTypeName.trim(); deviceType.name = deviceTypeName.trim();
@ -197,17 +204,29 @@ $(document).ready(function () {
} }
var features = []; var features = [];
var featureCodesValidation = true;
var regexp = /^[a-zA-Z0-9-_]+$/;
$('div[name^="deviceFeature"]').each(function() { $('div[name^="deviceFeature"]').each(function() {
var featureName = $(this).find("#feature-name").val(); var featureName = $(this).find(".feature-name").val();
var featureCode = $(this).find("#feature-code").val(); var featureCode = $(this).find(".feature-code").val();
var featureDescription = $(this).find(".feature-description").val();
if (featureName && featureName.trim() != "" && featureCode && featureCode.trim() != "") { if (featureName && featureName.trim() != "" && featureCode && featureCode.trim() != "") {
featureCodesValidation = featureCodesValidation && (featureCode.search(regexp) != -1);
var feature = {}; var feature = {};
feature.name = featureName.trim(); feature.name = featureName.trim();
feature.code = featureCode.trim(); feature.code = featureCode.trim();
feature.description = $("#feature-description").val(); feature.description = featureDescription;
features.push(feature); features.push(feature);
} }
}); });
if (!featureCodesValidation) {
$(errorMsg).text("Device Type feature code can only contain alphanumeric, underscore and dash characters.");
$(errorMsgWrapper).removeClass("hidden");
$([document.documentElement, document.body]).animate({
scrollTop: $(".page-sub-title").offset().top
}, 500);
return;
}
deviceType.deviceTypeMetaDefinition.features = features; deviceType.deviceTypeMetaDefinition.features = features;
var addRoleAPI = apiBasePath + "/admin/device-types/" + deviceType.name; var addRoleAPI = apiBasePath + "/admin/device-types/" + deviceType.name;
@ -217,6 +236,7 @@ $(document).ready(function () {
deviceType, deviceType,
function (data, textStatus, jqXHR) { function (data, textStatus, jqXHR) {
if (jqXHR.status == 200) { if (jqXHR.status == 200) {
$(errorMsgIdentifier).addClass(" hidden");
$("#modalDevice").modal('show'); $("#modalDevice").modal('show');
} }
}, },

@ -40,4 +40,5 @@
{{#zone "content"}} {{#zone "content"}}
{{unit "cdmf.unit.device.operation-mod"}} {{unit "cdmf.unit.device.operation-mod"}}
{{unit "cdmf.unit.effective-policy.view"}} {{unit "cdmf.unit.effective-policy.view"}}
{{unit "cdmf.unit.lib.data-table"}}
{{/zone}} {{/zone}}

@ -77,24 +77,25 @@ var displayPolicy = function (policyPayloadObj) {
'.policy-view/css/' + deviceType + '-policy-view.css'; '.policy-view/css/' + deviceType + '-policy-view.css';
var policyOperationsTemplateCacheKey = deviceType + '-policy-operations'; var policyOperationsTemplateCacheKey = deviceType + '-policy-operations';
$.isResourceExists(policyOperationsTemplateSrc, function (status) { if (policyOperationsTemplateSrc) {
$.template(policyOperationsTemplateCacheKey, policyOperationsTemplateSrc, function (template) { if (policyOperationsScriptSrc) {
var content = template();
$("#device-type-policy-operations").html(content).removeClass("hidden");
$(".policy-platform").addClass("hidden");
$.isResourceExists(policyOperationsScriptSrc, function (status) {
var script = document.createElement('script'); var script = document.createElement('script');
script.type = 'text/javascript'; script.type = 'text/javascript';
script.src = policyOperationsScriptSrc; script.src = policyOperationsScriptSrc;
$(".wr-advance-operations").prepend(script); $(".wr-advance-operations").prepend(script);
}
$.template(policyOperationsTemplateCacheKey, policyOperationsTemplateSrc, function (template) {
var content = template();
$("#device-type-policy-operations").html(content).removeClass("hidden");
$(".policy-platform").addClass("hidden");
if (policyOperationsScriptSrc) {
/* /*
This method should be implemented in the relevant plugin side and should include the logic to This method should be implemented in the relevant plugin side and should include the logic to
populate the policy profile in the plugin specific UI. populate the policy profile in the plugin specific UI.
*/ */
polulateProfileOperations(policyPayloadObj["profile"]["profileFeaturesList"]); polulateProfileOperations(policyPayloadObj["profile"]["profileFeaturesList"]);
}
}); });
});
$.isResourceExists(policyOperationsStylesSrc, function (status) { $.isResourceExists(policyOperationsStylesSrc, function (status) {
var style = document.createElement('link'); var style = document.createElement('link');
style.type = 'text/css'; style.type = 'text/css';
@ -104,7 +105,7 @@ var displayPolicy = function (policyPayloadObj) {
}); });
$(".wr-advance-operations-init").addClass("hidden"); $(".wr-advance-operations-init").addClass("hidden");
}); }
}; };
/** /**

Loading…
Cancel
Save