forked from community/device-mgt-plugins
parent
ad812f2328
commit
0456502bbe
@ -0,0 +1,43 @@
|
|||||||
|
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,394 @@
|
|||||||
|
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.DeviceManagementConstants;
|
||||||
|
import org.wso2.carbon.device.mgt.common.DeviceManagementException;
|
||||||
|
import org.wso2.carbon.device.mgt.common.EnrolmentInfo;
|
||||||
|
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.beans.Device;
|
||||||
|
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.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 CertificateEnrollmentService interface. This class implements MS-WSTEP
|
||||||
|
* protocol.
|
||||||
|
*/
|
||||||
|
@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();
|
||||||
|
WindowsDevice windowsDevice = new WindowsDevice();
|
||||||
|
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().getNextSibling().getFirstChild().getTextContent();
|
||||||
|
}
|
||||||
|
if (PluginConstants.TO.equals(nodeName)) {
|
||||||
|
Element toElement = (Element) headerElement.getObject();
|
||||||
|
headerTo = toElement.getFirstChild().getTextContent();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
windowsDevice.setDeviceType(DeviceManagementConstants.MobileDeviceTypes.
|
||||||
|
MOBILE_DEVICE_TYPE_WINDOWS);
|
||||||
|
windowsDevice.setUser(getRequestedUser(headerBinarySecurityToken));
|
||||||
|
List<ContextItem> contextItems = additionalContext.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());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/////////
|
||||||
|
|
||||||
|
org.wso2.carbon.device.mgt.common.Device device = generateDevice(windowsDevice);
|
||||||
|
try {
|
||||||
|
WindowsAPIUtils.getDeviceManagementService().enrollDevice(device);
|
||||||
|
} catch (DeviceManagementException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
/////////
|
||||||
|
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_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));
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getRequestedUser(String bst) {
|
||||||
|
CacheEntry cacheEntry = (CacheEntry) DeviceUtil.getCacheEntry(bst);
|
||||||
|
String userName = cacheEntry.getUsername();
|
||||||
|
return userName;
|
||||||
|
}
|
||||||
|
|
||||||
|
private org.wso2.carbon.device.mgt.common.Device generateDevice(WindowsDevice windowsDevice) {
|
||||||
|
|
||||||
|
org.wso2.carbon.device.mgt.common.Device generatedDevice = new org.wso2.carbon.device.mgt.common.Device();
|
||||||
|
|
||||||
|
org.wso2.carbon.device.mgt.common.Device.Property DeviceNameProperty = new org.wso2.carbon.device.mgt.common.Device.Property();
|
||||||
|
DeviceNameProperty.setName(PluginConstants.SyncML.DEVICE_NAME);
|
||||||
|
DeviceNameProperty.setValue(windowsDevice.getDeviceName());
|
||||||
|
|
||||||
|
org.wso2.carbon.device.mgt.common.Device.Property OSVersionProperty = new org.wso2.carbon.device.mgt.common.Device.Property();
|
||||||
|
OSVersionProperty.setName(PluginConstants.SyncML.OS_VERSION);
|
||||||
|
OSVersionProperty.setValue(windowsDevice.getOsVersion());
|
||||||
|
|
||||||
|
org.wso2.carbon.device.mgt.common.Device.Property IMSEIProperty = new org.wso2.carbon.device.mgt.common.Device.Property();
|
||||||
|
IMSEIProperty.setName(PluginConstants.SyncML.IMSI);
|
||||||
|
IMSEIProperty.setValue(windowsDevice.getImsi());
|
||||||
|
|
||||||
|
org.wso2.carbon.device.mgt.common.Device.Property IMEIProperty = new org.wso2.carbon.device.mgt.common.Device.Property();
|
||||||
|
IMEIProperty.setName(PluginConstants.SyncML.IMEI);
|
||||||
|
IMEIProperty.setValue(windowsDevice.getImei());
|
||||||
|
|
||||||
|
List<org.wso2.carbon.device.mgt.common.Device.Property> propertyList = new ArrayList<>();
|
||||||
|
propertyList.add(OSVersionProperty);
|
||||||
|
propertyList.add(IMSEIProperty);
|
||||||
|
propertyList.add(IMEIProperty);
|
||||||
|
propertyList.add(DeviceNameProperty);
|
||||||
|
|
||||||
|
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());
|
||||||
|
|
||||||
|
return generatedDevice;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -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,127 @@
|
|||||||
|
{{!
|
||||||
|
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;">
|
||||||
|
<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 fw-service 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}}">
|
||||||
|
{{#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}}
|
||||||
|
<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,67 @@
|
|||||||
|
/*
|
||||||
|
* 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"];
|
||||||
|
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]["params"] = currentParamList;
|
||||||
|
if (encodedFeaturePayloads) {
|
||||||
|
controlOperations[i]["payload"] = getPayload(encodedFeaturePayloads, controlOperations[i]["operation"]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return {"control_operations": controlOperations, "device": device};
|
||||||
|
}
|
||||||
|
|
||||||
|
function processParams(paramsList, autoCompleteParams) {
|
||||||
|
var log = new Log();
|
||||||
|
log.info("-- Params : "+paramsList.length);
|
||||||
|
log.info("-- Auto Params : "+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,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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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 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();
|
||||||
|
//payload[input.attr("id")] = input.val();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
uri += uriencodedQueryStr;
|
||||||
|
var httpMethod = form.attr("method").toUpperCase();
|
||||||
|
var contentType = form.attr("enctype");
|
||||||
|
console.log("URL "+uri);
|
||||||
|
console.log("Method "+httpMethod);
|
||||||
|
console.log("Content Type "+contentType);
|
||||||
|
var featurePayload = form.attr("data-payload");
|
||||||
|
if (featurePayload) {
|
||||||
|
contentType = "application/json";
|
||||||
|
payload = JSON.parse(atob(featurePayload));
|
||||||
|
|
||||||
|
} else if (contentType == undefined || contentType.isEmpty()) {
|
||||||
|
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") {
|
||||||
|
console.log("------ cType "+contentType);
|
||||||
|
var payloadTest = [deviceId];
|
||||||
|
invokerUtil.post(uri, payloadTest, successCallBack, errorCallBack, "application/json");
|
||||||
|
} 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');
|
||||||
|
});
|
||||||
|
});
|
Loading…
Reference in new issue