forked from community/device-mgt-plugins
Merge pull request #485 from hasuniea/windows10
adding Windows10 operation and policy supportrevert-dabc3590
commit
8b258ce24f
@ -0,0 +1,90 @@
|
||||
/*
|
||||
* 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.mobile.windows.api.operations.util;
|
||||
|
||||
import org.wso2.carbon.device.mgt.common.operation.mgt.Operation;
|
||||
import org.wso2.carbon.device.mgt.mobile.windows.api.common.PluginConstants;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class HeartBeatDeviceInfo {
|
||||
public List<Operation> getDeviceInfo() {
|
||||
|
||||
List<Operation> deviceInfoOperations = new ArrayList<>();
|
||||
|
||||
Operation osVersion = new Operation();
|
||||
osVersion.setCode(PluginConstants.SyncML.SOFTWARE_VERSION);
|
||||
deviceInfoOperations.add(osVersion);
|
||||
|
||||
Operation imsi = new Operation();
|
||||
imsi.setCode(PluginConstants.SyncML.IMSI);
|
||||
deviceInfoOperations.add(imsi);
|
||||
|
||||
Operation imei = new Operation();
|
||||
imei.setCode(PluginConstants.SyncML.IMEI);
|
||||
deviceInfoOperations.add(imei);
|
||||
|
||||
Operation deviceID = new Operation();
|
||||
deviceID.setCode(PluginConstants.SyncML.DEV_ID);
|
||||
deviceInfoOperations.add(deviceID);
|
||||
|
||||
Operation manufacturer = new Operation();
|
||||
manufacturer.setCode(PluginConstants.SyncML.MANUFACTURER);
|
||||
deviceInfoOperations.add(manufacturer);
|
||||
|
||||
Operation model = new Operation();
|
||||
model.setCode(PluginConstants.SyncML.MODEL);
|
||||
deviceInfoOperations.add(model);
|
||||
|
||||
Operation language = new Operation();
|
||||
language.setCode(PluginConstants.SyncML.LANGUAGE);
|
||||
deviceInfoOperations.add(language);
|
||||
|
||||
Operation vendor = new Operation();
|
||||
vendor.setCode(PluginConstants.SyncML.VENDOR);
|
||||
deviceInfoOperations.add(vendor);
|
||||
|
||||
Operation macaddress = new Operation();
|
||||
macaddress.setCode(PluginConstants.SyncML.MAC_ADDRESS);
|
||||
deviceInfoOperations.add(macaddress);
|
||||
|
||||
Operation resolution = new Operation();
|
||||
resolution.setCode(PluginConstants.SyncML.RESOLUTION);
|
||||
deviceInfoOperations.add(resolution);
|
||||
|
||||
Operation deviceName = new Operation();
|
||||
deviceName.setCode(PluginConstants.SyncML.DEVICE_NAME);
|
||||
deviceInfoOperations.add(deviceName);
|
||||
|
||||
Operation totalRam = new Operation();
|
||||
totalRam.setCode(PluginConstants.SyncML.TOTAL_RAM);
|
||||
deviceInfoOperations.add(totalRam);
|
||||
|
||||
Operation availableStorage = new Operation();
|
||||
availableStorage.setCode(PluginConstants.SyncML.TOTAL_STORAGE);
|
||||
deviceInfoOperations.add(availableStorage);
|
||||
|
||||
Operation remainingBattery = new Operation();
|
||||
remainingBattery.setCode(PluginConstants.SyncML.BATTERY_CHARGE_REMAINING);
|
||||
deviceInfoOperations.add(remainingBattery);
|
||||
|
||||
return deviceInfoOperations;
|
||||
}
|
||||
}
|
@ -0,0 +1,122 @@
|
||||
/*
|
||||
* 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.mobile.windows.api.services;
|
||||
|
||||
|
||||
import io.swagger.annotations.*;
|
||||
import org.w3c.dom.Document;
|
||||
import org.wso2.carbon.device.mgt.common.notification.mgt.NotificationManagementException;
|
||||
import org.wso2.carbon.device.mgt.mobile.windows.api.common.PluginConstants;
|
||||
import org.wso2.carbon.device.mgt.mobile.windows.api.common.exceptions.WindowsConfigurationException;
|
||||
import org.wso2.carbon.device.mgt.mobile.windows.api.common.exceptions.WindowsDeviceEnrolmentException;
|
||||
import org.wso2.carbon.device.mgt.mobile.windows.api.operations.WindowsOperationException;
|
||||
|
||||
import javax.ws.rs.Consumes;
|
||||
import javax.ws.rs.POST;
|
||||
import javax.ws.rs.Path;
|
||||
import javax.ws.rs.Produces;
|
||||
import javax.ws.rs.core.MediaType;
|
||||
import javax.ws.rs.core.Response;
|
||||
|
||||
|
||||
/**
|
||||
* Interface for Syncml message flow.
|
||||
*/
|
||||
@SwaggerDefinition(
|
||||
info = @Info(
|
||||
version = "1.0.0",
|
||||
title = "",
|
||||
extensions = {
|
||||
@Extension(properties = {
|
||||
@ExtensionProperty(name = "name", value = "Syncml Endpoint"),
|
||||
@ExtensionProperty(name = "context",
|
||||
value = "/api/device-mgt/windows/v1.0/syncmlmgt"),
|
||||
})
|
||||
}
|
||||
),
|
||||
tags = {
|
||||
@Tag(name = "devicemgt_windows", description = "")
|
||||
}
|
||||
)
|
||||
@Api(value = "Windows syncml service to initialize management session",
|
||||
description = "This carries all the resources related to Windows syncml message flow.")
|
||||
@Path("/devicemgt")
|
||||
public interface DeviceManagementService {
|
||||
@Path("/pending-operations")
|
||||
@POST
|
||||
@Consumes({PluginConstants.SYNCML_MEDIA_TYPE, MediaType.APPLICATION_XML})
|
||||
@Produces(PluginConstants.SYNCML_MEDIA_TYPE)
|
||||
@ApiOperation(
|
||||
httpMethod = "POST",
|
||||
value = "Getting pending operations for Windows device.",
|
||||
notes = "Using this API to fetching more information to enroll the Device and " +
|
||||
"getting pending operations.",
|
||||
tags = "Windows Device Management Administrative Service",
|
||||
authorizations = {
|
||||
@Authorization(
|
||||
value = "permission",
|
||||
scopes = {@AuthorizationScope(
|
||||
scope = "/device-mgt/devices/enroll/windows",
|
||||
description = "Getting pending operations and " +
|
||||
"device information to enroll the device")}
|
||||
)
|
||||
}
|
||||
)
|
||||
@ApiResponses(value = {
|
||||
@ApiResponse(
|
||||
code = 201,
|
||||
message = "Ok. \n Successfully getting pending operations.",
|
||||
responseHeaders = {
|
||||
@ResponseHeader(
|
||||
name = "Content-Location",
|
||||
description = "URL of the activity instance that refers to the scheduled operation."),
|
||||
@ResponseHeader(
|
||||
name = "Content-Type",
|
||||
description = "Content type of the body"),
|
||||
@ResponseHeader(
|
||||
name = "ETag",
|
||||
description = "Entity Tag of the response resource.\n" +
|
||||
"Used by caches, or in conditional requests."),
|
||||
@ResponseHeader(
|
||||
name = "Last-Modified",
|
||||
description = "Date and time the resource was last modified. \n" +
|
||||
"Used by caches, or in conditional requests.")}),
|
||||
@ApiResponse(
|
||||
code = 303,
|
||||
message = "See Other. \n The source can be retrieved from the URL specified in the location header.",
|
||||
responseHeaders = {
|
||||
@ResponseHeader(
|
||||
name = "Content-Location",
|
||||
description = "The Source URL of the document.")}),
|
||||
@ApiResponse(
|
||||
code = 400,
|
||||
message = "Bad Request. \n Invalid request or validation error."),
|
||||
@ApiResponse(
|
||||
code = 415,
|
||||
message = "Unsupported media type. \n The format of the requested entity was not supported.\n"),
|
||||
@ApiResponse(
|
||||
code = 500,
|
||||
message = "Internal Server Error. \n " +
|
||||
"Server error occurred while getting pending operations.")
|
||||
})
|
||||
Response getResponse(Document request) throws WindowsDeviceEnrolmentException, WindowsOperationException,
|
||||
NotificationManagementException, WindowsConfigurationException;
|
||||
|
||||
}
|
||||
|
@ -0,0 +1,61 @@
|
||||
/*
|
||||
* 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.mobile.windows.api.services.enrollment;
|
||||
|
||||
import org.wso2.carbon.device.mgt.mobile.windows.api.common.PluginConstants;
|
||||
import org.wso2.carbon.device.mgt.mobile.windows.api.common.exceptions.WAPProvisioningException;
|
||||
import org.wso2.carbon.device.mgt.mobile.windows.api.common.exceptions.WindowsDeviceEnrolmentException;
|
||||
import org.wso2.carbon.device.mgt.mobile.windows.api.services.enrollment.beans.AdditionalContext;
|
||||
import org.wso2.carbon.device.mgt.mobile.windows.api.services.enrollment.beans.RequestSecurityTokenResponse;
|
||||
|
||||
import javax.jws.WebMethod;
|
||||
import javax.jws.WebParam;
|
||||
import javax.jws.WebService;
|
||||
import javax.xml.ws.BindingType;
|
||||
import javax.xml.ws.RequestWrapper;
|
||||
import javax.xml.ws.ResponseWrapper;
|
||||
import javax.xml.ws.soap.SOAPBinding;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
|
||||
@WebService(targetNamespace = PluginConstants.DEVICE_ENROLLMENT_SERVICE_TARGET_NAMESPACE, name = "enrollment")
|
||||
@BindingType(value = SOAPBinding.SOAP12HTTP_BINDING)
|
||||
public interface EnrollmentService {
|
||||
|
||||
@RequestWrapper(localName = "RequestSecurityToken", targetNamespace = PluginConstants
|
||||
.WS_TRUST_TARGET_NAMESPACE)
|
||||
@WebMethod(operationName = "RequestSecurityToken")
|
||||
@ResponseWrapper(localName = "RequestSecurityTokenResponseCollection", targetNamespace =
|
||||
PluginConstants.WS_TRUST_TARGET_NAMESPACE)
|
||||
void requestSecurityToken(
|
||||
@WebParam(name = "TokenType", targetNamespace = PluginConstants.WS_TRUST_TARGET_NAMESPACE)
|
||||
String tokenType,
|
||||
@WebParam(name = "RequestType", targetNamespace = PluginConstants.WS_TRUST_TARGET_NAMESPACE)
|
||||
String requestType,
|
||||
@WebParam(name = "BinarySecurityToken", targetNamespace = PluginConstants
|
||||
.WS_SECURITY_TARGET_NAMESPACE)
|
||||
String binarySecurityToken,
|
||||
@WebParam(name = "AdditionalContext", targetNamespace = PluginConstants
|
||||
.SOAP_AUTHORIZATION_TARGET_NAMESPACE)
|
||||
AdditionalContext additionalContext,
|
||||
@WebParam(mode = WebParam.Mode.OUT, name = "RequestSecurityTokenResponse",
|
||||
targetNamespace = PluginConstants.WS_TRUST_TARGET_NAMESPACE)
|
||||
javax.xml.ws.Holder<RequestSecurityTokenResponse> response) throws
|
||||
WindowsDeviceEnrolmentException, UnsupportedEncodingException,
|
||||
WAPProvisioningException;
|
||||
}
|
@ -0,0 +1,48 @@
|
||||
/*
|
||||
* 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.mobile.windows.api.services.enrollment.beans;
|
||||
|
||||
import org.wso2.carbon.device.mgt.mobile.windows.api.common.PluginConstants;
|
||||
|
||||
import javax.xml.bind.annotation.XmlAccessType;
|
||||
import javax.xml.bind.annotation.XmlAccessorType;
|
||||
import javax.xml.bind.annotation.XmlElement;
|
||||
import javax.xml.bind.annotation.XmlType;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@XmlAccessorType(XmlAccessType.FIELD)
|
||||
@XmlType(name = "OIDCollection", namespace = PluginConstants.SOAP_AUTHORIZATION_TARGET_NAMESPACE,
|
||||
propOrder = {"contextitem"})
|
||||
@SuppressWarnings("unused")
|
||||
public class AdditionalContext {
|
||||
|
||||
@XmlElement(name = "ContextItem", required = true,
|
||||
namespace = PluginConstants.SOAP_AUTHORIZATION_TARGET_NAMESPACE)
|
||||
|
||||
protected List<ContextItem> contextitem;
|
||||
|
||||
public List<ContextItem> getcontextitem() {
|
||||
if (contextitem == null) {
|
||||
contextitem = new ArrayList<ContextItem>();
|
||||
}
|
||||
return this.contextitem;
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,63 @@
|
||||
/*
|
||||
* 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.mobile.windows.api.services.enrollment.beans;
|
||||
|
||||
import org.wso2.carbon.device.mgt.mobile.windows.api.common.PluginConstants;
|
||||
|
||||
import javax.xml.bind.annotation.*;
|
||||
|
||||
@XmlAccessorType(XmlAccessType.FIELD)
|
||||
@XmlType(name = "BinarySecurityToken", namespace = PluginConstants.WS_SECURITY_TARGET_NAMESPACE,
|
||||
propOrder = {"ValueType", "EncodingType"})
|
||||
@SuppressWarnings("unused")
|
||||
public class BinarySecurityToken {
|
||||
|
||||
@XmlAttribute(name = "ValueType")
|
||||
protected String ValueType;
|
||||
@XmlAttribute(name = "EncodingType")
|
||||
protected String EncodingType;
|
||||
@XmlValue
|
||||
protected String Token;
|
||||
|
||||
public void setValueType(String valuetype) {
|
||||
this.ValueType = valuetype;
|
||||
}
|
||||
|
||||
public String getValueType() {
|
||||
return this.ValueType;
|
||||
}
|
||||
|
||||
public void setEncodingType(String encodingtype) {
|
||||
this.EncodingType = encodingtype;
|
||||
}
|
||||
|
||||
public String getEncodingType() {
|
||||
return this.EncodingType;
|
||||
}
|
||||
|
||||
public void setToken(String token) {
|
||||
this.Token = token;
|
||||
}
|
||||
|
||||
public String getToken() {
|
||||
return this.Token;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -0,0 +1,54 @@
|
||||
/*
|
||||
* 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.mobile.windows.api.services.enrollment.beans;
|
||||
|
||||
import org.wso2.carbon.device.mgt.mobile.windows.api.common.PluginConstants;
|
||||
|
||||
import javax.xml.bind.annotation.XmlAccessType;
|
||||
import javax.xml.bind.annotation.XmlAccessorType;
|
||||
import javax.xml.bind.annotation.XmlElement;
|
||||
import javax.xml.bind.annotation.XmlType;
|
||||
|
||||
@XmlAccessorType(XmlAccessType.FIELD)
|
||||
@XmlType(name = "ContextItem", namespace = PluginConstants.SOAP_AUTHORIZATION_TARGET_NAMESPACE,
|
||||
propOrder = {"Name" , "Value"})
|
||||
public class ContextItem {
|
||||
|
||||
@XmlElement(required = true, namespace = PluginConstants.SOAP_AUTHORIZATION_TARGET_NAMESPACE)
|
||||
protected String Name;
|
||||
@XmlElement(required = true, namespace = PluginConstants.SOAP_AUTHORIZATION_TARGET_NAMESPACE)
|
||||
protected String Value;
|
||||
|
||||
public String getValue() {
|
||||
return Value;
|
||||
}
|
||||
|
||||
public void setValue(String value) {
|
||||
Value = value;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return Name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
Name = name;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,42 @@
|
||||
/*
|
||||
* 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.mobile.windows.api.services.enrollment.beans;
|
||||
|
||||
import org.wso2.carbon.device.mgt.mobile.windows.api.common.PluginConstants;
|
||||
|
||||
import javax.xml.bind.annotation.XmlAccessType;
|
||||
import javax.xml.bind.annotation.XmlAccessorType;
|
||||
import javax.xml.bind.annotation.XmlElement;
|
||||
import javax.xml.bind.annotation.XmlType;
|
||||
|
||||
@XmlAccessorType(XmlAccessType.FIELD)
|
||||
@XmlType(name = "RequestedSecurityToken", namespace = PluginConstants.WS_TRUST_TARGET_NAMESPACE,
|
||||
propOrder = {"binarySecurityToken"})
|
||||
@SuppressWarnings("unused")
|
||||
public class RequestSecurityToken {
|
||||
|
||||
@XmlElement(name = "BinarySecurityToken", required = true,
|
||||
namespace = PluginConstants.WS_SECURITY_TARGET_NAMESPACE)
|
||||
|
||||
protected BinarySecurityToken binarySecurityToken;
|
||||
|
||||
public void setBinarySecurityToken(BinarySecurityToken binarysecuritytoken) {
|
||||
this.binarySecurityToken = binarysecuritytoken;
|
||||
}
|
||||
}
|
@ -0,0 +1,82 @@
|
||||
/*
|
||||
* 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.mobile.windows.api.services.enrollment.beans;
|
||||
|
||||
import org.wso2.carbon.device.mgt.mobile.windows.api.common.PluginConstants;
|
||||
|
||||
import javax.xml.bind.annotation.XmlAccessType;
|
||||
import javax.xml.bind.annotation.XmlAccessorType;
|
||||
import javax.xml.bind.annotation.XmlElement;
|
||||
import javax.xml.bind.annotation.XmlType;
|
||||
import java.io.Serializable;
|
||||
|
||||
@XmlAccessorType(XmlAccessType.FIELD)
|
||||
@XmlType(name = "RequestSecurityTokenResponse", namespace = PluginConstants.WS_TRUST_TARGET_NAMESPACE,
|
||||
propOrder = {"TokenType", "DispositionMessage", "RequestedSecurityToken", "RequestID"})
|
||||
@SuppressWarnings("unused")
|
||||
public class RequestSecurityTokenResponse implements Serializable {
|
||||
|
||||
@XmlElement(name = "TokenType", namespace = PluginConstants.WS_TRUST_TARGET_NAMESPACE)
|
||||
private String TokenType;
|
||||
|
||||
// Windows 10 property
|
||||
@XmlElement(name = "DispositionMessage", namespace = PluginConstants.ENROLLMENT_POLICY_TARGET_NAMESPACE)
|
||||
private String DispositionMessage;
|
||||
|
||||
@XmlElement(name = "RequestedSecurityToken", required = true,
|
||||
namespace = PluginConstants.WS_TRUST_TARGET_NAMESPACE)
|
||||
private org.wso2.carbon.device.mgt.mobile.windows.api.services.enrollment.beans.RequestedSecurityToken RequestedSecurityToken;
|
||||
|
||||
@XmlElement(name = "RequestID", namespace = PluginConstants.ENROLLMENT_POLICY_TARGET_NAMESPACE)
|
||||
private int RequestID;
|
||||
|
||||
public String getTokenType() {
|
||||
return TokenType;
|
||||
}
|
||||
|
||||
public void setTokenType(String tokenType) {
|
||||
TokenType = tokenType;
|
||||
}
|
||||
|
||||
public org.wso2.carbon.device.mgt.mobile.windows.api.services.enrollment.beans.RequestedSecurityToken getRequestedSecurityToken() {
|
||||
return RequestedSecurityToken;
|
||||
}
|
||||
|
||||
public void setRequestedSecurityToken(org.wso2.carbon.device.mgt.mobile.windows.api.services.enrollment.beans.RequestedSecurityToken
|
||||
requestedSecurityToken) {
|
||||
RequestedSecurityToken = requestedSecurityToken;
|
||||
}
|
||||
|
||||
public int getRequestID() {
|
||||
return RequestID;
|
||||
}
|
||||
|
||||
public void setRequestID(int requestID) {
|
||||
RequestID = requestID;
|
||||
}
|
||||
|
||||
public String getDispositionMessage() {
|
||||
return DispositionMessage;
|
||||
}
|
||||
|
||||
public void setDispositionMessage(String dispositionMessage) {
|
||||
DispositionMessage = dispositionMessage;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,42 @@
|
||||
/*
|
||||
* 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.mobile.windows.api.services.enrollment.beans;
|
||||
|
||||
import org.wso2.carbon.device.mgt.mobile.windows.api.common.PluginConstants;
|
||||
|
||||
import javax.xml.bind.annotation.XmlAccessType;
|
||||
import javax.xml.bind.annotation.XmlAccessorType;
|
||||
import javax.xml.bind.annotation.XmlElement;
|
||||
import javax.xml.bind.annotation.XmlType;
|
||||
|
||||
@XmlAccessorType(XmlAccessType.FIELD)
|
||||
@XmlType(name = "RequestedSecurityToken", namespace = PluginConstants.WS_TRUST_TARGET_NAMESPACE,
|
||||
propOrder = {"binarySecurityToken"})
|
||||
public class RequestedSecurityToken {
|
||||
|
||||
@XmlElement(name = "BinarySecurityToken", required = true,
|
||||
namespace = PluginConstants.WS_SECURITY_TARGET_NAMESPACE)
|
||||
|
||||
protected BinarySecurityToken binarySecurityToken;
|
||||
|
||||
public void setBinarySecurityToken(BinarySecurityToken binarysecuritytoken) {
|
||||
this.binarySecurityToken = binarysecuritytoken;
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,27 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
@XmlSchema(namespace = "http://www.w3.org/2003/05/soap-envelope",
|
||||
xmlns = {
|
||||
@XmlNs(prefix = "", namespaceURI = "http://www.w3.org/2003/05/soap-envelope")
|
||||
}, elementFormDefault = javax.xml.bind.annotation.XmlNsForm.QUALIFIED)
|
||||
|
||||
package org.wso2.carbon.device.mgt.mobile.windows.api.services.enrollment.beans;
|
||||
|
||||
import javax.xml.bind.annotation.XmlNs;
|
||||
import javax.xml.bind.annotation.XmlSchema;
|
@ -0,0 +1,433 @@
|
||||
/*
|
||||
* 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.mobile.windows.api.services.enrollment.impl;
|
||||
|
||||
import org.apache.commons.codec.binary.Base64;
|
||||
import org.apache.commons.codec.digest.DigestUtils;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.apache.cxf.headers.Header;
|
||||
import org.apache.cxf.helpers.CastUtils;
|
||||
import org.apache.cxf.jaxws.context.WrappedMessageContext;
|
||||
import org.apache.cxf.message.Message;
|
||||
import org.w3c.dom.*;
|
||||
import org.wso2.carbon.certificate.mgt.core.exception.KeystoreException;
|
||||
import org.wso2.carbon.certificate.mgt.core.service.CertificateManagementServiceImpl;
|
||||
import org.wso2.carbon.context.PrivilegedCarbonContext;
|
||||
import org.wso2.carbon.device.mgt.common.*;
|
||||
import org.wso2.carbon.device.mgt.common.configuration.mgt.ConfigurationEntry;
|
||||
import org.wso2.carbon.device.mgt.mobile.windows.api.common.PluginConstants;
|
||||
import org.wso2.carbon.device.mgt.mobile.windows.api.common.beans.CacheEntry;
|
||||
import org.wso2.carbon.device.mgt.mobile.windows.api.common.exceptions.CertificateGenerationException;
|
||||
import org.wso2.carbon.device.mgt.mobile.windows.api.common.exceptions.SyncmlMessageFormatException;
|
||||
import org.wso2.carbon.device.mgt.mobile.windows.api.common.exceptions.WAPProvisioningException;
|
||||
import org.wso2.carbon.device.mgt.mobile.windows.api.common.exceptions.WindowsDeviceEnrolmentException;
|
||||
import org.wso2.carbon.device.mgt.mobile.windows.api.common.util.DeviceUtil;
|
||||
import org.wso2.carbon.device.mgt.mobile.windows.api.common.util.WindowsAPIUtils;
|
||||
import org.wso2.carbon.device.mgt.mobile.windows.api.operations.util.SyncmlCredentialUtil;
|
||||
import org.wso2.carbon.device.mgt.mobile.windows.api.services.enrollment.EnrollmentService;
|
||||
import org.wso2.carbon.device.mgt.mobile.windows.api.services.enrollment.beans.*;
|
||||
import org.wso2.carbon.device.mgt.mobile.windows.api.services.syncml.beans.WindowsDevice;
|
||||
import org.wso2.carbon.policy.mgt.common.PolicyManagementException;
|
||||
import org.wso2.carbon.policy.mgt.core.PolicyManagerService;
|
||||
import org.xml.sax.SAXException;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.jws.WebService;
|
||||
import javax.servlet.ServletContext;
|
||||
import javax.xml.parsers.DocumentBuilder;
|
||||
import javax.xml.parsers.DocumentBuilderFactory;
|
||||
import javax.xml.parsers.ParserConfigurationException;
|
||||
import javax.xml.transform.Transformer;
|
||||
import javax.xml.transform.TransformerException;
|
||||
import javax.xml.transform.TransformerFactory;
|
||||
import javax.xml.transform.dom.DOMSource;
|
||||
import javax.xml.transform.stream.StreamResult;
|
||||
import javax.xml.ws.BindingType;
|
||||
import javax.xml.ws.Holder;
|
||||
import javax.xml.ws.WebServiceContext;
|
||||
import javax.xml.ws.handler.MessageContext;
|
||||
import javax.xml.ws.soap.Addressing;
|
||||
import javax.xml.ws.soap.SOAPBinding;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.StringWriter;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.security.cert.CertificateEncodingException;
|
||||
import java.security.cert.X509Certificate;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
|
||||
/**
|
||||
* Implementation class of Windows10 Enrollment process.
|
||||
*/
|
||||
@WebService(endpointInterface = PluginConstants.ENROLLMENT_SERVICE_ENDPOINT,
|
||||
targetNamespace = PluginConstants.DEVICE_ENROLLMENT_SERVICE_TARGET_NAMESPACE)
|
||||
@Addressing(enabled = true, required = true)
|
||||
@BindingType(value = SOAPBinding.SOAP12HTTP_BINDING)
|
||||
public class EnrollmentServiceImpl implements EnrollmentService {
|
||||
private static Log log = LogFactory.getLog(EnrollmentServiceImpl.class);
|
||||
private X509Certificate rootCACertificate;
|
||||
private String pollingFrequency;
|
||||
private String provisioningURL;
|
||||
private String domain;
|
||||
|
||||
@Resource
|
||||
private WebServiceContext context;
|
||||
|
||||
@Override
|
||||
public void requestSecurityToken(String tokenType, String requestType, String binarySecurityToken,
|
||||
AdditionalContext additionalContext,
|
||||
Holder<RequestSecurityTokenResponse> response)
|
||||
throws WindowsDeviceEnrolmentException, UnsupportedEncodingException, WAPProvisioningException {
|
||||
|
||||
String headerBinarySecurityToken = null;
|
||||
String headerTo = null;
|
||||
String encodedWap;
|
||||
List<Header> headers = getHeaders();
|
||||
for (Header headerElement : headers != null ? headers : null) {
|
||||
String nodeName = headerElement.getName().getLocalPart();
|
||||
if (PluginConstants.SECURITY.equals(nodeName)) {
|
||||
Element element = (Element) headerElement.getObject();
|
||||
headerBinarySecurityToken = element.getFirstChild().getFirstChild().getTextContent();
|
||||
}
|
||||
if (PluginConstants.TO.equals(nodeName)) {
|
||||
Element toElement = (Element) headerElement.getObject();
|
||||
headerTo = toElement.getFirstChild().getTextContent();
|
||||
}
|
||||
}
|
||||
try {
|
||||
enrollDevice(additionalContext, headerBinarySecurityToken);
|
||||
} catch (DeviceManagementException e) {
|
||||
throw new WindowsDeviceEnrolmentException("Error occurred while enrolling the device.");
|
||||
} catch (PolicyManagementException e) {
|
||||
throw new WindowsDeviceEnrolmentException("Error occurred while enforcing windows policies.");
|
||||
}
|
||||
String[] splitEmail = headerTo.split("(/ENROLLMENTSERVER)");
|
||||
String email = splitEmail[PluginConstants.CertificateEnrolment.EMAIL_SEGMENT];
|
||||
|
||||
String[] splitDomain = email.split("(EnterpriseEnrollment.)");
|
||||
domain = splitDomain[PluginConstants.CertificateEnrolment.DOMAIN_SEGMENT];
|
||||
provisioningURL = PluginConstants.CertificateEnrolment.ENROLL_SUBDOMAIN + domain +
|
||||
PluginConstants.CertificateEnrolment.SYNCML_PROVISIONING_WIN10_SERVICE_URL;
|
||||
|
||||
List<ConfigurationEntry> tenantConfigurations;
|
||||
try {
|
||||
if ((tenantConfigurations = WindowsAPIUtils.getTenantConfigurationData()) != null) {
|
||||
for (ConfigurationEntry configurationEntry : tenantConfigurations) {
|
||||
if ((PluginConstants.TenantConfigProperties.NOTIFIER_FREQUENCY.equals(
|
||||
configurationEntry.getName()))) {
|
||||
pollingFrequency = configurationEntry.getValue().toString();
|
||||
} else {
|
||||
pollingFrequency = PluginConstants.TenantConfigProperties.DEFAULT_FREQUENCY;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
pollingFrequency = PluginConstants.TenantConfigProperties.DEFAULT_FREQUENCY;
|
||||
String msg = "Tenant configurations are not initialized yet.";
|
||||
log.error(msg);
|
||||
}
|
||||
ServletContext ctx = (ServletContext) context.getMessageContext().
|
||||
get(MessageContext.SERVLET_CONTEXT);
|
||||
File wapProvisioningFile = (File) ctx.getAttribute(PluginConstants.CONTEXT_WAP_PROVISIONING_FILE);
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("Received CSR from Device:" + binarySecurityToken);
|
||||
}
|
||||
|
||||
String wapProvisioningFilePath = wapProvisioningFile.getPath();
|
||||
RequestSecurityTokenResponse requestSecurityTokenResponse = new RequestSecurityTokenResponse();
|
||||
requestSecurityTokenResponse.setTokenType(PluginConstants.CertificateEnrolment.TOKEN_TYPE);
|
||||
|
||||
encodedWap = prepareWapProvisioningXML(binarySecurityToken, wapProvisioningFilePath,
|
||||
headerBinarySecurityToken);
|
||||
RequestedSecurityToken requestedSecurityToken = new RequestedSecurityToken();
|
||||
BinarySecurityToken binarySecToken = new BinarySecurityToken();
|
||||
binarySecToken.setValueType(PluginConstants.CertificateEnrolment.VALUE_TYPE);
|
||||
binarySecToken.setEncodingType(PluginConstants.CertificateEnrolment.ENCODING_TYPE);
|
||||
binarySecToken.setToken(encodedWap);
|
||||
requestedSecurityToken.setBinarySecurityToken(binarySecToken);
|
||||
requestSecurityTokenResponse.setRequestedSecurityToken(requestedSecurityToken);
|
||||
requestSecurityTokenResponse.setRequestID(PluginConstants.CertificateEnrolment.REQUEST_ID);
|
||||
response.value = requestSecurityTokenResponse;
|
||||
} catch (CertificateGenerationException e) {
|
||||
String msg = "Problem occurred while generating certificate.";
|
||||
log.error(msg, e);
|
||||
throw new WindowsDeviceEnrolmentException(msg, e);
|
||||
} catch (WAPProvisioningException e) {
|
||||
String msg = "Problem occurred while generating wap-provisioning file.";
|
||||
log.error(msg, e);
|
||||
throw new WindowsDeviceEnrolmentException(msg, e);
|
||||
} catch (DeviceManagementException e) {
|
||||
String msg = "Error occurred while getting tenant configurations.";
|
||||
log.error(msg);
|
||||
throw new WindowsDeviceEnrolmentException(msg, e);
|
||||
} finally {
|
||||
PrivilegedCarbonContext.endTenantFlow();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Method used to Convert the Document object into a String.
|
||||
*
|
||||
* @param document - Wap provisioning XML document
|
||||
* @return - String representation of wap provisioning XML document
|
||||
* @throws TransformerException
|
||||
*/
|
||||
private String convertDocumentToString(Document document) throws TransformerException {
|
||||
DOMSource DOMSource = new DOMSource(document);
|
||||
StringWriter stringWriter = new StringWriter();
|
||||
StreamResult streamResult = new StreamResult(stringWriter);
|
||||
TransformerFactory transformerFactory = TransformerFactory.newInstance();
|
||||
Transformer transformer = transformerFactory.newTransformer();
|
||||
transformer.transform(DOMSource, streamResult);
|
||||
|
||||
return stringWriter.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* This method prepares the wap-provisioning file by including relevant certificates etc.
|
||||
*
|
||||
* @param binarySecurityToken - CSR from device
|
||||
* @param wapProvisioningFilePath - File path of wap-provisioning file
|
||||
* @return - base64 encoded final wap-provisioning file as a String
|
||||
* @throws CertificateGenerationException
|
||||
* @throws org.wso2.carbon.device.mgt.mobile.windows.api.common.exceptions.WAPProvisioningException
|
||||
*/
|
||||
private String prepareWapProvisioningXML(String binarySecurityToken, String wapProvisioningFilePath,
|
||||
String headerBst) throws CertificateGenerationException,
|
||||
WAPProvisioningException,
|
||||
WindowsDeviceEnrolmentException {
|
||||
String rootCertEncodedString;
|
||||
String signedCertEncodedString;
|
||||
X509Certificate signedCertificate;
|
||||
String provisioningXmlString;
|
||||
|
||||
CertificateManagementServiceImpl certMgtServiceImpl = CertificateManagementServiceImpl.getInstance();
|
||||
Base64 base64Encoder = new Base64();
|
||||
try {
|
||||
rootCACertificate = (X509Certificate) certMgtServiceImpl.getCACertificate();
|
||||
rootCertEncodedString = base64Encoder.encodeAsString(rootCACertificate.getEncoded());
|
||||
|
||||
|
||||
signedCertificate = certMgtServiceImpl.getSignedCertificateFromCSR(binarySecurityToken);
|
||||
signedCertEncodedString = base64Encoder.encodeAsString(signedCertificate.getEncoded());
|
||||
|
||||
DocumentBuilderFactory domFactory = DocumentBuilderFactory.newInstance();
|
||||
DocumentBuilder builder;
|
||||
|
||||
builder = domFactory.newDocumentBuilder();
|
||||
Document document = builder.parse(wapProvisioningFilePath);
|
||||
NodeList wapParm = document.getElementsByTagName(PluginConstants.CertificateEnrolment.PARM);
|
||||
Node caCertificatePosition = wapParm.item(PluginConstants.CertificateEnrolment.CA_CERTIFICATE_POSITION);
|
||||
|
||||
//Adding SHA1 CA certificate finger print to wap-provisioning xml.
|
||||
caCertificatePosition.getParentNode().getAttributes().getNamedItem(PluginConstants.
|
||||
CertificateEnrolment.TYPE).setTextContent(String.valueOf(
|
||||
DigestUtils.sha1Hex(rootCACertificate.getEncoded())).toUpperCase());
|
||||
//Adding encoded CA certificate to wap-provisioning file after removing new line
|
||||
// characters.
|
||||
NamedNodeMap rootCertAttributes = caCertificatePosition.getAttributes();
|
||||
Node rootCertNode =
|
||||
rootCertAttributes.getNamedItem(PluginConstants.CertificateEnrolment.VALUE);
|
||||
rootCertEncodedString = rootCertEncodedString.replaceAll("\n", "");
|
||||
rootCertNode.setTextContent(rootCertEncodedString);
|
||||
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("Root certificate: " + rootCertEncodedString);
|
||||
}
|
||||
|
||||
Node signedCertificatePosition = wapParm.item(PluginConstants.CertificateEnrolment.
|
||||
SIGNED_CERTIFICATE_POSITION);
|
||||
|
||||
//Adding SHA1 signed certificate finger print to wap-provisioning xml.
|
||||
signedCertificatePosition.getParentNode().getAttributes().getNamedItem(PluginConstants.
|
||||
CertificateEnrolment.TYPE).setTextContent(String.valueOf(
|
||||
DigestUtils.sha1Hex(signedCertificate.getEncoded())).toUpperCase());
|
||||
|
||||
//Adding encoded signed certificate to wap-provisioning file after removing new line
|
||||
// characters.
|
||||
NamedNodeMap clientCertAttributes = signedCertificatePosition.getAttributes();
|
||||
Node clientEncodedNode =
|
||||
clientCertAttributes.getNamedItem(PluginConstants.CertificateEnrolment.VALUE);
|
||||
signedCertEncodedString = signedCertEncodedString.replaceAll("\n", "");
|
||||
|
||||
clientEncodedNode.setTextContent(signedCertEncodedString);
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("Signed certificate: " + signedCertEncodedString);
|
||||
}
|
||||
|
||||
//Adding domainName to wap-provisioning xml.
|
||||
Node domainPosition = wapParm.item(PluginConstants.CertificateEnrolment.DOMAIN_POSITION);
|
||||
NamedNodeMap domainAttribute = domainPosition.getAttributes();
|
||||
Node domainNode = domainAttribute.getNamedItem(PluginConstants.CertificateEnrolment.VALUE);
|
||||
domainNode.setTextContent(domain);
|
||||
|
||||
//Adding Next provisioning service URL to wap-provisioning xml.
|
||||
Node syncmlServicePosition = wapParm.item(PluginConstants.CertificateEnrolment.
|
||||
SYNCML_PROVISIONING_ADDR_POSITION);
|
||||
NamedNodeMap syncmlServiceAttribute = syncmlServicePosition.getAttributes();
|
||||
Node syncmlServiceNode = syncmlServiceAttribute.getNamedItem(PluginConstants.CertificateEnrolment.VALUE);
|
||||
syncmlServiceNode.setTextContent(provisioningURL);
|
||||
|
||||
// Adding user name auth token to wap-provisioning xml.
|
||||
Node userNameAuthPosition = wapParm.item(PluginConstants.CertificateEnrolment.APPAUTH_USERNAME_POSITION);
|
||||
NamedNodeMap appServerAttribute = userNameAuthPosition.getAttributes();
|
||||
Node authNameNode = appServerAttribute.getNamedItem(PluginConstants.CertificateEnrolment.VALUE);
|
||||
String userName = getRequestedUser(headerBst);
|
||||
//CacheEntry cacheEntry = (CacheEntry) DeviceUtil.getCacheEntry(headerBst);
|
||||
// String userName = cacheEntry.getUsername();
|
||||
authNameNode.setTextContent(userName);
|
||||
DeviceUtil.removeToken(headerBst);
|
||||
String password = DeviceUtil.generateRandomToken();
|
||||
Node passwordAuthPosition = wapParm.item(PluginConstants.CertificateEnrolment.APPAUTH_PASSWORD_POSITION);
|
||||
NamedNodeMap appSrvPasswordAttribute = passwordAuthPosition.getAttributes();
|
||||
Node authPasswordNode = appSrvPasswordAttribute.getNamedItem(PluginConstants.CertificateEnrolment.VALUE);
|
||||
authPasswordNode.setTextContent(password);
|
||||
String requestSecurityTokenResponse = SyncmlCredentialUtil.generateRST(userName, password);
|
||||
DeviceUtil.persistChallengeToken(requestSecurityTokenResponse, null, userName);
|
||||
|
||||
// Get device polling frequency from the tenant Configurations.
|
||||
Node numberOfFirstRetries = wapParm.item(PluginConstants.CertificateEnrolment.POLLING_FREQUENCY_POSITION);
|
||||
NamedNodeMap pollingAttributes = numberOfFirstRetries.getAttributes();
|
||||
Node pollValue = pollingAttributes.getNamedItem(PluginConstants.CertificateEnrolment.VALUE);
|
||||
pollValue.setTextContent(pollingFrequency);
|
||||
provisioningXmlString = convertDocumentToString(document);
|
||||
|
||||
} catch (ParserConfigurationException e) {
|
||||
throw new WAPProvisioningException("Problem occurred while creating configuration request", e);
|
||||
} catch (CertificateEncodingException e) {
|
||||
throw new WindowsDeviceEnrolmentException("Error occurred while encoding certificates.", e);
|
||||
} catch (SAXException e) {
|
||||
throw new WAPProvisioningException("Error occurred while parsing wap-provisioning.xml file.", e);
|
||||
} catch (TransformerException e) {
|
||||
throw new WAPProvisioningException("Error occurred while transforming wap-provisioning.xml file.", e);
|
||||
} catch (IOException e) {
|
||||
throw new WAPProvisioningException("Error occurred while getting wap-provisioning.xml file.", e);
|
||||
} catch (SyncmlMessageFormatException e) {
|
||||
throw new WindowsDeviceEnrolmentException("Error occurred while generating password hash value.", e);
|
||||
} catch (KeystoreException e) {
|
||||
throw new CertificateGenerationException("CA certificate cannot be generated.", e);
|
||||
}
|
||||
return base64Encoder.encodeAsString(provisioningXmlString.getBytes());
|
||||
}
|
||||
|
||||
/**
|
||||
* This method get the soap request header contents.
|
||||
*
|
||||
* @return List of SOAP headers.
|
||||
*/
|
||||
private List<Header> getHeaders() {
|
||||
MessageContext messageContext = context.getMessageContext();
|
||||
if (messageContext == null || !(messageContext instanceof WrappedMessageContext)) {
|
||||
return null;
|
||||
}
|
||||
Message message = ((WrappedMessageContext) messageContext).getWrappedMessage();
|
||||
return CastUtils.cast((List<?>) message.get(Header.HEADER_LIST));
|
||||
}
|
||||
|
||||
/**
|
||||
* This method to getting RSTR requested user from the Cache.
|
||||
*
|
||||
* @param bst Binary Security token which has given from BST Endpoint.
|
||||
* @return User for given token.
|
||||
*/
|
||||
private String getRequestedUser(String bst) {
|
||||
CacheEntry cacheEntry = (CacheEntry) DeviceUtil.getCacheEntry(bst);
|
||||
String userName = cacheEntry.getUsername();
|
||||
return userName;
|
||||
}
|
||||
|
||||
/**
|
||||
* This Method to generate windows device.
|
||||
*
|
||||
* @param windowsDevice Requested Device with properties.
|
||||
* @return Value added Device.
|
||||
*/
|
||||
private Device generateDevice(WindowsDevice windowsDevice) {
|
||||
|
||||
Device generatedDevice = new Device();
|
||||
|
||||
Device.Property OSVersionProperty = new Device.Property();
|
||||
OSVersionProperty.setName(PluginConstants.SyncML.OS_VERSION);
|
||||
OSVersionProperty.setValue(windowsDevice.getOsVersion());
|
||||
|
||||
Device.Property IMSEIProperty = new Device.Property();
|
||||
IMSEIProperty.setName(PluginConstants.SyncML.IMSI);
|
||||
IMSEIProperty.setValue(windowsDevice.getImsi());
|
||||
|
||||
Device.Property IMEIProperty = new Device.Property();
|
||||
IMEIProperty.setName(PluginConstants.SyncML.IMEI);
|
||||
IMEIProperty.setValue(windowsDevice.getImei());
|
||||
|
||||
List<Device.Property> propertyList = new ArrayList<>();
|
||||
propertyList.add(OSVersionProperty);
|
||||
propertyList.add(IMSEIProperty);
|
||||
propertyList.add(IMEIProperty);
|
||||
|
||||
EnrolmentInfo enrolmentInfo = new EnrolmentInfo();
|
||||
enrolmentInfo.setOwner(windowsDevice.getUser());
|
||||
enrolmentInfo.setOwnership(EnrolmentInfo.OwnerShip.BYOD);
|
||||
enrolmentInfo.setStatus(EnrolmentInfo.Status.ACTIVE);
|
||||
|
||||
generatedDevice.setEnrolmentInfo(enrolmentInfo);
|
||||
generatedDevice.setDeviceIdentifier(windowsDevice.getDeviceId());
|
||||
generatedDevice.setProperties(propertyList);
|
||||
generatedDevice.setType(windowsDevice.getDeviceType());
|
||||
generatedDevice.setName(windowsDevice.getDeviceName());
|
||||
|
||||
return generatedDevice;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method to enroll windows10 Device.
|
||||
*
|
||||
* @param requestContextItems Context values to enroll the device.
|
||||
* @param headerBinarySecurityToken SOAP request header value to identify the user.
|
||||
* @throws DeviceManagementException Exception occurs while enrolling the Device.
|
||||
* @throws PolicyManagementException Exception occurs while getting effective policies.
|
||||
*/
|
||||
private void enrollDevice(AdditionalContext requestContextItems, String headerBinarySecurityToken)
|
||||
throws DeviceManagementException, PolicyManagementException {
|
||||
WindowsDevice windowsDevice = new WindowsDevice();
|
||||
windowsDevice.setDeviceType(DeviceManagementConstants.MobileDeviceTypes.
|
||||
MOBILE_DEVICE_TYPE_WINDOWS);
|
||||
windowsDevice.setUser(getRequestedUser(headerBinarySecurityToken));
|
||||
List<ContextItem> contextItems = requestContextItems.getcontextitem();
|
||||
for (int x = 0; x < contextItems.size(); x++) {
|
||||
switch (x) {
|
||||
case PluginConstants.WindowsEnrollmentProperties.WIN_DEVICE_NAME:
|
||||
windowsDevice.setDeviceName(contextItems.get(x).getValue());
|
||||
case PluginConstants.WindowsEnrollmentProperties.WIN_DEVICE_IMEI:
|
||||
windowsDevice.setImei(contextItems.get(x).getValue());
|
||||
case PluginConstants.WindowsEnrollmentProperties.WIN_DEVICE_ID:
|
||||
windowsDevice.setDeviceId(contextItems.get(x).getValue());
|
||||
case PluginConstants.WindowsEnrollmentProperties.WIN_DEVICE_VERSION:
|
||||
windowsDevice.setOsVersion(contextItems.get(x).getValue());
|
||||
}
|
||||
}
|
||||
Device device = generateDevice(windowsDevice);
|
||||
WindowsAPIUtils.getDeviceManagementService().enrollDevice(device);
|
||||
PolicyManagerService policyManagerService = WindowsAPIUtils.getPolicyManagerService();
|
||||
policyManagerService.getEffectivePolicy(new DeviceIdentifier(windowsDevice.getDeviceId(), device.getType()));
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,141 @@
|
||||
/*
|
||||
* 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.mobile.windows.api.services.enrollment.util;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.bouncycastle.asn1.x509.*;
|
||||
import org.bouncycastle.cert.CertIOException;
|
||||
import org.bouncycastle.cert.X509v3CertificateBuilder;
|
||||
import org.bouncycastle.cert.jcajce.JcaX509CertificateConverter;
|
||||
import org.bouncycastle.cert.jcajce.JcaX509v3CertificateBuilder;
|
||||
import org.bouncycastle.operator.ContentSigner;
|
||||
import org.bouncycastle.operator.OperatorCreationException;
|
||||
import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder;
|
||||
import org.bouncycastle.pkcs.jcajce.JcaPKCS10CertificationRequest;
|
||||
import org.wso2.carbon.device.mgt.mobile.windows.api.common.PluginConstants;
|
||||
import org.wso2.carbon.device.mgt.mobile.windows.api.common.exceptions.CertificateGenerationException;
|
||||
import org.wso2.carbon.device.mgt.mobile.windows.api.common.exceptions.WAPProvisioningException;
|
||||
|
||||
import javax.security.auth.x500.X500Principal;
|
||||
import java.math.BigInteger;
|
||||
import java.security.InvalidKeyException;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.PrivateKey;
|
||||
import java.security.SecureRandom;
|
||||
import java.security.cert.CertificateException;
|
||||
import java.security.cert.X509Certificate;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Class for generating signed certificate for CSR form device.
|
||||
*/
|
||||
public class CertificateSigningService {
|
||||
|
||||
private static final long MILLI_SECONDS = 1000L * 60 * 60 * 24;
|
||||
|
||||
private enum PropertyIndex {
|
||||
COMMON_NAME_INDEX(0),
|
||||
NOT_BEFORE_DAYS_INDEX(1),
|
||||
NOT_AFTER_DAYS_INDEX(2);
|
||||
|
||||
private final int itemPosition;
|
||||
private PropertyIndex(final int itemPosition) {
|
||||
this.itemPosition = itemPosition;
|
||||
}
|
||||
public int getValue() {
|
||||
return this.itemPosition;
|
||||
}
|
||||
}
|
||||
|
||||
private static Log log = LogFactory.getLog(
|
||||
CertificateSigningService.class);
|
||||
|
||||
/**
|
||||
* Implement certificate signing task using CSR received from the device and the MDM server key
|
||||
* store.
|
||||
* @param jcaRequest - CSR from the device
|
||||
* @param privateKey - Private key of CA certificate in MDM server
|
||||
* @param caCert - CA certificate in MDM server
|
||||
* @param certParameterList - Parameter list for Signed certificate generation
|
||||
* @return - Signed certificate for CSR from device
|
||||
* @throws CertificateGenerationException
|
||||
* @throws WAPProvisioningException
|
||||
*/
|
||||
public static X509Certificate signCSR(JcaPKCS10CertificationRequest jcaRequest,
|
||||
PrivateKey privateKey, X509Certificate caCert,
|
||||
List certParameterList) throws
|
||||
CertificateGenerationException,
|
||||
WAPProvisioningException {
|
||||
|
||||
String commonName =
|
||||
(String) certParameterList.get(PropertyIndex.COMMON_NAME_INDEX.getValue());
|
||||
int notBeforeDays =
|
||||
(Integer) certParameterList.get(PropertyIndex.NOT_BEFORE_DAYS_INDEX.getValue());
|
||||
int notAfterDays =
|
||||
(Integer) certParameterList.get(PropertyIndex.NOT_AFTER_DAYS_INDEX.getValue());
|
||||
X509v3CertificateBuilder certificateBuilder;
|
||||
X509Certificate signedCertificate;
|
||||
|
||||
try {
|
||||
ContentSigner signer;
|
||||
BigInteger serialNumber = BigInteger.valueOf(new SecureRandom().
|
||||
nextInt(Integer.MAX_VALUE));
|
||||
Date notBeforeDate = new Date(System.currentTimeMillis() -
|
||||
(MILLI_SECONDS * notBeforeDays));
|
||||
Date notAfterDate = new Date(System.currentTimeMillis() +
|
||||
(MILLI_SECONDS * notAfterDays));
|
||||
certificateBuilder =
|
||||
new JcaX509v3CertificateBuilder(caCert, serialNumber, notBeforeDate, notAfterDate,
|
||||
new X500Principal(commonName),
|
||||
jcaRequest.getPublicKey());
|
||||
|
||||
//Adding extensions to the signed certificate.
|
||||
certificateBuilder.addExtension(Extension.keyUsage, true,
|
||||
new KeyUsage(KeyUsage.digitalSignature));
|
||||
certificateBuilder.addExtension(Extension.extendedKeyUsage, false,
|
||||
new ExtendedKeyUsage(KeyPurposeId.id_kp_clientAuth));
|
||||
certificateBuilder.addExtension(Extension.basicConstraints, true,
|
||||
new BasicConstraints(false));
|
||||
|
||||
signer = new JcaContentSignerBuilder(PluginConstants.CertificateEnrolment.ALGORITHM).
|
||||
setProvider(PluginConstants.CertificateEnrolment.PROVIDER).build(privateKey);
|
||||
|
||||
signedCertificate = new JcaX509CertificateConverter().setProvider(
|
||||
PluginConstants.CertificateEnrolment.PROVIDER).getCertificate(
|
||||
certificateBuilder.build(signer));
|
||||
} catch (InvalidKeyException e) {
|
||||
throw new CertificateGenerationException("CSR's public key is invalid", e);
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
throw new CertificateGenerationException("Certificate cannot be generated", e);
|
||||
}
|
||||
catch (CertIOException e) {
|
||||
throw new CertificateGenerationException(
|
||||
"Cannot add extension(s) to signed certificate", e);
|
||||
}
|
||||
catch (OperatorCreationException e) {
|
||||
throw new CertificateGenerationException("Content signer cannot be created", e);
|
||||
}
|
||||
catch (CertificateException e) {
|
||||
throw new CertificateGenerationException("Signed certificate cannot be generated", e);
|
||||
}
|
||||
return signedCertificate;
|
||||
}
|
||||
}
|
@ -0,0 +1,94 @@
|
||||
/*
|
||||
* 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.mobile.windows.api.services.enrollment.util;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.wso2.carbon.device.mgt.mobile.windows.api.common.PluginConstants;
|
||||
import org.wso2.carbon.device.mgt.mobile.windows.api.common.exceptions.KeyStoreGenerationException;
|
||||
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.security.KeyStore;
|
||||
import java.security.KeyStoreException;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.cert.CertificateException;
|
||||
|
||||
/**
|
||||
* Class for MDM Keystore operations.
|
||||
*/
|
||||
public class KeyStoreGenerator {
|
||||
|
||||
private static final Log log = LogFactory.getLog(
|
||||
KeyStoreGenerator.class);
|
||||
|
||||
/**
|
||||
* This method loads the MDM keystore.
|
||||
* @param keyStore - MDM Keystore
|
||||
* @param keyStorePassword - Keystore Password
|
||||
* @param keyStorePath - Keystore path
|
||||
* @throws KeyStoreGenerationException
|
||||
*/
|
||||
public static void loadToStore(KeyStore keyStore,
|
||||
char[] keyStorePassword,
|
||||
String keyStorePath) throws KeyStoreGenerationException {
|
||||
|
||||
FileInputStream fileInputStream = null;
|
||||
|
||||
try {
|
||||
if (keyStorePath != null) {
|
||||
fileInputStream = new FileInputStream(keyStorePath);
|
||||
keyStore.load(fileInputStream, keyStorePassword);
|
||||
}
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
throw new KeyStoreGenerationException(
|
||||
"Requested cryptographic algorithm is not available in the environment.", e);
|
||||
} catch (CertificateException e) {
|
||||
throw new KeyStoreGenerationException("Error working with certificate related to, " +
|
||||
keyStorePath, e);
|
||||
} catch (IOException e) {
|
||||
throw new KeyStoreGenerationException("File error while working with file, " +
|
||||
keyStorePath, e);
|
||||
} finally {
|
||||
try {
|
||||
if (fileInputStream != null) {
|
||||
fileInputStream.close();
|
||||
}
|
||||
} catch (IOException e) {
|
||||
throw new KeyStoreGenerationException("File error while closing the file, " +
|
||||
keyStorePath, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is for retrieving instance of Key Store.
|
||||
* @return Keystore object
|
||||
* @throws KeyStoreGenerationException
|
||||
*/
|
||||
public static KeyStore getKeyStore() throws KeyStoreGenerationException {
|
||||
try {
|
||||
return KeyStore.getInstance(PluginConstants.CertificateEnrolment.JKS);
|
||||
} catch (KeyStoreException e) {
|
||||
String msg = "KeyStore error while creating new JKS.";
|
||||
log.error(msg, e);
|
||||
throw new KeyStoreGenerationException(msg, e);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,200 @@
|
||||
/*
|
||||
* 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.mobile.windows.api.services.enrollment.util;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.joda.time.DateTime;
|
||||
import org.joda.time.format.ISODateTimeFormat;
|
||||
import org.wso2.carbon.device.mgt.mobile.windows.api.common.PluginConstants;
|
||||
|
||||
import javax.ws.rs.core.Response;
|
||||
import javax.xml.namespace.QName;
|
||||
import javax.xml.soap.*;
|
||||
import javax.xml.ws.handler.MessageContext;
|
||||
import javax.xml.ws.handler.soap.SOAPHandler;
|
||||
import javax.xml.ws.handler.soap.SOAPMessageContext;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* Class responsible for adding Timestamp security header in SOAP message and adding Content-length
|
||||
* in the HTTP header for avoiding HTTP chunking.
|
||||
*/
|
||||
public class MessageHandler implements SOAPHandler<SOAPMessageContext> {
|
||||
|
||||
public static final String TIME_ZONE = "Z";
|
||||
public static final int VALIDITY_TIME = 5;
|
||||
public static final int TIMESTAMP_END_INDEX = 6;
|
||||
public static final int TIMESTAMP_BEGIN_INDEX = 0;
|
||||
private static Log log = LogFactory.getLog(
|
||||
MessageHandler.class);
|
||||
|
||||
/**
|
||||
* This method resolves the security header coming in the SOAP message.
|
||||
* @return - Security Header
|
||||
*/
|
||||
@Override
|
||||
public Set<QName> getHeaders() {
|
||||
QName securityHeader = new QName(PluginConstants.WS_SECURITY_TARGET_NAMESPACE, PluginConstants.SECURITY);
|
||||
HashSet<QName> headers = new HashSet<QName>();
|
||||
headers.add(securityHeader);
|
||||
return headers;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method adds Timestamp for SOAP header, and adds Content-length for HTTP header for
|
||||
* avoiding HTTP chunking.
|
||||
*
|
||||
* @param context - Context of the SOAP Message
|
||||
*/
|
||||
@Override
|
||||
public boolean handleMessage(SOAPMessageContext context) {
|
||||
|
||||
Boolean outBoundProperty = (Boolean) context.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY);
|
||||
|
||||
if (outBoundProperty) {
|
||||
SOAPMessage message = context.getMessage();
|
||||
SOAPHeader header = null;
|
||||
SOAPEnvelope envelope = null;
|
||||
try {
|
||||
header = message.getSOAPHeader();
|
||||
envelope = message.getSOAPPart().getEnvelope();
|
||||
} catch (SOAPException e) {
|
||||
Response.serverError().entity("SOAP message content cannot be read.").build();
|
||||
}
|
||||
try {
|
||||
if ((header == null) && (envelope != null)) {
|
||||
header = envelope.addHeader();
|
||||
}
|
||||
} catch (SOAPException e) {
|
||||
Response.serverError().entity("SOAP header cannot be added.").build();
|
||||
}
|
||||
|
||||
SOAPFactory soapFactory = null;
|
||||
try {
|
||||
soapFactory = SOAPFactory.newInstance();
|
||||
} catch (SOAPException e) {
|
||||
Response.serverError().entity("Cannot get an instance of SOAP factory.").build();
|
||||
}
|
||||
|
||||
QName qNamesSecurity = new QName(PluginConstants.WS_SECURITY_TARGET_NAMESPACE,
|
||||
PluginConstants.CertificateEnrolment.SECURITY);
|
||||
SOAPHeaderElement Security = null;
|
||||
Name attributeName = null;
|
||||
try {
|
||||
if (header != null) {
|
||||
Security = header.addHeaderElement(qNamesSecurity);
|
||||
}
|
||||
if (soapFactory != null) {
|
||||
attributeName =
|
||||
soapFactory.createName(PluginConstants.CertificateEnrolment.TIMESTAMP_ID,
|
||||
PluginConstants.CertificateEnrolment.TIMESTAMP_U,
|
||||
PluginConstants.CertificateEnrolment
|
||||
.WSS_SECURITY_UTILITY);
|
||||
}
|
||||
} catch (SOAPException e) {
|
||||
Response.serverError().entity("Security header cannot be added.").build();
|
||||
}
|
||||
|
||||
QName qNameTimestamp = new QName(PluginConstants.CertificateEnrolment.WSS_SECURITY_UTILITY,
|
||||
PluginConstants.CertificateEnrolment.TIMESTAMP);
|
||||
SOAPHeaderElement timestamp = null;
|
||||
try {
|
||||
if (header != null) {
|
||||
timestamp = header.addHeaderElement(qNameTimestamp);
|
||||
timestamp.addAttribute(attributeName,
|
||||
PluginConstants.CertificateEnrolment.TIMESTAMP_0);
|
||||
}
|
||||
} catch (SOAPException e) {
|
||||
Response.serverError().entity("Exception while adding timestamp header.").build();
|
||||
}
|
||||
DateTime dateTime = new DateTime();
|
||||
DateTime expiredDateTime = dateTime.plusMinutes(VALIDITY_TIME);
|
||||
String createdISOTime = dateTime.toString(ISODateTimeFormat.dateTime());
|
||||
String expiredISOTime = expiredDateTime.toString(ISODateTimeFormat.dateTime());
|
||||
createdISOTime = createdISOTime.substring(TIMESTAMP_BEGIN_INDEX,
|
||||
createdISOTime.length() -
|
||||
TIMESTAMP_END_INDEX);
|
||||
createdISOTime = createdISOTime + TIME_ZONE;
|
||||
expiredISOTime = expiredISOTime.substring(TIMESTAMP_BEGIN_INDEX,
|
||||
expiredISOTime.length() -
|
||||
TIMESTAMP_END_INDEX);
|
||||
expiredISOTime = expiredISOTime + TIME_ZONE;
|
||||
QName qNameCreated = new QName(PluginConstants.CertificateEnrolment.WSS_SECURITY_UTILITY,
|
||||
PluginConstants.CertificateEnrolment.CREATED);
|
||||
SOAPHeaderElement SOAPHeaderCreated = null;
|
||||
|
||||
try {
|
||||
if (header != null) {
|
||||
SOAPHeaderCreated = header.addHeaderElement(qNameCreated);
|
||||
SOAPHeaderCreated.addTextNode(createdISOTime);
|
||||
}
|
||||
} catch (SOAPException e) {
|
||||
Response.serverError().entity("Exception while creating SOAP header.").build();
|
||||
}
|
||||
QName qNameExpires = new QName(PluginConstants.CertificateEnrolment.WSS_SECURITY_UTILITY,
|
||||
PluginConstants.CertificateEnrolment.EXPIRES);
|
||||
SOAPHeaderElement SOAPHeaderExpires = null;
|
||||
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
|
||||
String messageString = null;
|
||||
try {
|
||||
if (header != null) {
|
||||
SOAPHeaderExpires = header.addHeaderElement(qNameExpires);
|
||||
SOAPHeaderExpires.addTextNode(expiredISOTime);
|
||||
}
|
||||
if ((timestamp != null) && (Security != null)) {
|
||||
timestamp.addChildElement(SOAPHeaderCreated);
|
||||
timestamp.addChildElement(SOAPHeaderExpires);
|
||||
Security.addChildElement(timestamp);
|
||||
}
|
||||
message.saveChanges();
|
||||
message.writeTo(outputStream);
|
||||
messageString = new String(outputStream.toByteArray(),
|
||||
PluginConstants.CertificateEnrolment.UTF_8);
|
||||
} catch (SOAPException e) {
|
||||
Response.serverError().entity("Exception while creating timestamp SOAP header.")
|
||||
.build();
|
||||
} catch (IOException e) {
|
||||
Response.serverError().entity("Exception while writing message to output stream.")
|
||||
.build();
|
||||
}
|
||||
|
||||
Map<String, List<String>> headers =
|
||||
(Map<String, List<String>>) context.get(MessageContext.HTTP_REQUEST_HEADERS);
|
||||
headers = new HashMap<String, List<String>>();
|
||||
if (messageString != null) {
|
||||
headers.put(PluginConstants.CONTENT_LENGTH, Arrays.asList(String.valueOf(
|
||||
messageString.length())));
|
||||
}
|
||||
context.put(MessageContext.HTTP_REQUEST_HEADERS, headers);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean handleFault(SOAPMessageContext context) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close(MessageContext context) {
|
||||
}
|
||||
}
|
@ -0,0 +1,203 @@
|
||||
/*
|
||||
* 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.mobile.windows.api.services.impl;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.w3c.dom.Document;
|
||||
import org.wso2.carbon.context.PrivilegedCarbonContext;
|
||||
import org.wso2.carbon.device.mgt.common.Device;
|
||||
import org.wso2.carbon.device.mgt.common.DeviceIdentifier;
|
||||
import org.wso2.carbon.device.mgt.common.DeviceManagementConstants;
|
||||
import org.wso2.carbon.device.mgt.common.DeviceManagementException;
|
||||
import org.wso2.carbon.device.mgt.common.device.details.*;
|
||||
import org.wso2.carbon.device.mgt.common.notification.mgt.NotificationManagementException;
|
||||
import org.wso2.carbon.device.mgt.common.operation.mgt.Operation;
|
||||
import org.wso2.carbon.device.mgt.common.operation.mgt.OperationManagementException;
|
||||
import org.wso2.carbon.device.mgt.mobile.windows.api.common.PluginConstants;
|
||||
import org.wso2.carbon.device.mgt.mobile.windows.api.common.beans.CacheEntry;
|
||||
import org.wso2.carbon.device.mgt.mobile.windows.api.common.exceptions.SyncmlMessageFormatException;
|
||||
import org.wso2.carbon.device.mgt.mobile.windows.api.common.exceptions.SyncmlOperationException;
|
||||
import org.wso2.carbon.device.mgt.mobile.windows.api.common.exceptions.WindowsConfigurationException;
|
||||
import org.wso2.carbon.device.mgt.mobile.windows.api.common.exceptions.WindowsDeviceEnrolmentException;
|
||||
import org.wso2.carbon.device.mgt.mobile.windows.api.common.util.AuthenticationInfo;
|
||||
import org.wso2.carbon.device.mgt.mobile.windows.api.common.util.DeviceUtil;
|
||||
import org.wso2.carbon.device.mgt.mobile.windows.api.common.util.WindowsAPIUtils;
|
||||
import org.wso2.carbon.device.mgt.mobile.windows.api.operations.*;
|
||||
import org.wso2.carbon.device.mgt.mobile.windows.api.operations.util.*;
|
||||
import org.wso2.carbon.device.mgt.mobile.windows.api.operations.util.DeviceInfo;
|
||||
import org.wso2.carbon.device.mgt.mobile.windows.api.services.DeviceManagementService;
|
||||
import org.wso2.carbon.policy.mgt.common.PolicyManagementException;
|
||||
import org.wso2.carbon.policy.mgt.core.PolicyManagerService;
|
||||
|
||||
import javax.ws.rs.core.Response;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import static org.wso2.carbon.device.mgt.mobile.windows.api.common.util.WindowsAPIUtils.convertToDeviceIdentifierObject;
|
||||
|
||||
|
||||
public class DeviceManagementServiceImpl implements DeviceManagementService {
|
||||
private static Log log = LogFactory.getLog(
|
||||
org.wso2.carbon.device.mgt.mobile.windows.api.services.syncml.impl.SyncmlServiceImpl.class);
|
||||
|
||||
@Override
|
||||
public Response getResponse(Document request) throws WindowsDeviceEnrolmentException, WindowsOperationException,
|
||||
NotificationManagementException, WindowsConfigurationException {
|
||||
|
||||
int msgId;
|
||||
int sessionId;
|
||||
String user;
|
||||
String token;
|
||||
String response;
|
||||
SyncmlDocument syncmlDocument;
|
||||
List<? extends Operation> pendingOperations;
|
||||
OperationHandler operationHandler = new OperationHandler();
|
||||
OperationReply operationReply = new OperationReply();
|
||||
|
||||
try {
|
||||
if (SyncmlParser.parseSyncmlPayload(request) != null) {
|
||||
syncmlDocument = SyncmlParser.parseSyncmlPayload(request);
|
||||
SyncmlHeader syncmlHeader = syncmlDocument.getHeader();
|
||||
sessionId = syncmlHeader.getSessionId();
|
||||
user = syncmlHeader.getSource().getLocName();
|
||||
DeviceIdentifier deviceIdentifier = convertToDeviceIdentifierObject(syncmlHeader.getSource().
|
||||
getLocURI());
|
||||
msgId = syncmlHeader.getMsgID();
|
||||
if ((PluginConstants.SyncML.SYNCML_FIRST_MESSAGE_ID == msgId) &&
|
||||
(PluginConstants.SyncML.SYNCML_FIRST_SESSION_ID == sessionId)) {
|
||||
token = syncmlHeader.getCredential().getData();
|
||||
CacheEntry cacheToken = (CacheEntry) DeviceUtil.getCacheEntry(token);
|
||||
|
||||
if ((cacheToken.getUsername() != null) && (cacheToken.getUsername().equals(user))) {
|
||||
|
||||
if (modifyEnrollWithMoreDetail(request)) {
|
||||
pendingOperations = operationHandler.getPendingOperations(syncmlDocument);
|
||||
response = operationReply.generateReply(syncmlDocument,pendingOperations);
|
||||
return Response.status(Response.Status.OK).entity(response).build();
|
||||
} else {
|
||||
String msg = "Error occurred in while modify the enrollment.";
|
||||
log.error(msg);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build();
|
||||
}
|
||||
} else {
|
||||
String msg = "Authentication failure due to incorrect credentials.";
|
||||
log.error(msg);
|
||||
return Response.status(Response.Status.UNAUTHORIZED).entity(msg).build();
|
||||
}
|
||||
} else {
|
||||
if ((syncmlDocument.getBody().getAlert() != null)) {
|
||||
if (!syncmlDocument.getBody().getAlert().getData().equals(Constants.DISENROLL_ALERT_DATA)) {
|
||||
pendingOperations = operationHandler.getPendingOperations(syncmlDocument);
|
||||
return Response.ok().entity(operationReply.generateReply(
|
||||
syncmlDocument, pendingOperations)).build();
|
||||
} else {
|
||||
if (WindowsAPIUtils.getDeviceManagementService().getDevice(deviceIdentifier) != null) {
|
||||
WindowsAPIUtils.getDeviceManagementService().disenrollDevice(deviceIdentifier);
|
||||
return Response.ok().entity(operationReply.generateReply(syncmlDocument, null)).build();
|
||||
} else {
|
||||
String msg = "Enrolled device can not be found in the server.";
|
||||
log.error(msg);
|
||||
return Response.status(Response.Status.NOT_FOUND).entity(msg).build();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
pendingOperations = operationHandler.getPendingOperations(syncmlDocument);
|
||||
return Response.ok().entity(operationReply.generateReply(
|
||||
syncmlDocument, pendingOperations)).build();
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (SyncmlMessageFormatException e) {
|
||||
String msg = "Error occurred while parsing syncml request.";
|
||||
log.error(msg, e);
|
||||
throw new WindowsOperationException(msg, e);
|
||||
} catch (OperationManagementException e) {
|
||||
String msg = "Cannot access operation management service.";
|
||||
log.error(msg, e);
|
||||
throw new WindowsOperationException(msg, e);
|
||||
} catch (SyncmlOperationException e) {
|
||||
String msg = "Error occurred while getting effective feature.";
|
||||
log.error(msg, e);
|
||||
throw new WindowsConfigurationException(msg, e);
|
||||
} catch (DeviceManagementException e) {
|
||||
String msg = "Failure occurred in dis-enrollment flow.";
|
||||
log.error(msg, e);
|
||||
throw new WindowsOperationException(msg, e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enroll phone device
|
||||
*
|
||||
* @param request Device syncml request for the server side.
|
||||
* @return enroll state
|
||||
* @throws WindowsDeviceEnrolmentException
|
||||
* @throws WindowsOperationException
|
||||
*/
|
||||
private boolean modifyEnrollWithMoreDetail(Document request) throws WindowsDeviceEnrolmentException,
|
||||
WindowsOperationException {
|
||||
|
||||
String devMan;
|
||||
String devMod;
|
||||
boolean status = false;
|
||||
String user;
|
||||
SyncmlDocument syncmlDocument;
|
||||
|
||||
try {
|
||||
syncmlDocument = SyncmlParser.parseSyncmlPayload(request);
|
||||
ReplaceTag replace = syncmlDocument.getBody().getReplace();
|
||||
List<ItemTag> itemList = replace.getItems();
|
||||
devMan = itemList.get(PluginConstants.SyncML.DEVICE_MAN_POSITION).getData();
|
||||
devMod = itemList.get(PluginConstants.SyncML.DEVICE_MODEL_POSITION).getData();
|
||||
user = syncmlDocument.getHeader().getSource().getLocName();
|
||||
AuthenticationInfo authenticationInfo = new AuthenticationInfo();
|
||||
authenticationInfo.setUsername(user);
|
||||
WindowsAPIUtils.startTenantFlow(authenticationInfo);
|
||||
DeviceIdentifier deviceIdentifier = convertToDeviceIdentifierObject(syncmlDocument.
|
||||
getHeader().getSource().getLocURI());
|
||||
Device existingDevice = WindowsAPIUtils.getDeviceManagementService().getDevice(deviceIdentifier);
|
||||
if (!existingDevice.getProperties().isEmpty()) {
|
||||
List<Device.Property> existingProperties = new ArrayList<>();
|
||||
|
||||
Device.Property vendorProperty = new Device.Property();
|
||||
vendorProperty.setName(PluginConstants.SyncML.VENDOR);
|
||||
vendorProperty.setValue(devMan);
|
||||
existingProperties.add(vendorProperty);
|
||||
|
||||
Device.Property deviceModelProperty = new Device.Property();
|
||||
deviceModelProperty.setName(PluginConstants.SyncML.MODEL);
|
||||
deviceModelProperty.setValue(devMod);
|
||||
existingProperties.add(deviceModelProperty);
|
||||
|
||||
existingDevice.setProperties(existingProperties);
|
||||
existingDevice.setDeviceIdentifier(syncmlDocument.getHeader().getSource().getLocURI());
|
||||
existingDevice.setType(DeviceManagementConstants.MobileDeviceTypes.MOBILE_DEVICE_TYPE_WINDOWS);
|
||||
status = WindowsAPIUtils.getDeviceManagementService().modifyEnrollment(existingDevice);
|
||||
return status;
|
||||
}
|
||||
} catch (DeviceManagementException e) {
|
||||
throw new WindowsDeviceEnrolmentException("Failure occurred while enrolling device.", e);
|
||||
} finally {
|
||||
PrivilegedCarbonContext.endTenantFlow();
|
||||
}
|
||||
return status;
|
||||
}
|
||||
}
|
@ -1,26 +0,0 @@
|
||||
<!--
|
||||
~ 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.
|
||||
-->
|
||||
<WindowsPlugin>
|
||||
<AuthPolicy>Federated</AuthPolicy>
|
||||
<Password>wso2carbon</Password>
|
||||
<PrivateKeyPassword>cacert</PrivateKeyPassword>
|
||||
<SignedCertCN>CN=mdmcn</SignedCertCN>
|
||||
<SignedCertNotBefore>3</SignedCertNotBefore>
|
||||
<SignedCertNotAfter>300</SignedCertNotAfter>
|
||||
<domain>wso2.com</domain>
|
||||
</WindowsPlugin>
|
Binary file not shown.
@ -1,24 +0,0 @@
|
||||
<table class="table table-striped table-hover table-bordered display data-table" id="operations-log-table">
|
||||
<thead>
|
||||
<tr class="sort-row">
|
||||
<th>Operation Code</th>
|
||||
<th>Status</th>
|
||||
<th>Request created at</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{{#each operations}}
|
||||
<tr data-type="selectable" data-id="{{id}}">
|
||||
<td data-display="{{code}}" data-grid-label="Code">{{code}}</td>
|
||||
<td data-display="{{status}}" data-grid-label="Status">
|
||||
{{#equal status "COMPLETED"}}<span><i class="fw fw-ok icon-success"></i> Completed</span>{{/equal}}
|
||||
{{#equal status "PENDING"}}<span><i class="fw fw-warning icon-warning"></i> Pending</span>{{/equal}}
|
||||
{{#equal status "ERROR"}}<span><i class="fw fw-error icon-danger"></i> Error</span>{{/equal}}
|
||||
{{#equal status "IN_PROGRESS"}}<span><i class="fw fw-ok icon-warning"></i> In Progress</span>{{/equal}}
|
||||
</td>
|
||||
<td data-display="{{createdTimeStamp}}" data-grid-label="Created Timestamp">{{createdTimeStamp}}</td>
|
||||
</tr>
|
||||
{{/each}}
|
||||
<br class="c-both" />
|
||||
</tbody>
|
||||
</table>
|
@ -0,0 +1,146 @@
|
||||
{{!
|
||||
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.
|
||||
}}
|
||||
{{#if control_operations}}
|
||||
<div class="wr-operations" style="height: 87px; display: block;"
|
||||
xmlns="http://www.w3.org/1999/html">
|
||||
<style>
|
||||
::-webkit-input-placeholder {
|
||||
color: #B8B8B8;
|
||||
}
|
||||
|
||||
::-moz-placeholder {
|
||||
color: #B8B8B8;
|
||||
}
|
||||
|
||||
:-ms-input-placeholder {
|
||||
color: #B8B8B8;
|
||||
}
|
||||
|
||||
input:-moz-placeholder {
|
||||
color: #B8B8B8;
|
||||
}
|
||||
</style>
|
||||
{{#each control_operations}}
|
||||
<a href="javascript:operationSelect('{{operation}}')">
|
||||
{{#if iconFont}}
|
||||
<i class="fw {{iconFont}}"></i>
|
||||
{{else}}
|
||||
{{#if icon}}
|
||||
<img src="{{@app.context}}/{{icon}}" style="width: 48px;"/>
|
||||
{{else}}
|
||||
<i class="fw fw-service"></i>
|
||||
{{/if}}
|
||||
{{/if}}
|
||||
<span>{{name}}</span>
|
||||
</a>
|
||||
|
||||
<div class="operation" data-operation-code="{{operation}}">
|
||||
<div class="content">
|
||||
<div class="row">
|
||||
<div class="col-lg-5 col-md-6 col-centered">
|
||||
<h3>
|
||||
<span class="fw-stack">
|
||||
<i class="fw fw-ring fw-stack-2x"></i>
|
||||
<i class="fw {{iconFont}} fw-stack-1x"></i>
|
||||
</span>
|
||||
{{name}}
|
||||
<br>
|
||||
</h3>
|
||||
<h4>
|
||||
{{description}}
|
||||
<br>
|
||||
</h4>
|
||||
|
||||
<form action="{{params.0.uri}}" method="{{params.0.method}}"
|
||||
style="padding-bottom: 20px;"
|
||||
data-payload="{{payload}}" id="form-{{operation}}"
|
||||
data-device-id="{{../device.deviceIdentifier}}"
|
||||
data-content-type="{{params.0.contentType}}"
|
||||
data-operation-code="{{operation}}">
|
||||
{{#each params.0.pathParams}}
|
||||
<input type="{{type}}" id="{{name}}" placeholder="{{name}}" class="form-control" data-param-type="path" value="{{value}}" />
|
||||
<br />
|
||||
{{/each}}
|
||||
{{#each params.0.formParams}}
|
||||
<input type="{{type}}" id="{{name}}" name="{{name}}" placeholder="{{name}}" class="form-control" data-param-type="form" value="{{value}}" />
|
||||
<br />
|
||||
{{/each}}
|
||||
{{#each params.0.queryParams}}
|
||||
<input type="{{type}}" id="{{name}}" placeholder="{{name}}" class="form-control" data-param-type="query" value="{{value}}" />
|
||||
<br />
|
||||
{{/each}}
|
||||
{{#each uiParams}}
|
||||
{{#equal this.type "checkbox"}}
|
||||
<input type="{{this.type}}" id="{{this.id}}"
|
||||
class="checkbox"
|
||||
placeholder="{{this.label}}"
|
||||
data-param-type="form"/>
|
||||
{{this.label}}
|
||||
<br/>
|
||||
{{/equal}}
|
||||
{{#equal this.type "text"}}
|
||||
<input type="{{this.type}}" id="{{this.id}}"
|
||||
placeholder="{{this.label}}" class="form-control"
|
||||
data-param-type="form" value=""/>
|
||||
<br/>
|
||||
{{/equal}}
|
||||
{{/each}}
|
||||
<button id="btnSend" type="button" onclick="submitForm('form-{{operation}}')" class="btn btn-default"> Send
|
||||
to Device </button>
|
||||
<label id="lblSending" class="wr-input-label hidden"><i
|
||||
class="fw fw-lifecycle fw-spin fw-2x"></i> Sending..</label>
|
||||
<label id="lblSent" class="wr-input-label hidden"><i
|
||||
class="fw fw-check fw-2x"></i> Sent</label>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{{/each}}
|
||||
</div>
|
||||
{{else}}
|
||||
<div align="center">
|
||||
<h4 style="color: #D8000C"><i class="icon fw fw-error" style="color: #D8000C"></i>
|
||||
Operations Loading Failed!</h4>
|
||||
</div>
|
||||
{{/if}}
|
||||
|
||||
<div id="operation-response-template" style="display: none">
|
||||
<div class="content">
|
||||
<div class="row">
|
||||
<div class="col-lg-5 col-md-6 col-centered">
|
||||
<h3>
|
||||
<span class="fw-stack">
|
||||
<i class="fw fw-ring fw-stack-2x"></i>
|
||||
<i id="status-icon" class="fw fw-error fw-stack-1x"></i>
|
||||
</span>
|
||||
<br>
|
||||
</h3>
|
||||
<h4>
|
||||
<span id="title"></span>
|
||||
<br>
|
||||
</h4>
|
||||
<span id="description"></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{#zone "bottomJs"}}
|
||||
{{js "js/operation-bar.js"}}
|
||||
{{/zone}}
|
@ -0,0 +1,65 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
function onRequest(context) {
|
||||
var log = new Log("operation.js");
|
||||
var operationModule = require("/app/modules/business-controllers/operation.js")["operationModule"];
|
||||
var device = context.unit.params.device;
|
||||
var autoCompleteParams = context.unit.params.autoCompleteParams;
|
||||
var encodedFeaturePayloads=context.unit.params.encodedFeaturePayloads;
|
||||
var controlOperations = operationModule.getControlOperations(device.type);
|
||||
var queryParams = [];
|
||||
var formParams = [];
|
||||
var pathParams = [];
|
||||
for (var i = 0; i < controlOperations.length; i++) {
|
||||
var currentParamList = controlOperations[i]["params"];
|
||||
var uiParamList = controlOperations[i]["uiParams"];
|
||||
for (var j = 0; j < currentParamList.length; j++) {
|
||||
var currentParam = currentParamList[j];
|
||||
currentParamList[j]["formParams"] = processParams(currentParam["formParams"], autoCompleteParams);
|
||||
currentParamList[j]["queryParams"] = processParams(currentParam["queryParams"], autoCompleteParams);
|
||||
currentParamList[j]["pathParams"] = processParams(currentParam["pathParams"], autoCompleteParams);
|
||||
}
|
||||
controlOperations[i]["uiParams"] = uiParamList;
|
||||
if (encodedFeaturePayloads) {
|
||||
controlOperations[i]["payload"] = getPayload(encodedFeaturePayloads, controlOperations[i]["operation"]);
|
||||
}
|
||||
}
|
||||
return {"control_operations": controlOperations, "device": device};
|
||||
}
|
||||
|
||||
function processParams(paramsList, autoCompleteParams) {
|
||||
for (var i = 0; i < paramsList.length; i++) {
|
||||
var paramName = paramsList[i];
|
||||
var paramValue = "";
|
||||
var paramType = "text";
|
||||
for (var k = 0; k < autoCompleteParams.length; k++) {
|
||||
if (paramName == autoCompleteParams[k].name) {
|
||||
paramValue = autoCompleteParams[k].value;
|
||||
paramType = "hidden";
|
||||
}
|
||||
}
|
||||
paramsList[i] = {"name": paramName, "value": paramValue, "type": paramType};
|
||||
}
|
||||
return paramsList;
|
||||
}
|
||||
|
||||
function getPayload(featuresPayload, featureCode){
|
||||
var featuresJSONPayloads = JSON.parse(featuresPayload);
|
||||
return featuresJSONPayloads[featureCode];
|
||||
}
|
@ -0,0 +1,3 @@
|
||||
{
|
||||
"version": "1.0.0"
|
||||
}
|
@ -0,0 +1,227 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* On operation click function.
|
||||
* @param selection: Selected operation
|
||||
*/
|
||||
function operationSelect(selection) {
|
||||
$(modalPopupContent).addClass("operation-data");
|
||||
$(modalPopupContent).html($(" .operation[data-operation-code=" + selection + "]").html());
|
||||
$(modalPopupContent).data("operation-code", selection);
|
||||
showPopup();
|
||||
}
|
||||
|
||||
function submitForm(formId) {
|
||||
var form = $("#" + formId);
|
||||
var uri = form.attr("action");
|
||||
var deviceId = form.data("device-id");
|
||||
var contentType = form.data("content-type");
|
||||
var operationCode = form.data("operation-code");
|
||||
var uriencodedQueryStr = "";
|
||||
var uriencodedFormStr = "";
|
||||
var payload = {};
|
||||
form.find("input").each(function () {
|
||||
var input = $(this);
|
||||
if (input.data("param-type") == "path") {
|
||||
uri = uri.replace("{" + input.attr("id") + "}", input.val());
|
||||
} else if (input.data("param-type") == "query") {
|
||||
var prefix = (uriencodedQueryStr == "") ? "?" : "&";
|
||||
uriencodedQueryStr += prefix + input.attr("id") + "=" + input.val();
|
||||
} else if (input.data("param-type") == "form") {
|
||||
var prefix = (uriencodedFormStr == "") ? "" : "&";
|
||||
uriencodedFormStr += prefix + input.attr("id") + "=" + input.val();
|
||||
if(input.attr("type") == "text"){
|
||||
payload[input.attr("id")] = input.val();
|
||||
} else if(input.attr("type") == "checkbox"){
|
||||
payload[input.attr("id")] = input.is(":checked");
|
||||
}
|
||||
}
|
||||
});
|
||||
uri += uriencodedQueryStr;
|
||||
var httpMethod = form.attr("method").toUpperCase();
|
||||
//var contentType = form.attr("enctype");
|
||||
|
||||
if (contentType == undefined || contentType == "") {
|
||||
contentType = "application/x-www-form-urlencoded";
|
||||
payload = uriencodedFormStr;
|
||||
}
|
||||
|
||||
//setting responses callbacks
|
||||
var defaultStatusClasses = "fw fw-stack-1x";
|
||||
var content = $("#operation-response-template").find(".content");
|
||||
var title = content.find("#title");
|
||||
var statusIcon = content.find("#status-icon");
|
||||
var description = content.find("#description");
|
||||
description.html("");
|
||||
var successCallBack = function (response) {
|
||||
var res = response;
|
||||
try {
|
||||
res = JSON.parse(response).messageFromServer;
|
||||
} catch (err) {
|
||||
//do nothing
|
||||
}
|
||||
title.html("Operation Triggered!");
|
||||
statusIcon.attr("class", defaultStatusClasses + " fw-check");
|
||||
description.html(res);
|
||||
console.log("success!");
|
||||
$(modalPopupContent).html(content.html());
|
||||
};
|
||||
var errorCallBack = function (response) {
|
||||
console.log(response);
|
||||
title.html("An Error Occurred!");
|
||||
statusIcon.attr("class", defaultStatusClasses + " fw-error");
|
||||
var reason = (response.responseText == "null")?response.statusText:response.responseText;
|
||||
try {
|
||||
reason = JSON.parse(reason).message;
|
||||
} catch (err) {
|
||||
//do nothing
|
||||
}
|
||||
description.html(reason);
|
||||
console.log("Error!");
|
||||
$(modalPopupContent).html(content.html());
|
||||
};
|
||||
//executing http request
|
||||
if (httpMethod == "GET") {
|
||||
invokerUtil.get(uri, successCallBack, errorCallBack, contentType);
|
||||
} else if (httpMethod == "POST") {
|
||||
var deviceList = [deviceId];
|
||||
payload = generatePayload(operationCode, payload, deviceList);
|
||||
invokerUtil.post(uri, payload, successCallBack, errorCallBack, contentType);
|
||||
} else if (httpMethod == "PUT") {
|
||||
invokerUtil.put(uri, payload, successCallBack, errorCallBack, contentType);
|
||||
} else if (httpMethod == "DELETE") {
|
||||
invokerUtil.delete(uri, successCallBack, errorCallBack, contentType);
|
||||
} else {
|
||||
title.html("An Error Occurred!");
|
||||
statusIcon.attr("class", defaultStatusClasses + " fw-error");
|
||||
description.html("This operation requires http method: " + httpMethod + " which is not supported yet!");
|
||||
$(modalPopupContent).html(content.html());
|
||||
}
|
||||
}
|
||||
|
||||
$(document).on('submit', 'form', function (e) {
|
||||
cosole.log("darn!!");
|
||||
e.preventDefault();
|
||||
var postOperationRequest = $.ajax({
|
||||
url: $(this).attr("action") + '&' + $(this).serialize(),
|
||||
method: "post"
|
||||
});
|
||||
|
||||
var btnSubmit = $('#btnSend', this);
|
||||
btnSubmit.addClass('hidden');
|
||||
|
||||
var lblSending = $('#lblSending', this);
|
||||
lblSending.removeClass('hidden');
|
||||
|
||||
var lblSent = $('#lblSent', this);
|
||||
postOperationRequest.done(function (data) {
|
||||
lblSending.addClass('hidden');
|
||||
lblSent.removeClass('hidden');
|
||||
setTimeout(function () {
|
||||
hidePopup();
|
||||
}, 3000);
|
||||
});
|
||||
|
||||
postOperationRequest.fail(function (jqXHR, textStatus) {
|
||||
lblSending.addClass('hidden');
|
||||
lblSent.addClass('hidden');
|
||||
});
|
||||
});
|
||||
|
||||
// Constants to define operation types available
|
||||
var operationTypeConstants = {
|
||||
"PROFILE": "profile",
|
||||
"CONFIG": "config",
|
||||
"COMMAND": "command"
|
||||
};
|
||||
|
||||
|
||||
var generatePayload = function (operationCode, operationData, deviceList) {
|
||||
var payload;
|
||||
var operationType;
|
||||
switch (operationCode) {
|
||||
case windowsOperationConstants["CAMERA_OPERATION_CODE"]:
|
||||
operationType = operationTypeConstants["PROFILE"];
|
||||
payload = {
|
||||
"operation": {
|
||||
"enabled": operationData["cameraEnabled"]
|
||||
}
|
||||
};
|
||||
break;
|
||||
case windowsOperationConstants["CHANGE_LOCK_CODE_OPERATION_CODE"]:
|
||||
operationType = operationTypeConstants["PROFILE"];
|
||||
payload = {
|
||||
"operation": {
|
||||
"lockCode": operationData["lockCode"]
|
||||
}
|
||||
};
|
||||
break;
|
||||
case windowsOperationConstants["ENCRYPT_STORAGE_OPERATION_CODE"]:
|
||||
operationType = operationTypeConstants["PROFILE"];
|
||||
payload = {
|
||||
"operation": {
|
||||
"encrypted": operationData["encryptStorageEnabled"]
|
||||
}
|
||||
};
|
||||
break;
|
||||
case windowsOperationConstants["NOTIFICATION_OPERATION_CODE"]:
|
||||
operationType = operationTypeConstants["PROFILE"];
|
||||
payload = {
|
||||
"operation": {
|
||||
"message": operationData["message"]
|
||||
}
|
||||
};
|
||||
break;
|
||||
case windowsOperationConstants["PASSCODE_POLICY_OPERATION_CODE"]:
|
||||
operationType = operationTypeConstants["PROFILE"];
|
||||
payload = {
|
||||
"operation": {
|
||||
"allowSimple": operationData["passcodePolicyAllowSimple"],
|
||||
"requireAlphanumeric": operationData["passcodePolicyRequireAlphanumeric"],
|
||||
"minLength": operationData["passcodePolicyMinLength"],
|
||||
"minComplexChars": operationData["passcodePolicyMinComplexChars"],
|
||||
"maxPINAgeInDays": operationData["passcodePolicyMaxPasscodeAgeInDays"],
|
||||
"pinHistory": operationData["passcodePolicyPasscodeHistory"],
|
||||
"maxFailedAttempts": operationData["passcodePolicyMaxFailedAttempts"]
|
||||
}
|
||||
};
|
||||
break;
|
||||
default:
|
||||
// If the operation is neither of above, it is a command operation
|
||||
operationType = operationTypeConstants["COMMAND"];
|
||||
// Operation payload of a command operation is simply an array of device IDs
|
||||
payload = deviceList;
|
||||
}
|
||||
|
||||
if (operationType == operationTypeConstants["PROFILE"] && deviceList) {
|
||||
payload["deviceIDs"] = deviceList;
|
||||
}
|
||||
|
||||
return payload;
|
||||
};
|
||||
|
||||
|
||||
// Constants to define Windows Operation Constants
|
||||
var windowsOperationConstants = {
|
||||
"PASSCODE_POLICY_OPERATION_CODE": "PASSCODE_POLICY",
|
||||
"CAMERA_OPERATION_CODE": "CAMERA",
|
||||
"ENCRYPT_STORAGE_OPERATION_CODE": "ENCRYPT_STORAGE",
|
||||
"NOTIFICATION_OPERATION_CODE": "NOTIFICATION",
|
||||
"CHANGE_LOCK_CODE_OPERATION_CODE": "CHANGE_LOCK_CODE"
|
||||
};
|
Loading…
Reference in new issue