diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/api/UserManagementService.java b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/api/UserManagementService.java index 432b752a66..5e580f6a06 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/api/UserManagementService.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/api/UserManagementService.java @@ -49,6 +49,7 @@ import io.swagger.annotations.ResponseHeader; import org.apache.axis2.transport.http.HTTPConstants; import org.wso2.carbon.apimgt.annotations.api.Scopes; import org.wso2.carbon.apimgt.annotations.api.Scope; +import org.wso2.carbon.device.mgt.common.invitation.mgt.DeviceEnrollmentInvitation; import org.wso2.carbon.device.mgt.jaxrs.beans.ActivityList; import org.wso2.carbon.device.mgt.jaxrs.beans.BasicUserInfo; import org.wso2.carbon.device.mgt.jaxrs.beans.BasicUserInfoList; @@ -74,7 +75,6 @@ import javax.ws.rs.Produces; import javax.ws.rs.QueryParam; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; -import java.util.List; @SwaggerDefinition( info = @Info( @@ -893,7 +893,8 @@ public interface UserManagementService { @ApiParam( name = "users", value = "List of users", - required = true) List usernames); + required = true) + @Valid DeviceEnrollmentInvitation deviceEnrollmentInvitation); @POST @Path("/enrollment-invite") diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/UserManagementServiceImpl.java b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/UserManagementServiceImpl.java index 81233092f3..6f240093ec 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/UserManagementServiceImpl.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/UserManagementServiceImpl.java @@ -45,8 +45,11 @@ import org.wso2.carbon.context.PrivilegedCarbonContext; import org.wso2.carbon.device.mgt.common.exceptions.DeviceManagementException; import org.wso2.carbon.device.mgt.common.EnrolmentInfo; import org.wso2.carbon.device.mgt.common.configuration.mgt.ConfigurationManagementException; +import org.wso2.carbon.device.mgt.common.exceptions.OTPManagementException; +import org.wso2.carbon.device.mgt.common.invitation.mgt.DeviceEnrollmentInvitation; import org.wso2.carbon.device.mgt.common.operation.mgt.Activity; import org.wso2.carbon.device.mgt.common.operation.mgt.OperationManagementException; +import org.wso2.carbon.device.mgt.common.spi.OTPManagementService; import org.wso2.carbon.device.mgt.core.DeviceManagementConstants; import org.wso2.carbon.device.mgt.core.service.DeviceManagementProviderService; import org.wso2.carbon.device.mgt.core.service.EmailMetaInfo; @@ -716,48 +719,29 @@ public class UserManagementServiceImpl implements UserManagementService { return CredentialManagementResponseBuilder.buildChangePasswordResponse(credentials); } - /** - * Method used to send an invitation email to a existing user to enroll a device. - * - * @param usernames Username list of the users to be invited - */ + @POST @Path("/send-invitation") @Produces({MediaType.APPLICATION_JSON}) - public Response inviteExistingUsersToEnrollDevice(List usernames) { + public Response inviteExistingUsersToEnrollDevice(DeviceEnrollmentInvitation deviceEnrollmentInvitation) { + if (deviceEnrollmentInvitation.getUsernames() == null || deviceEnrollmentInvitation.getUsernames().isEmpty()) { + String msg = "Error occurred while validating list of user-names. User-names cannot be empty."; + log.error(msg); + throw new BadRequestException( + new ErrorResponse.ErrorResponseBuilder().setCode(HttpStatus.SC_BAD_REQUEST).setMessage(msg) + .build()); + } if (log.isDebugEnabled()) { - log.debug("Sending enrollment invitation mail to existing user."); + log.debug("Sending device enrollment invitation mail to existing user/s."); } - DeviceManagementProviderService dms = DeviceMgtAPIUtils.getDeviceManagementService(); + OTPManagementService oms = DeviceMgtAPIUtils.getOTPManagementService(); try { - for (String username : usernames) { - String recipient = getClaimValue(username, Constants.USER_CLAIM_EMAIL_ADDRESS); - - Properties props = new Properties(); - props.setProperty("first-name", getClaimValue(username, Constants.USER_CLAIM_FIRST_NAME)); - props.setProperty("username", username); - - EmailMetaInfo metaInfo = new EmailMetaInfo(recipient, props); - dms.sendEnrolmentInvitation(DeviceManagementConstants.EmailAttributes.USER_ENROLLMENT_TEMPLATE, - metaInfo); - } - } catch (DeviceManagementException e) { - String msg = "Error occurred while inviting user to enrol their device"; - if (e.getMessage() != null && !e.getMessage().isEmpty()) { - msg = e.getMessage(); - } + oms.sendDeviceEnrollmentInvitationMail(deviceEnrollmentInvitation); + } catch (OTPManagementException e) { + String msg = "Error occurred while generating OTP and inviting user/s to enroll their device/s."; log.error(msg, e); return Response.serverError().entity( new ErrorResponse.ErrorResponseBuilder().setMessage(msg).build()).build(); - } catch (UserStoreException e) { - String msg = "Error occurred while getting claim values to invite user"; - log.error(msg, e); - return Response.serverError().entity( - new ErrorResponse.ErrorResponseBuilder().setMessage(msg).build()).build(); - } catch (ConfigurationManagementException e) { - String msg = "Error occurred while sending the email invitations. Mail server not configured."; - return Response.serverError().entity( - new ErrorResponse.ErrorResponseBuilder().setMessage(msg).build()).build(); } return Response.status(Response.Status.OK).entity("Invitation mails have been sent.").build(); } diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/util/DeviceMgtAPIUtils.java b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/util/DeviceMgtAPIUtils.java index 91161ced0d..e3a166dc2b 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/util/DeviceMgtAPIUtils.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/util/DeviceMgtAPIUtils.java @@ -14,6 +14,23 @@ * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. + * + * + * Copyright (c) 2020, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved. + * + * Entgra (Pvt) Ltd. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. */ package org.wso2.carbon.device.mgt.jaxrs.util; @@ -142,6 +159,7 @@ public class DeviceMgtAPIUtils { private static IntegrationClientService integrationClientService; private static MetadataManagementService metadataManagementService; + private static OTPManagementService otpManagementService; static { String keyStorePassword = ServerConfiguration.getInstance().getFirstProperty("Security.KeyStore.Password"); @@ -338,6 +356,29 @@ public class DeviceMgtAPIUtils { return integrationClientService; } + /** + * Initializing and accessing method for OTPManagementService. + * + * @return OTPManagementService instance + * @throws IllegalStateException if OTPManagementService cannot be initialized + */ + public static synchronized OTPManagementService getOTPManagementService() { + if (otpManagementService == null) { + synchronized (DeviceMgtAPIUtils.class) { + if (otpManagementService == null) { + PrivilegedCarbonContext ctx = PrivilegedCarbonContext.getThreadLocalCarbonContext(); + otpManagementService = (OTPManagementService) ctx.getOSGiService(OTPManagementService.class, null); + if (otpManagementService == null) { + String msg = "OTP Management service has not initialized."; + log.error(msg); + throw new IllegalStateException(msg); + } + } + } + } + return otpManagementService; + } + public static RegistryService getRegistryService() { RegistryService registryService; PrivilegedCarbonContext ctx = PrivilegedCarbonContext.getThreadLocalCarbonContext(); diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/util/DeviceManagerUtil.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/util/DeviceManagerUtil.java index cb5d305aef..9404e5de86 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/util/DeviceManagerUtil.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/util/DeviceManagerUtil.java @@ -14,6 +14,23 @@ * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. + * + * + * Copyright (c) 2020, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved. + * + * Entgra (Pvt) Ltd. 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.core.util; @@ -79,6 +96,7 @@ import org.wso2.carbon.identity.jwt.client.extension.service.JWTClientManagerSer import org.wso2.carbon.user.api.TenantManager; import org.wso2.carbon.user.api.UserRealm; import org.wso2.carbon.user.api.UserStoreException; +import org.wso2.carbon.user.api.UserStoreManager; import org.wso2.carbon.utils.CarbonUtils; import org.wso2.carbon.utils.ConfigurationContextService; import org.wso2.carbon.utils.NetworkUtils; @@ -1047,4 +1065,17 @@ public final class DeviceManagerUtil { } return roleList; } + + /** + * Retrieve the value of the user property from the user profile + * @param username of the user + * @param claimUri name of the claim + * @return value for the claim uri of user + * @throws UserStoreException when there is error in retrieving the user store manager + */ + public static String getUserClaimValue(String username, String claimUri) throws UserStoreException { + UserStoreManager userStoreManager = CarbonContext.getThreadLocalCarbonContext().getUserRealm() + .getUserStoreManager(); + return userStoreManager.getUserClaimValue(username, claimUri, null); + } }