diff --git a/components/apimgt-extensions/org.wso2.carbon.apimgt.handlers/src/main/java/org/wso2/carbon/apimgt/handlers/AuthenticationHandler.java b/components/apimgt-extensions/org.wso2.carbon.apimgt.handlers/src/main/java/org/wso2/carbon/apimgt/handlers/AuthenticationHandler.java index c9873629b7..464dfc248d 100644 --- a/components/apimgt-extensions/org.wso2.carbon.apimgt.handlers/src/main/java/org/wso2/carbon/apimgt/handlers/AuthenticationHandler.java +++ b/components/apimgt-extensions/org.wso2.carbon.apimgt.handlers/src/main/java/org/wso2/carbon/apimgt/handlers/AuthenticationHandler.java @@ -232,4 +232,4 @@ public class AuthenticationHandler extends AbstractHandler { map.put(CONTENT_TYPE, "application/json"); return map; } -} \ No newline at end of file +} diff --git a/components/apimgt-extensions/org.wso2.carbon.apimgt.handlers/src/main/java/org/wso2/carbon/apimgt/handlers/utils/AuthConstants.java b/components/apimgt-extensions/org.wso2.carbon.apimgt.handlers/src/main/java/org/wso2/carbon/apimgt/handlers/utils/AuthConstants.java index f2a9f7a42b..d9a9ef8a7b 100644 --- a/components/apimgt-extensions/org.wso2.carbon.apimgt.handlers/src/main/java/org/wso2/carbon/apimgt/handlers/utils/AuthConstants.java +++ b/components/apimgt-extensions/org.wso2.carbon.apimgt.handlers/src/main/java/org/wso2/carbon/apimgt/handlers/utils/AuthConstants.java @@ -24,6 +24,7 @@ public class AuthConstants { public static final String MDM_SIGNATURE = "mdm-signature"; public static final String PROXY_MUTUAL_AUTH_HEADER = "proxy-mutual-auth-header"; public static final String MUTUAL_AUTH_HEADER = "mutual-auth-header"; + public static final String ONE_TIME_TOKEN_HEADER = "one-time-token"; public static final String ENCODED_PEM = "encoded-pem"; public static final String CALLBACK_URL = ""; public static final String CLIENT_NAME = "IOT-API-MANAGER"; diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/services/SubscriptionManager.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/services/SubscriptionManager.java index 0382d33516..8ac4cf4b13 100644 --- a/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/services/SubscriptionManager.java +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/services/SubscriptionManager.java @@ -21,6 +21,7 @@ import org.wso2.carbon.device.application.mgt.common.ExecutionStatus; import org.wso2.carbon.device.application.mgt.common.dto.ScheduledSubscriptionDTO; import org.wso2.carbon.device.application.mgt.common.exception.ApplicationManagementException; import org.wso2.carbon.device.application.mgt.common.exception.SubscriptionManagementException; +import org.wso2.carbon.device.mgt.common.DeviceIdentifier; import org.wso2.carbon.device.mgt.common.PaginationResult; import java.util.List; @@ -101,6 +102,18 @@ public interface SubscriptionManager { void performEntAppSubscription(String applicationUUID, List params, String subType, String action, boolean requiresUpdatingExternal) throws ApplicationManagementException; + /** + * Install given application releases for given device. If application is already installed that application skips. + * This is used in enterprise app installing policy. + * + * @param deviceIdentifier Device identifiers + * @param releaseUUID UUIs of applicatios + * @throws ApplicationManagementException if error occurred while installing given applications into the given + * device + */ + void installAppsForDevice(DeviceIdentifier deviceIdentifier, List releaseUUID) + throws ApplicationManagementException; + /*** * This method used to get the app id ,device ids and pass them to DM service method. * diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/impl/ApplicationManagerImpl.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/impl/ApplicationManagerImpl.java index bad405cb38..1404c0c912 100644 --- a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/impl/ApplicationManagerImpl.java +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/impl/ApplicationManagerImpl.java @@ -2029,8 +2029,8 @@ public class ApplicationManagerImpl implements ApplicationManager { appUnrestrictedRoles = applicationUpdateWrapper.getUnrestrictedRoles(); } else { List addingRoleList = getDifference(applicationUpdateWrapper.getUnrestrictedRoles(), - applicationDTO.getUnrestrictedRoles()); - List removingRoleList = getDifference(applicationDTO.getUnrestrictedRoles(), + appUnrestrictedRoles); + List removingRoleList = getDifference(appUnrestrictedRoles, applicationUpdateWrapper.getUnrestrictedRoles()); if (!addingRoleList.isEmpty()) { visibilityDAO.addUnrestrictedRoles(addingRoleList, applicationId, tenantId); diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/impl/SubscriptionManagerImpl.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/impl/SubscriptionManagerImpl.java index dee1b7a6d1..47545d4c83 100644 --- a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/impl/SubscriptionManagerImpl.java +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/impl/SubscriptionManagerImpl.java @@ -94,6 +94,7 @@ import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Properties; +import java.util.concurrent.atomic.AtomicBoolean; import java.util.stream.Collectors; /** @@ -261,7 +262,7 @@ public class SubscriptionManagerImpl implements SubscriptionManager { log.error(msg, e); throw new SubscriptionManagementException(msg, e); } catch (DBConnectionException e) { - String msg = "Error occurred while retrieving the database connection"; + String msg = "Error occurred while retrieving the database connection to clean the scheduled subscriptions"; log.error(msg, e); throw new SubscriptionManagementException(msg, e); } finally { @@ -454,6 +455,70 @@ public class SubscriptionManagerImpl implements SubscriptionManager { } } + @Override public void installAppsForDevice(DeviceIdentifier deviceIdentifier, List releaseUUIDs) + throws ApplicationManagementException { + + int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(true); + Device device; + try { + device = DataHolder.getInstance().getDeviceManagementService().getDevice(deviceIdentifier, false); + if (device == null) { + String msg = "Invalid device identifier is received and couldn't find an deveice for the requested " + + "device identifier. Device UUID: " + deviceIdentifier.getId() + " Device Type: " + + deviceIdentifier.getType(); + log.error(msg); + throw new BadRequestException(msg); + } + } catch (DeviceManagementException e) { + String msg = "Error occured while getting device data for given device identifier.Device UUID: " + + deviceIdentifier.getId() + " Device Type: " + deviceIdentifier.getType(); + log.error(msg, e); + throw new ApplicationManagementException(msg, e); + } + + List appInstallingDevices = new ArrayList<>(); + + for (String releaseUUID : releaseUUIDs) { + try { + ConnectionManagerUtil.openDBConnection(); + ApplicationDTO applicationDTO = this.applicationDAO.getAppWithRelatedRelease(releaseUUID, tenantId); + if (applicationDTO != null) { + List deviceSubscriptionDTOS = this.subscriptionDAO + .getDeviceSubscriptions(applicationDTO.getApplicationReleaseDTOs().get(0).getId(), + tenantId); + AtomicBoolean isAppSubscribable = new AtomicBoolean(true); + for (DeviceSubscriptionDTO deviceSubscriptionDTO : deviceSubscriptionDTOS) { + if (device.getId() == deviceSubscriptionDTO.getDeviceId() && !deviceSubscriptionDTO + .isUnsubscribed()) { + isAppSubscribable.set(false); + break; + } + } + if (isAppSubscribable.get()) { + appInstallingDevices.add(deviceIdentifier); + } + } + } catch (DBConnectionException e) { + String msg = " Error occurred while getting DB connection to retrieve app data data from DB. Device " + + "UUID: " + deviceIdentifier.getId() + " Device Type: " + deviceIdentifier.getType(); + log.error(msg, e); + throw new ApplicationManagementException(msg, e); + } catch (ApplicationManagementDAOException e) { + String msg = " Error occurred while getting application data from DB. Device UUID: " + deviceIdentifier + .getId() + " Device Type: " + deviceIdentifier.getType(); + log.error(msg, e); + throw new ApplicationManagementException(msg, e); + } finally { + ConnectionManagerUtil.closeDBConnection(); + } + + if (!appInstallingDevices.isEmpty()) { + performBulkAppOperation(releaseUUID, appInstallingDevices, SubscriptionType.DEVICE.toString(), + SubAction.INSTALL.toString()); + } + } + } + /** * This method is responsible to update subscription data for google enterprise install. * @@ -584,13 +649,11 @@ public class SubscriptionManagerImpl implements SubscriptionManager { List identifiers; if (!deviceIdentifierMap.containsKey(identifier.getType())) { identifiers = new ArrayList<>(); - identifiers.add(identifier); - deviceIdentifierMap.put(identifier.getType(), identifiers); } else { identifiers = deviceIdentifierMap.get(identifier.getType()); - identifiers.add(identifier); - deviceIdentifierMap.put(identifier.getType(), identifiers); } + identifiers.add(identifier); + deviceIdentifierMap.put(identifier.getType(), identifiers); } for (Map.Entry> entry : deviceIdentifierMap.entrySet()) { Activity activity = addAppOperationOnDevices(applicationDTO, new ArrayList<>(entry.getValue()), diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/pom.xml b/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/pom.xml index 5ee7393cd1..d5af449477 100644 --- a/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/pom.xml +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/pom.xml @@ -66,7 +66,6 @@ generate-resources ${node.version} - ${npm.version} @@ -101,46 +100,6 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/.npmrc b/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/.npmrc new file mode 100644 index 0000000000..f7425e8e44 --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/.npmrc @@ -0,0 +1 @@ +registry=http://nexus.entgra.io/repository/npm-group/ diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/package.json b/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/package.json index df1743f096..49eae0fc0d 100644 --- a/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/package.json +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/package.json @@ -10,15 +10,17 @@ }, "license": "Apache License 2.0", "dependencies": { + "@ant-design/compatible": "^1.0.0", "@ant-design/dark-theme": "^0.2.2", "@ant-design/icons": "^4.0.6", "@babel/polyfill": "^7.6.0", "acorn": "^6.2.0", - "antd": "^3.23.6", + "antd": "^4.0.0", "axios": "^0.19.0", "babel-eslint": "^9.0.0", "d3": "^5.9.7", "dagre": "^0.8.4", + "entgra-icons-react": "^1.0.0", "eslint": "^5.16.0", "eslint-plugin-import": "^2.18.2", "eslint-plugin-jsx-a11y": "^6.2.3", @@ -58,6 +60,7 @@ "chai": "^4.1.2", "cross-env": "^7.0.0", "css-loader": "^0.28.11", + "entgra-icons": "^1.4.0", "eslint": "^5.16.0", "eslint-config-prettier": "4.3.0", "eslint-plugin-babel": "5.3.0", diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/public/conf/config.json b/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/public/conf/config.json index 93174ff827..de1726ce39 100644 --- a/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/public/conf/config.json +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/public/conf/config.json @@ -18,73 +18,69 @@ }, "defaultPlatformIcons": { "default": { - "icon": "global", - "color": "#535c68", - "theme": "outlined" + "icon": "fw-globe", + "color": "#535c68" }, "android": { - "icon": "android", - "color": "#7db343", - "theme": "filled" + "icon": "fw-android", + "color": "#7db343" }, "ios": { - "icon": "apple", - "color": "#535c68", - "theme": "filled" + "icon": "fw-apple", + "color": "#535c68" }, "windows": { - "icon": "windows", - "color": "#008cc4", - "theme": "filled" + "icon": "fw-windows", + "color": "#008cc4" } }, "lifecycle": { "CREATED": { "title": "Created", "text": "The initial most state of an application.\n You can only proceed to one of the following states:", - "icon": "file-text", + "icon": "fw-document", "step": 0 }, "IN-REVIEW": { "title": "In-Review", "text": "In this state the application is being reviewed by approvers. You can move from this state to APPROVED state if it is approved by reviewers. Otherwise, you can move the application into either REJECTED state or CREATED state based on the feedback getting by reviewers.", - "icon": "audit", + "icon": "fw-throttling-policy", "step": 1 }, "APPROVED": { "title": "Approved", "text": "The approved state is a compulsory state prior to publishing the application.\n You can only proceed to one of the following states:", - "icon": "file-done", + "icon": "fw-check", "step": 2 }, "PUBLISHED": { "title": "Published", "text": "The state which is applied for applications which are qualified for your Corporate App Store. Only the applications of Published state can be installed to your corporate devices.\n You can only proceed to one of the following states:", - "icon": "global", + "icon": "fw-globe", "step": 3 }, "BLOCKED": { "title": "Blocked", "text": "This state allows you to block your application either to publish or deprecate at a future date.\n You can only proceed to one of the following states:", - "icon": "exception", + "icon": "fw-lock", "step": 4 }, "DEPRECATED": { "title": "Deprecated", "text": "The applications which are outdated and no longer suit your app store.\n You can only proceed to one of the following states:", - "icon": "file-excel", + "icon": "fw-warning", "step": 5 }, "REJECTED": { "title": "Rejected", "text": "The Approvers can reject an application due to a faulty of the app or not being in compliance with company policies.\n You can only proceed to one of the following states:", - "icon": "frown", + "icon": "fw-error", "step": 6 }, "RETIRED": { "title": "Retired", "text": "The final state of an application, where no transition of states will be allowed after this.", - "icon": "rest", + "icon": "fw-delete", "step": 7 } }, diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/src/scenes/Home/components/Logout/index.js b/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/src/scenes/Home/components/Logout/index.js index 1d94718fd1..f41e654bcc 100644 --- a/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/src/scenes/Home/components/Logout/index.js +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/src/scenes/Home/components/Logout/index.js @@ -17,7 +17,8 @@ */ import React from 'react'; -import { notification, Menu, Icon } from 'antd'; +import { LogoutOutlined } from '@ant-design/icons'; +import { notification, Menu } from 'antd'; import axios from 'axios'; import { withConfigContext } from '../../../../components/ConfigContext'; @@ -70,7 +71,7 @@ class Logout extends React.Component { return ( - + Logout diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/src/scenes/Home/index.js b/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/src/scenes/Home/index.js index 983e74c07b..080ac912b6 100644 --- a/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/src/scenes/Home/index.js +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/src/scenes/Home/index.js @@ -17,7 +17,19 @@ */ import React from 'react'; -import { Layout, Menu, Icon, Drawer, Button } from 'antd'; + +import { + AndroidFilled, + AppstoreOutlined, + ControlOutlined, + PlusOutlined, + SettingOutlined, + UserOutlined, + MenuFoldOutlined, + MenuUnfoldOutlined, +} from '@ant-design/icons'; + +import { Layout, Menu, Drawer, Button } from 'antd'; import { Switch, Link } from 'react-router-dom'; import RouteWithSubRoutes from '../../components/RouteWithSubRoutes'; import { Redirect } from 'react-router'; @@ -81,7 +93,7 @@ class Dashboard extends React.Component { > - + Apps @@ -92,7 +104,7 @@ class Dashboard extends React.Component { - + Add New App } @@ -118,21 +130,20 @@ class Dashboard extends React.Component { - + Manage } > - General + General {this.config.androidEnterpriseToken != null && ( - Android - Enterprise + Android Enterprise )} @@ -142,7 +153,7 @@ class Dashboard extends React.Component { className="profile" title={ - + {this.config.username} } @@ -157,10 +168,11 @@ class Dashboard extends React.Component {
@@ -194,14 +206,14 @@ class Dashboard extends React.Component { > - + Apps - + Add New App } @@ -223,7 +235,7 @@ class Dashboard extends React.Component { - + Manage @@ -238,7 +250,7 @@ class Dashboard extends React.Component { - + } > diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/src/scenes/Home/scenes/AddNewApp/components/AddNewAppForm/components/NewAppDetailsForm/index.js b/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/src/scenes/Home/scenes/AddNewApp/components/AddNewAppForm/components/NewAppDetailsForm/index.js index 3be2c38fc6..4219e5fcd6 100644 --- a/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/src/scenes/Home/scenes/AddNewApp/components/AddNewAppForm/components/NewAppDetailsForm/index.js +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/src/scenes/Home/scenes/AddNewApp/components/AddNewAppForm/components/NewAppDetailsForm/index.js @@ -17,7 +17,9 @@ */ import React from 'react'; -import { Alert, Button, Col, Form, Input, Row, Select, Spin } from 'antd'; +import { Form } from '@ant-design/compatible'; +import '@ant-design/compatible/assets/index.css'; +import { Alert, Button, Col, Input, Row, Select, Spin } from 'antd'; import axios from 'axios'; import { withConfigContext } from '../../../../../../../../components/ConfigContext'; import { handleApiError } from '../../../../../../../../services/utils/errorHandler'; diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/src/scenes/Home/scenes/AddNewApp/components/AddNewAppForm/components/NewAppUploadForm/index.js b/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/src/scenes/Home/scenes/AddNewApp/components/AddNewAppForm/components/NewAppUploadForm/index.js index 1073adbd78..32368cb26a 100644 --- a/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/src/scenes/Home/scenes/AddNewApp/components/AddNewAppForm/components/NewAppUploadForm/index.js +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/src/scenes/Home/scenes/AddNewApp/components/AddNewAppForm/components/NewAppUploadForm/index.js @@ -17,11 +17,12 @@ */ import React from 'react'; +import { MinusOutlined, PlusOutlined, UploadOutlined } from '@ant-design/icons'; +import { Form } from '@ant-design/compatible'; +import '@ant-design/compatible/assets/index.css'; import { Button, Col, - Form, - Icon, Input, Row, Select, @@ -280,7 +281,7 @@ class NewAppUploadForm extends React.Component { } = this.state; const uploadButton = (
- +
Select
); @@ -315,7 +316,7 @@ class NewAppUploadForm extends React.Component { > {binaryFiles.length !== 1 && ( )} , @@ -577,7 +578,7 @@ class NewAppUploadForm extends React.Component { + + + + )} + {!isUnrestrictedRolesEditEnabled && ( + + {unrestrictedRoles.map(unrestrictedRole => { + return ( + + {unrestrictedRole} + + ); + })} + + )} + - } @@ -139,15 +140,13 @@ const columns = [ const defaultPlatformIcons = config.defaultPlatformIcons; let icon = defaultPlatformIcons.default.icon; let color = defaultPlatformIcons.default.color; - let theme = defaultPlatformIcons.default.theme; if (defaultPlatformIcons.hasOwnProperty(platform)) { icon = defaultPlatformIcons[platform].icon; color = defaultPlatformIcons[platform].color; - theme = defaultPlatformIcons[platform].theme; } return ( - + ); }, diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/src/scenes/Home/scenes/Apps/components/AppList/components/Filters/index.js b/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/src/scenes/Home/scenes/Apps/components/AppList/components/Filters/index.js index 8ddbb6e0c4..649f3f8dc6 100644 --- a/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/src/scenes/Home/scenes/Apps/components/AppList/components/Filters/index.js +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/src/scenes/Home/scenes/Apps/components/AppList/components/Filters/index.js @@ -17,16 +17,9 @@ */ import React from 'react'; -import { - Card, - Col, - Row, - Typography, - Divider, - Select, - Button, - Form, -} from 'antd'; +import { Form } from '@ant-design/compatible'; +import '@ant-design/compatible/assets/index.css'; +import { Card, Col, Row, Typography, Divider, Select, Button } from 'antd'; import axios from 'axios'; import { withConfigContext } from '../../../../../../../../components/ConfigContext'; import { handleApiError } from '../../../../../../../../services/utils/errorHandler'; @@ -196,7 +189,8 @@ class FiltersForm extends React.Component { permission="/permission/admin/app-mgt/publisher/application/update" yes={
- +

Categories:

+ {getFieldDecorator('categories', { rules: [ { @@ -221,7 +215,8 @@ class FiltersForm extends React.Component { , )} - +

Tags:

+ {getFieldDecorator('tags', { rules: [ { @@ -244,10 +239,11 @@ class FiltersForm extends React.Component {
} /> +

Device Type:

+ {getFieldDecorator('deviceType', { rules: [ { @@ -271,7 +267,8 @@ class FiltersForm extends React.Component { } /> - +

App Type:

+ {getFieldDecorator('appType', {})( } + prefix={} placeholder="Username" />, )} @@ -167,7 +168,7 @@ class NormalLoginForm extends React.Component { })( } + prefix={} type="password" placeholder="Password" />, diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.store.ui/pom.xml b/components/application-mgt/org.wso2.carbon.device.application.mgt.store.ui/pom.xml index 785056802b..5d7f53e162 100644 --- a/components/application-mgt/org.wso2.carbon.device.application.mgt.store.ui/pom.xml +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.store.ui/pom.xml @@ -69,7 +69,6 @@ generate-resources ${node.version} - ${npm.version} diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.store.ui/react-app/package.json b/components/application-mgt/org.wso2.carbon.device.application.mgt.store.ui/react-app/package.json index 56aa61b49b..91b0a4158b 100644 --- a/components/application-mgt/org.wso2.carbon.device.application.mgt.store.ui/react-app/package.json +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.store.ui/react-app/package.json @@ -11,7 +11,7 @@ "license": "Apache License 2.0", "dependencies": { "acorn": "^6.2.0", - "antd": "^3.23.6", + "antd": "^4.0.0", "axios": "^0.18.1", "babel-eslint": "^9.0.0", "d3": "^5.9.7", diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.store.ui/react-app/src/scenes/Home/components/Logout/index.js b/components/application-mgt/org.wso2.carbon.device.application.mgt.store.ui/react-app/src/scenes/Home/components/Logout/index.js index a11d1d029a..d2c5e106eb 100644 --- a/components/application-mgt/org.wso2.carbon.device.application.mgt.store.ui/react-app/src/scenes/Home/components/Logout/index.js +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.store.ui/react-app/src/scenes/Home/components/Logout/index.js @@ -17,7 +17,8 @@ */ import React from 'react'; -import { Menu, Icon } from 'antd'; +import { LogoutOutlined } from '@ant-design/icons'; +import { Menu } from 'antd'; import axios from 'axios'; import { withConfigContext } from '../../../../components/context/ConfigContext'; import { handleApiError } from '../../../../services/utils/errorHandler'; @@ -64,7 +65,7 @@ class Logout extends React.Component { return ( - + Logout diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.store.ui/react-app/src/scenes/Home/index.js b/components/application-mgt/org.wso2.carbon.device.application.mgt.store.ui/react-app/src/scenes/Home/index.js index b8582bbc3a..c5a8bf47fc 100644 --- a/components/application-mgt/org.wso2.carbon.device.application.mgt.store.ui/react-app/src/scenes/Home/index.js +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.store.ui/react-app/src/scenes/Home/index.js @@ -17,7 +17,17 @@ */ import React from 'react'; -import { Layout, Menu, Icon, Drawer, Button, Alert } from 'antd'; +import { + UploadOutlined, + UserOutlined, + AndroidFilled, + AppleFilled, + WindowsFilled, + HddFilled, + MenuFoldOutlined, + MenuUnfoldOutlined, +} from '@ant-design/icons'; +import { Layout, Menu, Drawer, Button, Alert } from 'antd'; const { Header, Content, Footer } = Layout; import { Link } from 'react-router-dom'; @@ -112,23 +122,27 @@ class Dashboard extends React.Component { }; render() { - const config = this.props.context; const { selectedKeys, deviceTypes, forbiddenErrors } = this.state; - const DeviceTypesData = deviceTypes.map(deviceType => { - const platform = deviceType.name; - const defaultPlatformIcons = config.defaultPlatformIcons; - let icon = defaultPlatformIcons.default.icon; - let theme = defaultPlatformIcons.default.theme; - if (defaultPlatformIcons.hasOwnProperty(platform)) { - icon = defaultPlatformIcons[platform].icon; - theme = defaultPlatformIcons[platform].theme; + let icon; + switch (deviceType.name) { + case 'android': + icon = ; + break; + case 'ios': + icon = ; + break; + case 'windows': + icon = ; + break; + default: + icon = ; } return ( - - - - {platform} + + + {icon} + {deviceType.name} ); @@ -161,7 +175,7 @@ class Dashboard extends React.Component { - + Web Clips @@ -170,7 +184,7 @@ class Dashboard extends React.Component { className="profile" title={ - + {this.config.user.username} } @@ -185,10 +199,11 @@ class Dashboard extends React.Component {
@@ -221,7 +236,7 @@ class Dashboard extends React.Component { - + Web Clips @@ -236,7 +251,7 @@ class Dashboard extends React.Component { - + } > diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.store.ui/react-app/src/scenes/Home/scenes/Apps/components/AppList/index.js b/components/application-mgt/org.wso2.carbon.device.application.mgt.store.ui/react-app/src/scenes/Home/scenes/Apps/components/AppList/index.js index 15f9e0d216..ab43ad7156 100644 --- a/components/application-mgt/org.wso2.carbon.device.application.mgt.store.ui/react-app/src/scenes/Home/scenes/Apps/components/AppList/index.js +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.store.ui/react-app/src/scenes/Home/scenes/Apps/components/AppList/index.js @@ -143,11 +143,13 @@ class AppList extends React.Component { > {apps.length === 0 && ( - + + + )} {apps.map(app => ( diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.store.ui/react-app/src/scenes/Home/scenes/Apps/scenes/Release/components/ReleasePage/components/ReleaseView/components/ReviewContainer/componets/CurrentUsersReview/components/AddReview/index.js b/components/application-mgt/org.wso2.carbon.device.application.mgt.store.ui/react-app/src/scenes/Home/scenes/Apps/scenes/Release/components/ReleasePage/components/ReleaseView/components/ReviewContainer/componets/CurrentUsersReview/components/AddReview/index.js index 7a972a9f15..af24e7dbf5 100644 --- a/components/application-mgt/org.wso2.carbon.device.application.mgt.store.ui/react-app/src/scenes/Home/scenes/Apps/scenes/Release/components/ReleasePage/components/ReleaseView/components/ReviewContainer/componets/CurrentUsersReview/components/AddReview/index.js +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.store.ui/react-app/src/scenes/Home/scenes/Apps/scenes/Release/components/ReleasePage/components/ReleaseView/components/ReviewContainer/componets/CurrentUsersReview/components/AddReview/index.js @@ -17,10 +17,10 @@ */ import React from 'react'; +import { StarOutlined } from '@ant-design/icons'; import { Drawer, Button, - Icon, Row, Col, Typography, @@ -127,7 +127,7 @@ class AddReview extends React.Component { return (

- {totalCount} total + {totalCount} total
diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.store.ui/react-app/src/scenes/Home/scenes/Apps/scenes/Release/components/ReleasePage/components/ReleaseView/components/ReviewContainer/componets/Reviews/components/Review/index.js b/components/application-mgt/org.wso2.carbon.device.application.mgt.store.ui/react-app/src/scenes/Home/scenes/Apps/scenes/Release/components/ReleasePage/components/ReleaseView/components/ReviewContainer/componets/Reviews/components/Review/index.js index 3dac70cf55..2d3ec681d9 100644 --- a/components/application-mgt/org.wso2.carbon.device.application.mgt.store.ui/react-app/src/scenes/Home/scenes/Apps/scenes/Release/components/ReleasePage/components/ReleaseView/components/ReviewContainer/componets/Reviews/components/Review/index.js +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.store.ui/react-app/src/scenes/Home/scenes/Apps/scenes/Release/components/ReleasePage/components/ReleaseView/components/ReviewContainer/componets/Reviews/components/Review/index.js @@ -170,7 +170,7 @@ class Review extends React.Component { ); return ( -
+
-
diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.store.ui/react-app/src/scenes/Home/scenes/Apps/scenes/Release/components/ReleasePage/components/ReleaseView/index.js b/components/application-mgt/org.wso2.carbon.device.application.mgt.store.ui/react-app/src/scenes/Home/scenes/Apps/scenes/Release/components/ReleasePage/components/ReleaseView/index.js index fcdafd7551..fa6307d6b0 100644 --- a/components/application-mgt/org.wso2.carbon.device.application.mgt.store.ui/react-app/src/scenes/Home/scenes/Apps/scenes/Release/components/ReleasePage/components/ReleaseView/index.js +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.store.ui/react-app/src/scenes/Home/scenes/Apps/scenes/Release/components/ReleasePage/components/ReleaseView/index.js @@ -17,6 +17,7 @@ */ import React from 'react'; +import { DownOutlined } from '@ant-design/icons'; import { Divider, Row, @@ -26,7 +27,6 @@ import { Dropdown, notification, Menu, - Icon, Tabs, Tag, } from 'antd'; @@ -216,13 +216,13 @@ class ReleaseView extends React.Component { yes={ } no={ } /> diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.store.ui/react-app/src/scenes/Home/scenes/Apps/scenes/Release/components/ReleasePage/index.js b/components/application-mgt/org.wso2.carbon.device.application.mgt.store.ui/react-app/src/scenes/Home/scenes/Apps/scenes/Release/components/ReleasePage/index.js index 7c8b168386..787236598e 100644 --- a/components/application-mgt/org.wso2.carbon.device.application.mgt.store.ui/react-app/src/scenes/Home/scenes/Apps/scenes/Release/components/ReleasePage/index.js +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.store.ui/react-app/src/scenes/Home/scenes/Apps/scenes/Release/components/ReleasePage/index.js @@ -18,7 +18,8 @@ import React from 'react'; import '../../../../../../../../App.css'; -import { Skeleton, Typography, Row, Col, Card, Breadcrumb, Icon } from 'antd'; +import { HomeOutlined } from '@ant-design/icons'; +import { Skeleton, Typography, Row, Col, Card, Breadcrumb } from 'antd'; import ReleaseView from './components/ReleaseView'; import axios from 'axios'; import { withConfigContext } from '../../../../../../../../components/context/ConfigContext'; @@ -110,7 +111,7 @@ class ReleasePage extends React.Component { - {deviceType + ' apps'}{' '} + {deviceType + ' apps'}{' '} {appName} diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.store.ui/react-app/src/scenes/Login/index.js b/components/application-mgt/org.wso2.carbon.device.application.mgt.store.ui/react-app/src/scenes/Login/index.js index b6e9b2ad49..3d0f11d4a8 100644 --- a/components/application-mgt/org.wso2.carbon.device.application.mgt.store.ui/react-app/src/scenes/Login/index.js +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.store.ui/react-app/src/scenes/Login/index.js @@ -17,14 +17,14 @@ */ import React from 'react'; +import { LockOutlined, UserOutlined } from '@ant-design/icons'; import { Typography, Row, Col, - Form, - Icon, Input, Button, + Form, Checkbox, notification, } from 'antd'; @@ -36,6 +36,62 @@ const { Title } = Typography; const { Text } = Typography; class Login extends React.Component { + constructor(props) { + super(props); + this.state = { + inValid: false, + loading: false, + }; + } + + handleSubmit = values => { + this.setState({ + loading: true, + inValid: false, + }); + const parameters = { + username: values.username, + password: values.password, + platform: 'store', + }; + + const request = Object.keys(parameters) + .map(key => key + '=' + parameters[key]) + .join('&'); + + axios + .post(window.location.origin + '/store-ui-request-handler/login', request) + .then(res => { + if (res.status === 200) { + let redirectUrl = window.location.origin + '/store'; + const searchParams = new URLSearchParams(window.location.search); + if (searchParams.has('redirect')) { + redirectUrl = searchParams.get('redirect'); + } + window.location = redirectUrl; + } else { + throw new Error(); + } + }) + .catch(error => { + if (error.hasOwnProperty('response') && error.response.status === 401) { + this.setState({ + loading: false, + inValid: true, + }); + } else { + notification.error({ + message: 'There was a problem', + duration: 10, + description: '', + }); + this.setState({ + loading: false, + inValid: false, + }); + } + }); + }; render() { const config = this.props.context; return ( @@ -46,7 +102,13 @@ class Login extends React.Component { - + Login - +
+ + + } + placeholder="Username" + /> + + + + } + placeholder="Password" + /> + + {this.state.loading && Loading..} + {this.state.inValid && ( + Invalid Login Details + )} +
+ Forgot password + + Remember me + + + + +
@@ -69,140 +182,4 @@ class Login extends React.Component { } } -class NormalLoginForm extends React.Component { - constructor(props) { - super(props); - this.state = { - inValid: false, - loading: false, - }; - } - - handleSubmit = e => { - const thisForm = this; - const config = this.props.context; - - e.preventDefault(); - this.props.form.validateFields((err, values) => { - thisForm.setState({ - inValid: false, - }); - if (!err) { - thisForm.setState({ - loading: true, - }); - const parameters = { - username: values.username, - password: values.password, - platform: 'store', - }; - - const request = Object.keys(parameters) - .map(key => key + '=' + parameters[key]) - .join('&'); - - axios - .post(window.location.origin + config.serverConfig.loginUri, request) - .then(res => { - if (res.status === 200) { - let redirectUrl = window.location.origin + '/store'; - const searchParams = new URLSearchParams(window.location.search); - if (searchParams.has('redirect')) { - redirectUrl = searchParams.get('redirect'); - } - window.location = redirectUrl; - } - }) - .catch(function(error) { - if ( - error.hasOwnProperty('response') && - error.response.status === 401 - ) { - thisForm.setState({ - loading: false, - inValid: true, - }); - } else { - notification.error({ - message: 'There was a problem', - duration: 10, - description: '', - }); - thisForm.setState({ - loading: false, - inValid: false, - }); - } - }); - } - }); - }; - - render() { - const { getFieldDecorator } = this.props.form; - let errorMsg = ''; - if (this.state.inValid) { - errorMsg = Invalid Login Details; - } - let loading = ''; - if (this.state.loading) { - loading = Loading..; - } - return ( -
- - {getFieldDecorator('username', { - rules: [{ required: true, message: 'Please input your username!' }], - })( - } - placeholder="Username" - />, - )} - - - {getFieldDecorator('password', { - rules: [{ required: true, message: 'Please input your Password!' }], - })( - } - type="password" - placeholder="Password" - />, - )} - - {loading} - {errorMsg} - - {getFieldDecorator('remember', { - valuePropName: 'checked', - initialValue: true, - })(Remember me)} -
- - Forgot password - - -
-
- ); - } -} - -const WrappedNormalLoginForm = withConfigContext( - Form.create({ name: 'normal_login' })(NormalLoginForm), -); - export default withConfigContext(Login); diff --git a/components/device-mgt/io.entgra.carbon.device.mgt.config.api/pom.xml b/components/device-mgt/io.entgra.carbon.device.mgt.config.api/pom.xml index 8ffc22a4ec..fe1ff78a87 100644 --- a/components/device-mgt/io.entgra.carbon.device.mgt.config.api/pom.xml +++ b/components/device-mgt/io.entgra.carbon.device.mgt.config.api/pom.xml @@ -273,5 +273,9 @@ + + org.wso2.carbon.multitenancy + org.wso2.carbon.tenant.mgt + diff --git a/components/device-mgt/io.entgra.carbon.device.mgt.config.api/src/main/webapp/WEB-INF/web.xml b/components/device-mgt/io.entgra.carbon.device.mgt.config.api/src/main/webapp/WEB-INF/web.xml index 6b397c9fbe..aafbcec0e0 100644 --- a/components/device-mgt/io.entgra.carbon.device.mgt.config.api/src/main/webapp/WEB-INF/web.xml +++ b/components/device-mgt/io.entgra.carbon.device.mgt.config.api/src/main/webapp/WEB-INF/web.xml @@ -124,4 +124,4 @@ /* - \ No newline at end of file + diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/api/DeviceManagementService.java b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/api/DeviceManagementService.java index 02ded254df..60799bf5a2 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/api/DeviceManagementService.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/api/DeviceManagementService.java @@ -2273,4 +2273,58 @@ public interface DeviceManagementService { response = ErrorResponse.class) }) Response getDeviceFilters(); + + @GET + @Produces(MediaType.APPLICATION_JSON) + @Path("/{clientId}/{clientSecret}/default-token") + @ApiOperation( + produces = MediaType.APPLICATION_JSON, + httpMethod = "GET", + value = "Getting the default token", + notes = "Getting the default access token by using given client ID and the client secret value.", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = Constants.SCOPE, value = "perm:device:enroll") + }) + } + ) + @ApiResponses( + value = { + @ApiResponse( + code = 200, + message = "OK. \n Successfully returned the default token details.", + response = Policy.class, + responseHeaders = { + @ResponseHeader( + name = "Content-Type", + description = "The 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 = 500, + message = "Internal Server Error. \n " + + "Server error occurred while retrieving the default token.", + response = ErrorResponse.class) + } + ) + Response getDefaultToken( + @ApiParam( + name = "client ID", + value = "Client Id.", + required = true) + @PathParam("clientId") + String clientId, + @ApiParam( + name = "client secret", + value = "Client Secret", + required = true) + @PathParam("clientSecret") + String clientSecret + ); } 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 397c35b336..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 @@ -35,7 +35,6 @@ package org.wso2.carbon.device.mgt.jaxrs.service.api; import com.google.gson.JsonArray; -import com.google.gson.JsonObject; import io.swagger.annotations.SwaggerDefinition; import io.swagger.annotations.Info; import io.swagger.annotations.ExtensionProperty; @@ -50,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; @@ -75,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( @@ -894,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/DeviceAgentServiceImpl.java b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/DeviceAgentServiceImpl.java index ca034edec3..f759ed13a9 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/DeviceAgentServiceImpl.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/DeviceAgentServiceImpl.java @@ -36,6 +36,7 @@ import org.wso2.carbon.device.mgt.common.exceptions.DeviceManagementException; import org.wso2.carbon.device.mgt.common.exceptions.InvalidConfigurationException; 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.common.policy.mgt.Policy; import org.wso2.carbon.device.mgt.common.policy.mgt.monitor.ComplianceFeature; import org.wso2.carbon.device.mgt.common.policy.mgt.monitor.PolicyComplianceException; import org.wso2.carbon.device.mgt.core.service.DeviceManagementProviderService; @@ -50,6 +51,9 @@ import org.wso2.carbon.event.stream.stub.EventStreamAdminServiceStub; import org.wso2.carbon.event.stream.stub.types.EventStreamAttributeDto; import org.wso2.carbon.event.stream.stub.types.EventStreamDefinitionDto; import org.wso2.carbon.identity.jwt.client.extension.exception.JWTClientException; +import org.wso2.carbon.policy.mgt.common.PolicyAdministratorPoint; +import org.wso2.carbon.policy.mgt.common.PolicyEvaluationException; +import org.wso2.carbon.policy.mgt.common.PolicyManagementException; import org.wso2.carbon.user.api.UserStoreException; import javax.validation.Valid; @@ -95,6 +99,10 @@ public class DeviceAgentServiceImpl implements DeviceAgentService { device.getEnrolmentInfo().setDateOfEnrolment(System.currentTimeMillis()); device.getEnrolmentInfo().setDateOfLastUpdate(System.currentTimeMillis()); boolean status = dms.enrollDevice(device); + PolicyAdministratorPoint pap = DeviceMgtAPIUtils.getPolicyManagementService().getPAP(); + DeviceIdentifier deviceId = new DeviceIdentifier(device.getDeviceIdentifier(), device.getType()); + DeviceMgtAPIUtils.getPolicyManagementService().getEffectivePolicy(deviceId); + pap.publishChanges(); return Response.status(Response.Status.OK).entity(status).build(); } catch (DeviceManagementException e) { String msg = "Error occurred while enrolling the device, which carries the id '" + @@ -104,6 +112,9 @@ public class DeviceAgentServiceImpl implements DeviceAgentService { } catch (InvalidConfigurationException e) { log.error("failed to add operation", e); return Response.status(Response.Status.INTERNAL_SERVER_ERROR).build(); + } catch (PolicyManagementException e) { + log.error("failed to add designated policies against newly enrolled device.", e); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).build(); } } diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/DeviceManagementServiceImpl.java b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/DeviceManagementServiceImpl.java index 3600ffb3ab..73a07b7aad 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/DeviceManagementServiceImpl.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/DeviceManagementServiceImpl.java @@ -38,11 +38,13 @@ package org.wso2.carbon.device.mgt.jaxrs.service.impl; import java.util.LinkedList; import java.util.Queue; + import org.apache.commons.httpclient.HttpStatus; import org.apache.commons.lang.StringUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.wso2.carbon.context.CarbonContext; +import org.wso2.carbon.context.PrivilegedCarbonContext; import org.wso2.carbon.device.mgt.common.Device; import org.wso2.carbon.device.mgt.common.DeviceFilters; import org.wso2.carbon.device.mgt.common.DeviceIdentifier; @@ -102,6 +104,10 @@ import org.wso2.carbon.device.mgt.jaxrs.service.api.DeviceManagementService; import org.wso2.carbon.device.mgt.jaxrs.service.impl.util.InputValidationException; import org.wso2.carbon.device.mgt.jaxrs.service.impl.util.RequestValidationUtil; import org.wso2.carbon.device.mgt.jaxrs.util.DeviceMgtAPIUtils; +import org.wso2.carbon.identity.jwt.client.extension.JWTClient; +import org.wso2.carbon.identity.jwt.client.extension.dto.AccessTokenInfo; +import org.wso2.carbon.identity.jwt.client.extension.exception.JWTClientException; +import org.wso2.carbon.identity.jwt.client.extension.service.JWTClientManagerService; import org.wso2.carbon.policy.mgt.common.PolicyManagementException; import org.wso2.carbon.policy.mgt.core.PolicyManagerService; import org.wso2.carbon.user.api.UserStoreException; @@ -1282,6 +1288,10 @@ public class DeviceManagementServiceImpl implements DeviceManagementService { operation.setId(operationStatusBean.getOperationId()); DeviceMgtAPIUtils.getDeviceManagementService().updateOperation(device, operation); return Response.status(Response.Status.OK).entity("OperationStatus updated successfully.").build(); + } catch (BadRequestException e) { + String msg = "Error occured due to invalid request"; + log.error(msg, e); + return Response.status(Response.Status.BAD_REQUEST).entity(msg).build(); } catch (DeviceManagementException e) { String msg = "Error occurred when fetching device " + deviceIdentifier.toString(); log.error(msg, e); @@ -1290,10 +1300,6 @@ public class DeviceManagementServiceImpl implements DeviceManagementService { String msg = "Error occurred when updating operation of device " + deviceIdentifier; log.error(msg, e); return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build(); - } catch (BadRequestException e) { - String msg = "Error occured due to invalid request"; - log.error(msg, e); - return Response.status(Response.Status.BAD_REQUEST).entity(msg).build(); } } @@ -1328,4 +1334,21 @@ public class DeviceManagementServiceImpl implements DeviceManagementService { return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build(); } } + + @GET + @Path("/{clientId}/{clientSecret}/default-token") + @Override + public Response getDefaultToken(@PathParam("clientId") String clientId, @PathParam("clientSecret") String clientSecret) { + JWTClientManagerService jwtClientManagerService = DeviceMgtAPIUtils.getJWTClientManagerService(); + try { + JWTClient jwtClient = jwtClientManagerService.getJWTClient(); + AccessTokenInfo accessTokenInfo = jwtClient.getAccessToken(clientId, clientSecret, + PrivilegedCarbonContext.getThreadLocalCarbonContext().getUsername(), "default"); + return Response.status(Response.Status.OK).entity(accessTokenInfo).build(); + } catch (JWTClientException e) { + String msg = "Error occurred while getting default access token by using given client Id and client secret."; + log.error(msg, e); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build(); + } + } } diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/GroupManagementServiceImpl.java b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/GroupManagementServiceImpl.java index 3b10b8681d..0502f37ab3 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/GroupManagementServiceImpl.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/GroupManagementServiceImpl.java @@ -25,15 +25,19 @@ import org.wso2.carbon.CarbonConstants; 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.exceptions.DeviceNotFoundException; +import org.wso2.carbon.device.mgt.common.EnrolmentInfo; import org.wso2.carbon.device.mgt.common.GroupPaginationRequest; import org.wso2.carbon.device.mgt.common.PaginationResult; +import org.wso2.carbon.device.mgt.common.exceptions.DeviceManagementException; +import org.wso2.carbon.device.mgt.common.exceptions.DeviceNotFoundException; import org.wso2.carbon.device.mgt.common.group.mgt.DeviceGroup; import org.wso2.carbon.device.mgt.common.group.mgt.DeviceGroupConstants; import org.wso2.carbon.device.mgt.common.group.mgt.GroupAlreadyExistException; import org.wso2.carbon.device.mgt.common.group.mgt.GroupManagementException; -import org.wso2.carbon.device.mgt.common.group.mgt.RoleDoesNotExistException; import org.wso2.carbon.device.mgt.common.group.mgt.GroupNotExistException; +import org.wso2.carbon.device.mgt.common.group.mgt.RoleDoesNotExistException; +import org.wso2.carbon.device.mgt.common.policy.mgt.Policy; +import org.wso2.carbon.device.mgt.core.service.DeviceManagementProviderService; import org.wso2.carbon.device.mgt.core.service.GroupManagementProviderService; import org.wso2.carbon.device.mgt.jaxrs.beans.DeviceGroupList; import org.wso2.carbon.device.mgt.jaxrs.beans.DeviceList; @@ -42,6 +46,10 @@ import org.wso2.carbon.device.mgt.jaxrs.beans.RoleList; import org.wso2.carbon.device.mgt.jaxrs.service.api.GroupManagementService; import org.wso2.carbon.device.mgt.jaxrs.service.impl.util.RequestValidationUtil; import org.wso2.carbon.device.mgt.jaxrs.util.DeviceMgtAPIUtils; +import org.wso2.carbon.policy.mgt.common.PolicyAdministratorPoint; +import org.wso2.carbon.policy.mgt.common.PolicyEvaluationException; +import org.wso2.carbon.policy.mgt.common.PolicyEvaluationPoint; +import org.wso2.carbon.policy.mgt.common.PolicyManagementException; import javax.ws.rs.core.Response; import java.util.ArrayList; @@ -259,6 +267,16 @@ public class GroupManagementServiceImpl implements GroupManagementService { public Response addDevicesToGroup(int groupId, List deviceIdentifiers) { try { DeviceMgtAPIUtils.getGroupManagementProviderService().addDevices(groupId, deviceIdentifiers); + PolicyAdministratorPoint pap = DeviceMgtAPIUtils.getPolicyManagementService().getPAP(); + DeviceManagementProviderService dms = DeviceMgtAPIUtils.getDeviceManagementService(); + for(DeviceIdentifier deviceIdentifier : deviceIdentifiers) { + Device device = dms.getDevice(deviceIdentifier, false); + if(!device.getEnrolmentInfo().getStatus().equals(EnrolmentInfo.Status.REMOVED)) { + pap.removePolicyUsed(deviceIdentifier); + DeviceMgtAPIUtils.getPolicyManagementService().getEffectivePolicy(deviceIdentifier); + } + } + pap.publishChanges(); return Response.status(Response.Status.OK).build(); } catch (GroupManagementException e) { String msg = "Error occurred while adding devices to group."; @@ -266,6 +284,15 @@ public class GroupManagementServiceImpl implements GroupManagementService { return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build(); } catch (DeviceNotFoundException e) { return Response.status(Response.Status.BAD_REQUEST).entity(e.getMessage()).build(); + } catch (PolicyManagementException e) { + log.error("Error occurred while adding policies against device(s).", e); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).build(); +// } catch (PolicyEvaluationException e) { +// log.error("Error occurred while retrieving policies against device(s).", e); +// return Response.status(Response.Status.INTERNAL_SERVER_ERROR).build(); + } catch (DeviceManagementException e) { + log.error("Error occurred while retrieving device information.", e); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).build(); } } @@ -273,6 +300,16 @@ public class GroupManagementServiceImpl implements GroupManagementService { public Response removeDevicesFromGroup(int groupId, List deviceIdentifiers) { try { DeviceMgtAPIUtils.getGroupManagementProviderService().removeDevice(groupId, deviceIdentifiers); + PolicyAdministratorPoint pap = DeviceMgtAPIUtils.getPolicyManagementService().getPAP(); + DeviceManagementProviderService dms = DeviceMgtAPIUtils.getDeviceManagementService(); + for(DeviceIdentifier deviceIdentifier : deviceIdentifiers) { + Device device = dms.getDevice(deviceIdentifier, false); + if(!device.getEnrolmentInfo().getStatus().equals(EnrolmentInfo.Status.REMOVED)) { + pap.removePolicyUsed(deviceIdentifier); + DeviceMgtAPIUtils.getPolicyManagementService().getEffectivePolicy(deviceIdentifier); + } + } + pap.publishChanges(); return Response.status(Response.Status.OK).build(); } catch (GroupManagementException e) { String msg = "Error occurred while removing devices from group."; @@ -280,6 +317,12 @@ public class GroupManagementServiceImpl implements GroupManagementService { return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build(); } catch (DeviceNotFoundException e) { return Response.status(Response.Status.BAD_REQUEST).entity(e.getMessage()).build(); + }catch (PolicyManagementException e) { + log.error("Error occurred while adding policies against device(s).", e); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).build(); + }catch (DeviceManagementException e) { + log.error("Error occurred while retrieving device information.", e); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).build(); } } @@ -290,6 +333,8 @@ public class GroupManagementServiceImpl implements GroupManagementService { deviceIdentifiers.add(deviceToGroupsAssignment.getDeviceIdentifier()); GroupManagementProviderService service = DeviceMgtAPIUtils.getGroupManagementProviderService(); List deviceGroups = service.getGroups(deviceToGroupsAssignment.getDeviceIdentifier(), false); + PolicyAdministratorPoint pap = DeviceMgtAPIUtils.getPolicyManagementService().getPAP(); + DeviceManagementProviderService dms = DeviceMgtAPIUtils.getDeviceManagementService(); for (DeviceGroup group : deviceGroups) { Integer groupId = group.getGroupId(); if (deviceToGroupsAssignment.getDeviceGroupIds().contains(groupId)) { @@ -300,7 +345,12 @@ public class GroupManagementServiceImpl implements GroupManagementService { } for (int groupId : deviceToGroupsAssignment.getDeviceGroupIds()) { DeviceMgtAPIUtils.getGroupManagementProviderService().addDevices(groupId, deviceIdentifiers); + for (DeviceIdentifier deviceIdentifier : deviceIdentifiers) { + pap.removePolicyUsed(deviceIdentifier); + DeviceMgtAPIUtils.getPolicyManagementService().getEffectivePolicy(deviceIdentifier); + } } + pap.publishChanges(); return Response.status(Response.Status.OK).build(); } catch (GroupManagementException e) { String msg = "Error occurred while assigning device to groups."; @@ -308,6 +358,9 @@ public class GroupManagementServiceImpl implements GroupManagementService { return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build(); } catch (DeviceNotFoundException e) { return Response.status(Response.Status.BAD_REQUEST).entity(e.getMessage()).build(); + } catch (PolicyManagementException e) { + log.error("Failed to add policies for device assigned to group.", e); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).build(); } } @@ -325,4 +378,4 @@ public class GroupManagementServiceImpl implements GroupManagementService { } } -} \ No newline at end of file +} diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/NotificationManagementServiceImpl.java b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/NotificationManagementServiceImpl.java index 3a7023796e..f5d8c7724f 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/NotificationManagementServiceImpl.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/NotificationManagementServiceImpl.java @@ -32,7 +32,14 @@ import org.wso2.carbon.device.mgt.jaxrs.service.impl.util.RequestValidationUtil; import org.wso2.carbon.device.mgt.jaxrs.util.DeviceMgtAPIUtils; import javax.validation.constraints.Size; -import javax.ws.rs.*; +import javax.ws.rs.Consumes; +import javax.ws.rs.GET; +import javax.ws.rs.HeaderParam; +import javax.ws.rs.PUT; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; +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; 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) { - if (log.isDebugEnabled()) { - log.debug("Sending enrollment invitation mail to existing user."); + 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()); } - DeviceManagementProviderService dms = DeviceMgtAPIUtils.getDeviceManagementService(); + if (log.isDebugEnabled()) { + log.debug("Sending device enrollment invitation mail to existing user/s."); + } + 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 31b9543d08..56f2a76e36 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; @@ -52,6 +69,7 @@ import org.wso2.carbon.device.mgt.common.operation.mgt.Operation; import org.wso2.carbon.device.mgt.common.permission.mgt.PermissionManagerService; import org.wso2.carbon.device.mgt.common.report.mgt.ReportManagementService; import org.wso2.carbon.device.mgt.common.spi.DeviceTypeGeneratorService; +import org.wso2.carbon.device.mgt.common.spi.OTPManagementService; import org.wso2.carbon.device.mgt.core.app.mgt.ApplicationManagementProviderService; import org.wso2.carbon.device.mgt.core.device.details.mgt.DeviceInformationManager; import org.wso2.carbon.device.mgt.core.dto.DeviceTypeVersion; @@ -134,13 +152,14 @@ public class DeviceMgtAPIUtils { public static final String DAS_ADMIN_SERVICE_EP = "https://" + DAS_HOST_NAME + ":" + DAS_PORT + "/services/"; private static SSLContext sslContext; - private static Log log = LogFactory.getLog(DeviceMgtAPIUtils.class); + private static final Log log = LogFactory.getLog(DeviceMgtAPIUtils.class); private static KeyStore keyStore; private static KeyStore trustStore; private static char[] keyStorePassword; private static IntegrationClientService integrationClientService; private static MetadataManagementService metadataManagementService; + private static OTPManagementService otpManagementService; static { String keyStorePassword = ServerConfiguration.getInstance().getFirstProperty("Security.KeyStore.Password"); @@ -337,6 +356,25 @@ 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) { + 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.api/src/test/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/DeviceAgentServiceTest.java b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/test/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/DeviceAgentServiceTest.java index c1aa2d41bf..729b1827cd 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/test/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/DeviceAgentServiceTest.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/test/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/DeviceAgentServiceTest.java @@ -93,6 +93,7 @@ public class DeviceAgentServiceTest { private static final String AUTHENTICATED_USER = "admin"; private static final String MONITOR_OPERATION = "POLICY_MONITOR"; private static Device demoDevice; + private PolicyManagerService policyManagerService; @ObjectFactory public IObjectFactory getObjectFactory() { @@ -108,6 +109,7 @@ public class DeviceAgentServiceTest { this.deviceAgentService = new DeviceAgentServiceImpl(); this.deviceAccessAuthorizationService = Mockito.mock(DeviceAccessAuthorizationServiceImpl.class, Mockito.RETURNS_MOCKS); + this.policyManagerService = Mockito.mock(PolicyManagerService.class, Mockito.RETURNS_MOCKS); this.privilegedCarbonContext = Mockito.mock(PrivilegedCarbonContext.class, Mockito.RETURNS_MOCKS); this.eventStreamAdminServiceStub = Mockito.mock(EventStreamAdminServiceStub.class, Mockito.RETURNS_MOCKS); demoDevice = DeviceMgtAPITestHelper.generateDummyDevice(TEST_DEVICE_TYPE, TEST_DEVICE_IDENTIFIER); @@ -167,6 +169,8 @@ public class DeviceAgentServiceTest { .toReturn(this.deviceManagementProviderService); PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getAuthenticatedUser")) .toReturn(AUTHENTICATED_USER); + PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getPolicyManagementService")) + .toReturn(policyManagerService); EnrolmentInfo enrolmentInfo = demoDevice.getEnrolmentInfo(); enrolmentInfo.setStatus(EnrolmentInfo.Status.INACTIVE); demoDevice.setEnrolmentInfo(enrolmentInfo); diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/test/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/GroupManagementServiceImplTest.java b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/test/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/GroupManagementServiceImplTest.java index d1bcbb27eb..20136b172d 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/test/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/GroupManagementServiceImplTest.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/test/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/GroupManagementServiceImplTest.java @@ -19,6 +19,7 @@ package org.wso2.carbon.device.mgt.jaxrs.service.impl; +import org.mockito.Mock; import org.mockito.Mockito; import org.powermock.api.mockito.PowerMockito; import org.powermock.core.classloader.annotations.PowerMockIgnore; @@ -42,10 +43,12 @@ import org.wso2.carbon.device.mgt.common.group.mgt.GroupAlreadyExistException; import org.wso2.carbon.device.mgt.common.group.mgt.GroupManagementException; import org.wso2.carbon.device.mgt.common.group.mgt.GroupNotExistException; import org.wso2.carbon.device.mgt.common.group.mgt.RoleDoesNotExistException; +import org.wso2.carbon.device.mgt.core.service.DeviceManagementProviderService; import org.wso2.carbon.device.mgt.core.service.GroupManagementProviderService; import org.wso2.carbon.device.mgt.jaxrs.beans.DeviceToGroupsAssignment; import org.wso2.carbon.device.mgt.jaxrs.service.api.GroupManagementService; import org.wso2.carbon.device.mgt.jaxrs.util.DeviceMgtAPIUtils; +import org.wso2.carbon.policy.mgt.core.PolicyManagerService; import javax.ws.rs.core.Response; import java.util.ArrayList; @@ -61,6 +64,8 @@ import java.util.List; public class GroupManagementServiceImplTest { private GroupManagementService groupManagementService; private GroupManagementProviderService groupManagementProviderService; + private PolicyManagerService policyManagerService; + private DeviceManagementProviderService deviceManagementProviderService; private PrivilegedCarbonContext context; @ObjectFactory @@ -72,6 +77,8 @@ public class GroupManagementServiceImplTest { public void init() { groupManagementService = new GroupManagementServiceImpl(); groupManagementProviderService = Mockito.mock(GroupManagementProviderService.class); + this.policyManagerService = Mockito.mock(PolicyManagerService.class, Mockito.RETURNS_MOCKS); + this.deviceManagementProviderService = Mockito.mock(DeviceManagementProviderService.class, Mockito.RETURNS_MOCKS); context = Mockito.mock(PrivilegedCarbonContext.class); Mockito.doReturn("admin").when(context).getUsername(); } @@ -298,6 +305,10 @@ public class GroupManagementServiceImplTest { public void testAddDevicesToGroup() throws GroupManagementException, DeviceNotFoundException { PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getGroupManagementProviderService")) .toReturn(groupManagementProviderService); + PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getPolicyManagementService")) + .toReturn(policyManagerService); + PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getDeviceManagementService")) + .toReturn(deviceManagementProviderService); List deviceIdentifiers = new ArrayList<>(); Mockito.doNothing().when(groupManagementProviderService).addDevices(1, deviceIdentifiers); Mockito.doThrow(new GroupManagementException()).when(groupManagementProviderService).addDevices(2, @@ -319,6 +330,10 @@ public class GroupManagementServiceImplTest { public void testRemoveDevicesFromGroup() throws GroupManagementException, DeviceNotFoundException { PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getGroupManagementProviderService")) .toReturn(groupManagementProviderService); + PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getPolicyManagementService")) + .toReturn(policyManagerService); + PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getDeviceManagementService")) + .toReturn(deviceManagementProviderService); List deviceIdentifiers = new ArrayList<>(); Mockito.doNothing().when(groupManagementProviderService).removeDevice(1, deviceIdentifiers); Mockito.doThrow(new GroupManagementException()).when(groupManagementProviderService).removeDevice(2, @@ -357,6 +372,10 @@ public class GroupManagementServiceImplTest { public void testUpdateDeviceAssigningToGroups() throws GroupManagementException, DeviceNotFoundException { PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getGroupManagementProviderService")) .toReturn(groupManagementProviderService); + PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getPolicyManagementService")) + .toReturn(policyManagerService); + PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getDeviceManagementService")) + .toReturn(deviceManagementProviderService); Mockito.reset(groupManagementProviderService); DeviceToGroupsAssignment deviceToGroupsAssignment = new DeviceToGroupsAssignment(); List groupIds = new ArrayList<>(); diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/test/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/UserManagementServiceImplTest.java b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/test/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/UserManagementServiceImplTest.java index 13942afb25..aa2f84733f 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/test/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/UserManagementServiceImplTest.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/test/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/UserManagementServiceImplTest.java @@ -15,6 +15,23 @@ * 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.service.impl; @@ -34,6 +51,10 @@ import org.testng.annotations.Test; import org.wso2.carbon.context.CarbonContext; import org.wso2.carbon.device.mgt.common.exceptions.DeviceManagementException; 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.spi.OTPManagementService; +import org.wso2.carbon.device.mgt.core.otp.mgt.service.OTPManagementServiceImpl; import org.wso2.carbon.device.mgt.core.service.DeviceManagementProviderService; import org.wso2.carbon.device.mgt.core.service.DeviceManagementProviderServiceImpl; import org.wso2.carbon.device.mgt.jaxrs.beans.BasicUserInfo; @@ -66,9 +87,11 @@ public class UserManagementServiceImplTest { private UserStoreManager userStoreManager; private UserManagementService userManagementService; private DeviceManagementProviderService deviceManagementProviderService; + private OTPManagementService otpManagementService; private static final String DEFAULT_DEVICE_USER = "Internal/devicemgt-user"; private UserRealm userRealm; private EnrollmentInvitation enrollmentInvitation; + private DeviceEnrollmentInvitation deviceEnrollmentInvitation; private List userList; private static final String TEST_USERNAME = "test"; private static final String TEST2_USERNAME = "test2"; @@ -86,6 +109,7 @@ public class UserManagementServiceImplTest { userStoreManager = Mockito.mock(UserStoreManager.class, Mockito.RETURNS_MOCKS); deviceManagementProviderService = Mockito .mock(DeviceManagementProviderServiceImpl.class, Mockito.CALLS_REAL_METHODS); + otpManagementService = Mockito.mock(OTPManagementServiceImpl.class, Mockito.CALLS_REAL_METHODS); userRealm = Mockito.mock(UserRealm.class); RealmConfiguration realmConfiguration = Mockito.mock(RealmConfiguration.class); Mockito.doReturn(null).when(realmConfiguration).getSecondaryRealmConfig(); @@ -97,6 +121,8 @@ public class UserManagementServiceImplTest { enrollmentInvitation.setRecipients(recipients); userList = new ArrayList<>(); userList.add(TEST_USERNAME); + deviceEnrollmentInvitation = new DeviceEnrollmentInvitation(); + deviceEnrollmentInvitation.setUsernames(userList); } @Test(description = "This method tests the addUser method of UserManagementService") @@ -205,13 +231,11 @@ public class UserManagementServiceImplTest { @Test(description = "This method tests the send invitation method of UserManagementService", dependsOnMethods = {"testIsUserExists"}) - public void testSendInvitation() throws ConfigurationManagementException, DeviceManagementException { - PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getUserStoreManager")) - .toReturn(this.userStoreManager); - PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getDeviceManagementService")) - .toReturn(this.deviceManagementProviderService); - Mockito.doNothing().when(deviceManagementProviderService).sendEnrolmentInvitation(Mockito.any(), Mockito.any()); - Response response = userManagementService.inviteExistingUsersToEnrollDevice(userList); + public void testSendInvitation() throws OTPManagementException { + PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getOTPManagementService")) + .toReturn(this.otpManagementService); + Mockito.doNothing().when(otpManagementService).sendDeviceEnrollmentInvitationMail(Mockito.any()); + Response response = userManagementService.inviteExistingUsersToEnrollDevice(deviceEnrollmentInvitation); Assert.assertEquals(response.getStatus(), Response.Status.OK.getStatusCode(), "Inviting existing users to enroll device failed"); } @@ -240,7 +264,7 @@ public class UserManagementServiceImplTest { @Test(description = "This method tests the inviteToEnrollDevice method of UserManagementService", dependsOnMethods = "testGetUsers") - public void testInviteToEnrollDevice() { + public void testInviteToEnrollDevice() throws ConfigurationManagementException, DeviceManagementException { URL resourceUrl = ClassLoader.getSystemResource("testng.xml"); System.setProperty("carbon.home", resourceUrl.getPath()); PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getUserStoreManager")) @@ -248,6 +272,7 @@ public class UserManagementServiceImplTest { PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getAuthenticatedUser")).toReturn(TEST_USERNAME); PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getDeviceManagementService")) .toReturn(this.deviceManagementProviderService); + Mockito.doNothing().when(deviceManagementProviderService).sendEnrolmentInvitation(Mockito.any(), Mockito.any()); EnrollmentInvitation enrollmentInvitation = new EnrollmentInvitation(); List recipients = new ArrayList<>(); recipients.add(TEST_USERNAME); @@ -289,16 +314,22 @@ public class UserManagementServiceImplTest { @Test(description = "This method tests the behaviour of methods when there is an issue with " + "DeviceManagementProviderService", dependsOnMethods = {"testGetUserCount"}) - public void testNegativeScenarios1() throws ConfigurationManagementException, DeviceManagementException { + public void testNegativeScenarios1() + throws ConfigurationManagementException, DeviceManagementException, OTPManagementException { PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getUserStoreManager")) .toReturn(this.userStoreManager); PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getDeviceManagementService")) .toReturn(this.deviceManagementProviderService); PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getAuthenticatedUser")).toReturn(TEST_USERNAME); Mockito.reset(deviceManagementProviderService); + PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getOTPManagementService")) + .toReturn(this.otpManagementService); + Mockito.reset(otpManagementService); Mockito.doThrow(new DeviceManagementException()).when(deviceManagementProviderService) .sendEnrolmentInvitation(Mockito.any(), Mockito.any()); - Response response = userManagementService.inviteExistingUsersToEnrollDevice(userList); + Mockito.doThrow(new OTPManagementException()).when(otpManagementService) + .sendDeviceEnrollmentInvitationMail(Mockito.any()); + Response response = userManagementService.inviteExistingUsersToEnrollDevice(deviceEnrollmentInvitation); Assert.assertEquals(response.getStatus(), Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), "Invite existing users to enroll device succeeded under erroneous conditions"); response = userManagementService.inviteToEnrollDevice(enrollmentInvitation); @@ -346,6 +377,8 @@ public class UserManagementServiceImplTest { PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getDeviceManagementService")) .toReturn(this.deviceManagementProviderService); Mockito.reset(this.userStoreManager); + PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getOTPManagementService")) + .toReturn(this.otpManagementService); Mockito.doThrow(new UserStoreException()).when(userStoreManager) .getUserClaimValue(Mockito.any(), Mockito.any(), Mockito.any()); Mockito.doThrow(new UserStoreException()).when(userStoreManager) @@ -362,7 +395,7 @@ public class UserManagementServiceImplTest { response = userManagementService.inviteToEnrollDevice(enrollmentInvitation); Assert.assertEquals(response.getStatus(), Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), "Invite existing users to enroll device succeeded under erroneous conditions"); - response = userManagementService.inviteExistingUsersToEnrollDevice(userList); + response = userManagementService.inviteExistingUsersToEnrollDevice(deviceEnrollmentInvitation); Assert.assertEquals(response.getStatus(), Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), "Invite existing users to enroll device succeeded under erroneous conditions"); } diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/DeviceManagementConstants.java b/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/DeviceManagementConstants.java index 20b4f5b626..492288febb 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/DeviceManagementConstants.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/DeviceManagementConstants.java @@ -125,4 +125,14 @@ public final class DeviceManagementConstants { public static final String DEFAULT_HTTP_PROTOCOL = "https"; public static final String DAS_URL = DEFAULT_HTTP_PROTOCOL + "://" + DAS_HOST_NAME + ":" + DAS_PORT; } + + public static final class OTPProperties { + private OTPProperties() { throw new AssertionError(); } + + public static final String FIRST_NAME = "first-name"; + public static final String LAST_NAME = "last-name"; + public static final String TENANT_ADMIN_USERNAME = "tenant-admin-username"; + public static final String TENANT_ADMIN_PASSWORD = "tenant-admin-password"; + } + } diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/exceptions/BadRequestException.java b/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/exceptions/BadRequestException.java index b7d99da0e0..ed681b8140 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/exceptions/BadRequestException.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/exceptions/BadRequestException.java @@ -19,7 +19,7 @@ package org.wso2.carbon.device.mgt.common.exceptions; -public class BadRequestException extends Exception { +public class BadRequestException extends DeviceManagementException { private static final long serialVersionUID = 2304023531260840549L; public BadRequestException() { diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/exceptions/DBConnectionException.java b/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/exceptions/DBConnectionException.java new file mode 100644 index 0000000000..a47449c060 --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/exceptions/DBConnectionException.java @@ -0,0 +1,33 @@ +/* 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.common.exceptions; + +/** + * Exception thrown due to Database Connection issues. + */ +public class DBConnectionException extends Exception { + + private static final long serialVersionUID = -6779125067467878014L; + + public DBConnectionException(String message, Throwable cause) { + super(message, cause); + } + + public DBConnectionException(String msg) { + super(msg); + } +} diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/exceptions/OTPManagementException.java b/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/exceptions/OTPManagementException.java new file mode 100644 index 0000000000..3dd3bee07f --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/exceptions/OTPManagementException.java @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2020, 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.common.exceptions; + +public class OTPManagementException extends Exception { + + private static final long serialVersionUID = 397485329551276175L; + + public OTPManagementException(String msg, Exception nestedEx) { + super(msg, nestedEx); + } + + public OTPManagementException(String message, Throwable cause) { + super(message, cause); + } + + public OTPManagementException(String msg) { + super(msg); + } + + public OTPManagementException() { + super(); + } + + public OTPManagementException(Throwable cause) { + super(cause); + } + +} diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/exceptions/UnAuthorizedException.java b/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/exceptions/UnAuthorizedException.java new file mode 100644 index 0000000000..6c3d5c6346 --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/exceptions/UnAuthorizedException.java @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2020, Entgra (pvt) Ltd. (http://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.common.exceptions; + +public class UnAuthorizedException extends DeviceManagementException { + private static final long serialVersionUID = 2304023531260840549L; + + public UnAuthorizedException() { + super(); + } + + public UnAuthorizedException(String msg) { + super(msg); + } + + public UnAuthorizedException(Throwable cause) { + super(cause); + } + + public UnAuthorizedException(String msg, Exception nestedEx) { + super(msg, nestedEx); + } + + public UnAuthorizedException(String message, Throwable cause) { + super(message, cause); + } +} + diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/general/OneTimeTokenDetails.java b/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/general/OneTimeTokenDetails.java new file mode 100644 index 0000000000..f204a1f390 --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/general/OneTimeTokenDetails.java @@ -0,0 +1,96 @@ +/* + * 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.common.general; + +import java.util.Map; + +public class OneTimeTokenDetails extends TenantDetail { + + String password; + String token; + long createdDate; + long updatedDate; + boolean isExpired; + String metaInfo; + Map replaceValue; + String emailType; + + public long getCreatedDate() { + return createdDate; + } + + public void setCreatedDate(long createdDate) { + this.createdDate = createdDate; + } + + public long getUpdatedDate() { + return updatedDate; + } + + public void setUpdatedDate(long updatedDate) { + this.updatedDate = updatedDate; + } + + public boolean isExpired() { + return isExpired; + } + + public void setExpired(boolean expired) { + isExpired = expired; + } + + public String getMetaInfo() { + return metaInfo; + } + + public void setMetaInfo(String metaInfo) { + this.metaInfo = metaInfo; + } + + public Map getReplaceValue() { + return replaceValue; + } + + public void setReplaceValue(Map replaceValue) { + this.replaceValue = replaceValue; + } + + public String getEmailType() { + return emailType; + } + + public void setEmailType(String emailType) { + this.emailType = emailType; + } + + public String getPassword() { + return password; + } + + public void setPassword(String password) { + this.password = password; + } + + public String getToken() { + return token; + } + + public void setToken(String token) { + this.token = token; + } +} diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/invitation/mgt/DeviceEnrollmentInvitation.java b/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/invitation/mgt/DeviceEnrollmentInvitation.java new file mode 100644 index 0000000000..0bdb03e921 --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/invitation/mgt/DeviceEnrollmentInvitation.java @@ -0,0 +1,59 @@ +/* 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.common.invitation.mgt; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; + +import java.io.Serializable; +import java.util.List; + +@ApiModel( + value = "DeviceEnrollmentInvitation", + description = "Holds data to send device enrollment invitation to list of existing users.") +public class DeviceEnrollmentInvitation implements Serializable { + + private static final long serialVersionUID = 6933837278652532052L; + + @ApiModelProperty( + name = "usernames", + value = "List of usernames of users.", + required = true) + private List usernames; + + @ApiModelProperty( + name = "deviceEnrollmentTypes", + value = "List of enrollment types against device types.") + private List deviceEnrollmentTypes; + + public List getUsernames() { + return usernames; + } + + public void setUsernames(List usernames) { + this.usernames = usernames; + } + + public List getDeviceEnrollmentTypes() { + return deviceEnrollmentTypes; + } + + public void setDeviceEnrollmentTypes( + List deviceEnrollmentTypes) { + this.deviceEnrollmentTypes = deviceEnrollmentTypes; + } +} diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/invitation/mgt/DeviceEnrollmentInvitationDetails.java b/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/invitation/mgt/DeviceEnrollmentInvitationDetails.java new file mode 100644 index 0000000000..3882d47293 --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/invitation/mgt/DeviceEnrollmentInvitationDetails.java @@ -0,0 +1,25 @@ +package org.wso2.carbon.device.mgt.common.invitation.mgt; + +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.List; + +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "DeviceEnrollmentInvitationDetails", propOrder = { + "enrollmentDetails" +}) +public class DeviceEnrollmentInvitationDetails { + + @XmlElement(name = "EnrollmentDetails") + private List enrollmentDetails; + + public List getEnrollmentDetails() { + return enrollmentDetails; + } + + public void setEnrollmentDetails(List enrollmentDetails) { + this.enrollmentDetails = enrollmentDetails; + } +} diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/invitation/mgt/DeviceEnrollmentType.java b/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/invitation/mgt/DeviceEnrollmentType.java new file mode 100644 index 0000000000..0124fde36d --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/invitation/mgt/DeviceEnrollmentType.java @@ -0,0 +1,59 @@ +/* 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.common.invitation.mgt; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; + +import java.io.Serializable; +import java.util.List; + +@ApiModel( + value = "DeviceEnrollmentType", + description = "Holds data of enrollment types against device types.") +public class DeviceEnrollmentType implements Serializable { + + private static final long serialVersionUID = 6563596191450032613L; + + @ApiModelProperty( + name = "deviceType", + value = "Device type (i.e: android, ios, windows)", + required = true) + private String deviceType; + + @ApiModelProperty( + name = "enrollmentType", + value = "Enrollment type (i.e: BYOD, COPE, COSU)", + required = true) + private List enrollmentType; + + public String getDeviceType() { + return deviceType; + } + + public void setDeviceType(String deviceType) { + this.deviceType = deviceType; + } + + public List getEnrollmentType() { + return enrollmentType; + } + + public void setEnrollmentType(List enrollmentType) { + this.enrollmentType = enrollmentType; + } +} diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/invitation/mgt/EnrollmentDetails.java b/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/invitation/mgt/EnrollmentDetails.java new file mode 100644 index 0000000000..905022440b --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/invitation/mgt/EnrollmentDetails.java @@ -0,0 +1,36 @@ +package org.wso2.carbon.device.mgt.common.invitation.mgt; + +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 = "EnrollmentDetails", propOrder = { + "enrollmentType", + "enrollmentSteps" +}) +public class EnrollmentDetails { + + @XmlElement(name = "EnrollmentType") + private String enrollmentType; + + @XmlElement(name = "EnrollmentSteps") + private String enrollmentSteps; + + public String getEnrollmentType() { + return enrollmentType; + } + + public void setEnrollmentType(String enrollmentType) { + this.enrollmentType = enrollmentType; + } + + public String getEnrollmentSteps() { + return enrollmentSteps; + } + + public void setEnrollmentSteps(String enrollmentSteps) { + this.enrollmentSteps = enrollmentSteps; + } +} diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/notification/mgt/NotificationManagementService.java b/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/notification/mgt/NotificationManagementService.java index ab048c1db5..e071ff6153 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/notification/mgt/NotificationManagementService.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/notification/mgt/NotificationManagementService.java @@ -102,5 +102,4 @@ public interface NotificationManagementService { PaginationResult getNotificationsByStatus(Notification.Status status, PaginationRequest request) throws NotificationManagementException; - } diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/otp/mgt/OTPEmailTypes.java b/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/otp/mgt/OTPEmailTypes.java new file mode 100644 index 0000000000..72bbea982e --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/otp/mgt/OTPEmailTypes.java @@ -0,0 +1,22 @@ +/* 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.common.otp.mgt; + +public enum OTPEmailTypes { + USER_VERIFY, DEVICE_ENROLLMENT +} diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/otp/mgt/dto/OneTimePinDTO.java b/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/otp/mgt/dto/OneTimePinDTO.java new file mode 100644 index 0000000000..11923947c1 --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/otp/mgt/dto/OneTimePinDTO.java @@ -0,0 +1,113 @@ +/* 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.common.otp.mgt.dto; + +import java.sql.Timestamp; + +public class OneTimePinDTO { + + int id; + String otpToken; + int tenantId; + String username; + String email; + String emailType; + String metaInfo; + Timestamp createdAt; + int expiryTime; + boolean isExpired; + + public int getTenantId() { + return tenantId; + } + + public void setTenantId(int tenantId) { + this.tenantId = tenantId; + } + + public String getUsername() { + return username; + } + + public void setUsername(String username) { + this.username = username; + } + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public String getOtpToken() { + return otpToken; + } + + public void setOtpToken(String otpToken) { + this.otpToken = otpToken; + } + + public String getEmail() { + return email; + } + + public void setEmail(String email) { + this.email = email; + } + + public String getEmailType() { + return emailType; + } + + public void setEmailType(String emailType) { + this.emailType = emailType; + } + + public String getMetaInfo() { return metaInfo; } + + public void setMetaInfo(String metaInfo) { + this.metaInfo = metaInfo; + } + + public Timestamp getCreatedAt() { + return createdAt; + } + + public void setCreatedAt(Timestamp createdAt) { + this.createdAt = createdAt; + } + + public int getExpiryTime() { + return expiryTime; + } + + public void setExpiryTime(int expiryTime) { + this.expiryTime = expiryTime; + } + + public boolean isExpired() { + return isExpired; + } + + public void setExpired(boolean expired) { + isExpired = expired; + } + +} diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/otp/mgt/wrapper/OTPWrapper.java b/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/otp/mgt/wrapper/OTPWrapper.java new file mode 100644 index 0000000000..319da774d1 --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/otp/mgt/wrapper/OTPWrapper.java @@ -0,0 +1,53 @@ +/* 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.common.otp.mgt.wrapper; + +import org.wso2.carbon.device.mgt.common.metadata.mgt.Metadata; + +import java.util.List; + +public class OTPWrapper { + + private String email; + private String emailType; + private String username; + private List properties; + + public String getEmail() { + return email; + } + + public void setEmail(String email) { + this.email = email; + } + + public String getEmailType() { + return emailType; + } + + public void setEmailType(String emailType) { + this.emailType = emailType; + } + + public String getUsername() { return username; } + + public void setUsername(String username) { this.username = username; } + + public List getProperties() { return properties; } + + public void setProperties(List properties) { this.properties = properties; } +} diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/policy/mgt/ui/Item.java b/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/policy/mgt/ui/Item.java index c7e678bf27..99ac1e397f 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/policy/mgt/ui/Item.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/policy/mgt/ui/Item.java @@ -44,6 +44,7 @@ public class Item { private Text text; private InputList inputList; private String nullableValue; + private String divider; @XmlElement(name = "Label") public String getLabel() { @@ -197,4 +198,13 @@ public class Item { public void setNullableValue(String nullableValue) { this.nullableValue = nullableValue; } + + @XmlElement(name = "Divider") + public String getDivider() { + return divider; + } + + public void setDivider(String divider) { + this.divider = divider; + } } diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/roles/config/DefaultRoles.java b/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/roles/config/DefaultRoles.java new file mode 100644 index 0000000000..f70e2107c6 --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/roles/config/DefaultRoles.java @@ -0,0 +1,49 @@ +/* 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.common.roles.config; + +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlElementWrapper; +import javax.xml.bind.annotation.XmlRootElement; +import java.util.List; + +@XmlRootElement(name = "DefaultRoles") +public class DefaultRoles { + + private boolean enabled; + private List roles; + + @XmlElement(name = "Enabled", required = true) + public boolean isEnabled() { + return enabled; + } + + public void setEnabled(boolean enabled) { + this.enabled = enabled; + } + + @XmlElementWrapper(name = "Roles", required = true) + @XmlElement(name = "Role", required = true) + public List getRoles() { + return roles; + } + + public void setRoles(List roles) { + this.roles = roles; + } +} diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/roles/config/Role.java b/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/roles/config/Role.java new file mode 100644 index 0000000000..f633b9b2d3 --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/roles/config/Role.java @@ -0,0 +1,49 @@ +/* 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.common.roles.config; + +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlElementWrapper; +import javax.xml.bind.annotation.XmlRootElement; +import java.util.List; + +@XmlRootElement(name = "Role") +public class Role { + + private String name; + private List permissions; + + @XmlElement(name = "Name", required = true) + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + @XmlElementWrapper(name = "Permissions", required = true) + @XmlElement(name = "Permission", required = true) + public List getPermissions() { + return permissions; + } + + public void setPermissions(List permissions) { + this.permissions = permissions; + } +} diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/spi/DeviceManagementService.java b/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/spi/DeviceManagementService.java index 25303cf966..e6f33f85de 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/spi/DeviceManagementService.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/spi/DeviceManagementService.java @@ -38,6 +38,7 @@ import org.wso2.carbon.device.mgt.common.*; import org.wso2.carbon.device.mgt.common.app.mgt.ApplicationManager; import org.wso2.carbon.device.mgt.common.exceptions.DeviceManagementException; import org.wso2.carbon.device.mgt.common.general.GeneralConfig; +import org.wso2.carbon.device.mgt.common.invitation.mgt.DeviceEnrollmentInvitationDetails; import org.wso2.carbon.device.mgt.common.policy.mgt.PolicyMonitoringManager; import org.wso2.carbon.device.mgt.common.pull.notification.PullNotificationSubscriber; import org.wso2.carbon.device.mgt.common.push.notification.PushNotificationConfig; @@ -77,4 +78,6 @@ public interface DeviceManagementService { DeviceTypePlatformDetails getDeviceTypePlatformDetails(); + DeviceEnrollmentInvitationDetails getDeviceEnrollmentInvitationDetails(); + } diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/spi/OTPManagementService.java b/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/spi/OTPManagementService.java new file mode 100644 index 0000000000..f63a95ca32 --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/spi/OTPManagementService.java @@ -0,0 +1,65 @@ +/* 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.common.spi; + +import org.wso2.carbon.device.mgt.common.exceptions.BadRequestException; +import org.wso2.carbon.device.mgt.common.exceptions.DeviceManagementException; +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.otp.mgt.dto.OneTimePinDTO; +import org.wso2.carbon.device.mgt.common.otp.mgt.wrapper.OTPWrapper; + +import java.util.Map; + +public interface OTPManagementService { + + /** + * Create OTP token and store tenant details in the DB + * @param otpWrapper OTP Mail Wrapper object which contains tenant details of registering user + * @throws OTPManagementException if error occurs while creating OTP token and storing tenant details. + * @throws BadRequestException if found and incompatible payload to create OTP token. + */ + void sendUserVerifyingMail(OTPWrapper otpWrapper) throws OTPManagementException, DeviceManagementException; + + /** + * Check the validity of the OTP + * @param oneTimeToken OTP + * @return The OTP data + * @throws OTPManagementException if error occurred whle verifying validity of the OPT + * @throws BadRequestException if found an null value for OTP + */ + OneTimePinDTO isValidOTP(String oneTimeToken) throws OTPManagementException, BadRequestException; + + /** + * Invalidate the OTP and send welcome mail + * @param oneTimeToken OTP + * @param email email address + * @param properties email properties to add to email body + * @throws OTPManagementException if error occurred while invalidate the OTP or send welcome email + */ + void completeSelfRegistration(String oneTimeToken, String email, Map properties) + throws OTPManagementException; + + /** + * Create OTP token and send device enrollment invitation + * @param deviceEnrollmentInvitation object which contains device enrollment invitation related details + * @throws OTPManagementException if error occurred while creating OTP token &/ sending mail + */ + void sendDeviceEnrollmentInvitationMail(DeviceEnrollmentInvitation deviceEnrollmentInvitation) + throws OTPManagementException; +} diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/pom.xml b/components/device-mgt/org.wso2.carbon.device.mgt.core/pom.xml index 4d1c23ba6c..347c710be6 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.core/pom.xml +++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/pom.xml @@ -360,6 +360,10 @@ org.wso2.carbon.multitenancy org.wso2.carbon.tenant.mgt + + commons-validator + commons-validator + diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/DeviceManagementConstants.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/DeviceManagementConstants.java index 7f7610126b..b09d6fad9d 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/DeviceManagementConstants.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/DeviceManagementConstants.java @@ -116,6 +116,8 @@ public final class DeviceManagementConstants { public static final String USER_REGISTRATION_TEMPLATE = "user-registration"; public static final String USER_ENROLLMENT_TEMPLATE = "user-enrollment"; + public static final String USER_VERIFY_TEMPLATE = "user-verify"; + public static final String USER_WELCOME_TEMPLATE = "user-welcome"; public static final String DEFAULT_ENROLLMENT_TEMPLATE = "default-enrollment-invitation"; } @@ -142,6 +144,9 @@ public final class DeviceManagementConstants { public static final String DEFAULT_DEVICE_USER = "Internal/devicemgt-user"; public static final String DEFAULT_DEVICE_ADMIN = "Internal/devicemgt-admin"; + public static final String CLAIM_EMAIL_ADDRESS = "http://wso2.org/claims/emailaddress"; + public static final String CLAIM_FIRST_NAME = "http://wso2.org/claims/givenname"; + // Permissions that are given for a normal device user. public static final Permission[] PERMISSIONS_FOR_DEVICE_USER = { new Permission("/permission/admin/Login", "ui.execute"), @@ -169,4 +174,13 @@ public final class DeviceManagementConstants { public static final String DEVICE_INFO_PARAM = "device-info"; public static final String APP_USAGE_ENDPOINT = REPORTING_CONTEXT + "/app-usage"; } + + public static final class Payload { + private Payload() { + throw new AssertionError(); + } + public static final String DEVICE_INFO_DEVICE_NAME = "DEVICE_NAME"; + public static final String DEVICE_INFO_IMEI = "IMEI"; + public static final String DEVICE_INFO_IMSI = "IMSI";; + } } diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/config/DeviceManagementConfig.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/config/DeviceManagementConfig.java index 456de2f2d4..cf58967988 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/config/DeviceManagementConfig.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/config/DeviceManagementConfig.java @@ -18,6 +18,7 @@ package org.wso2.carbon.device.mgt.core.config; import org.wso2.carbon.device.mgt.common.enrollment.notification.EnrollmentNotificationConfiguration; +import org.wso2.carbon.device.mgt.common.roles.config.DefaultRoles; import org.wso2.carbon.device.mgt.core.config.analytics.OperationAnalyticsConfiguration; import org.wso2.carbon.device.mgt.core.config.archival.ArchivalConfiguration; import org.wso2.carbon.device.mgt.core.config.cache.CertificateCacheConfiguration; @@ -60,7 +61,7 @@ public final class DeviceManagementConfig { private RemoteSessionConfiguration remoteSessionConfiguration; private ArchivalConfiguration archivalConfiguration; private EnrollmentNotificationConfiguration enrollmentNotificationConfiguration; - + private DefaultRoles defaultRoles; @XmlElement(name = "ManagementRepository", required = true) public DeviceManagementConfigRepository getDeviceManagementConfigRepository() { @@ -215,5 +216,10 @@ public final class DeviceManagementConfig { EnrollmentNotificationConfiguration enrollmentNotificationConfiguration) { this.enrollmentNotificationConfiguration = enrollmentNotificationConfiguration; } + + @XmlElement(name = "DefaultRoles", required = true) + public DefaultRoles getDefaultRoles() { return defaultRoles; } + + public void setDefaultRoles(DefaultRoles defaultRoles) { this.defaultRoles = defaultRoles; } } diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/device/details/mgt/impl/DeviceInformationManagerImpl.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/device/details/mgt/impl/DeviceInformationManagerImpl.java index 2e791f733d..b152e65a84 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/device/details/mgt/impl/DeviceInformationManagerImpl.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/device/details/mgt/impl/DeviceInformationManagerImpl.java @@ -134,6 +134,20 @@ public class DeviceInformationManagerImpl implements DeviceInformationManager { deviceDetailsDAO.addDeviceProperties(injectableProps, device.getId(), device.getEnrolmentInfo().getId()); } + + if (deviceInfo.getDeviceDetailsMap().containsKey(DeviceManagementConstants + .Payload.DEVICE_INFO_DEVICE_NAME) && + StringUtils.isNotEmpty(deviceInfo.getDeviceDetailsMap() + .get(DeviceManagementConstants.Payload.DEVICE_INFO_DEVICE_NAME)) + && !device.getName().equals(deviceInfo.getDeviceDetailsMap() + .get(DeviceManagementConstants.Payload.DEVICE_INFO_DEVICE_NAME))) { + String name = deviceInfo.getDeviceDetailsMap() + .get(DeviceManagementConstants.Payload.DEVICE_INFO_DEVICE_NAME); + log.info("Device identifier " + device.getDeviceIdentifier() + ", Device name " + + "changed by user from " + device.getName() + " to " + name); + device.setName(name); + } + deviceDAO.updateDevice(device, CarbonContext.getThreadLocalCarbonContext().getTenantId()); DeviceManagementDAOFactory.commitTransaction(); @@ -142,8 +156,10 @@ public class DeviceInformationManagerImpl implements DeviceInformationManager { Object[] metaData = {device.getDeviceIdentifier(), device.getType()}; Object[] payload = new Object[]{ Calendar.getInstance().getTimeInMillis(), - deviceInfo.getDeviceDetailsMap().get("IMEI"), - deviceInfo.getDeviceDetailsMap().get("IMSI"), + deviceInfo.getDeviceDetailsMap().get(DeviceManagementConstants.Payload + .DEVICE_INFO_IMEI), + deviceInfo.getDeviceDetailsMap().get(DeviceManagementConstants.Payload + .DEVICE_INFO_IMSI), deviceInfo.getDeviceModel(), deviceInfo.getVendor(), deviceInfo.getOsVersion(), diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/internal/DeviceManagementServiceComponent.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/internal/DeviceManagementServiceComponent.java index edc388f202..60b309ad76 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/internal/DeviceManagementServiceComponent.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/internal/DeviceManagementServiceComponent.java @@ -35,6 +35,7 @@ import org.wso2.carbon.device.mgt.common.permission.mgt.PermissionManagerService import org.wso2.carbon.device.mgt.common.report.mgt.ReportManagementService; import org.wso2.carbon.device.mgt.common.spi.DeviceManagementService; import org.wso2.carbon.device.mgt.common.spi.DeviceTypeGeneratorService; +import org.wso2.carbon.device.mgt.common.spi.OTPManagementService; import org.wso2.carbon.device.mgt.core.DeviceManagementConstants; import org.wso2.carbon.device.mgt.core.app.mgt.ApplicationManagementProviderService; import org.wso2.carbon.device.mgt.core.app.mgt.ApplicationManagerProviderServiceImpl; @@ -56,6 +57,8 @@ import org.wso2.carbon.device.mgt.core.notification.mgt.NotificationManagementSe import org.wso2.carbon.device.mgt.core.notification.mgt.dao.NotificationManagementDAOFactory; import org.wso2.carbon.device.mgt.core.operation.mgt.OperationManagerImpl; import org.wso2.carbon.device.mgt.core.operation.mgt.dao.OperationManagementDAOFactory; +import org.wso2.carbon.device.mgt.core.otp.mgt.dao.OTPManagementDAOFactory; +import org.wso2.carbon.device.mgt.core.otp.mgt.service.OTPManagementServiceImpl; import org.wso2.carbon.device.mgt.core.permission.mgt.PermissionManagerServiceImpl; import org.wso2.carbon.device.mgt.core.privacy.PrivacyComplianceProvider; import org.wso2.carbon.device.mgt.core.privacy.impl.PrivacyComplianceProviderImpl; @@ -72,9 +75,11 @@ import org.wso2.carbon.device.mgt.core.task.DeviceTaskManagerService; import org.wso2.carbon.device.mgt.core.config.ui.UIConfigurationManager; import org.wso2.carbon.device.mgt.core.util.DeviceManagementSchemaInitializer; import org.wso2.carbon.device.mgt.core.util.DeviceManagerUtil; +import org.wso2.carbon.device.mgt.core.util.DeviceMgtTenantMgtListener; import org.wso2.carbon.email.sender.core.service.EmailSenderService; import org.wso2.carbon.ndatasource.core.DataSourceService; import org.wso2.carbon.registry.core.service.RegistryService; +import org.wso2.carbon.stratos.common.listeners.TenantMgtListener; import org.wso2.carbon.user.core.service.RealmService; import org.wso2.carbon.utils.Axis2ConfigurationContextObserver; import org.wso2.carbon.utils.ConfigurationContextService; @@ -176,6 +181,7 @@ public class DeviceManagementServiceComponent { NotificationManagementDAOFactory.init(dsConfig); OperationManagementDAOFactory.init(dsConfig); MetadataManagementDAOFactory.init(dsConfig); + OTPManagementDAOFactory.init(dsConfig.getJndiLookupDefinition().getJndiName()); /*Initialize the device cache*/ DeviceManagerUtil.initializeDeviceCache(); @@ -245,6 +251,9 @@ public class DeviceManagementServiceComponent { componentContext.getBundleContext().registerService(PrivacyComplianceProvider.class.getName(), privacyComplianceProvider, null); + componentContext.getBundleContext() + .registerService(TenantMgtListener.class.getName(), new DeviceMgtTenantMgtListener(), null); + if (log.isDebugEnabled()) { log.debug("Device management core bundle has been successfully initialized"); } @@ -325,7 +334,10 @@ public class DeviceManagementServiceComponent { MetadataManagementService metadataManagementService = new MetadataManagementServiceImpl(); bundleContext.registerService(MetadataManagementService.class.getName(), metadataManagementService, null); - /* Registering App Management service */ + OTPManagementService otpManagementService = new OTPManagementServiceImpl(); + bundleContext.registerService(OTPManagementService.class.getName(), otpManagementService, null); + + /* Registering App Management service */ try { AppManagementConfigurationManager.getInstance().initConfig(); AppManagementConfig appConfig = diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/notification/mgt/NotificationManagementServiceImpl.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/notification/mgt/NotificationManagementServiceImpl.java index 41686a4646..3371f8d804 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/notification/mgt/NotificationManagementServiceImpl.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/notification/mgt/NotificationManagementServiceImpl.java @@ -234,7 +234,6 @@ public class NotificationManagementServiceImpl implements NotificationManagement } } - @Override public List getNotificationsByStatus(Notification.Status status) throws NotificationManagementException { diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/notification/mgt/dao/NotificationDAO.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/notification/mgt/dao/NotificationDAO.java index 4c47d7c90e..4e39af6f0b 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/notification/mgt/dao/NotificationDAO.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/notification/mgt/dao/NotificationDAO.java @@ -100,5 +100,4 @@ public interface NotificationDAO { List getNotificationsByStatus(PaginationRequest request, Notification.Status status, int tenantId) throws NotificationManagementException; - } diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/notification/mgt/dao/impl/AbstractNotificationDAOImpl.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/notification/mgt/dao/impl/AbstractNotificationDAOImpl.java index c16c05ef3a..8b0a37b7c1 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/notification/mgt/dao/impl/AbstractNotificationDAOImpl.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/notification/mgt/dao/impl/AbstractNotificationDAOImpl.java @@ -24,7 +24,12 @@ import org.wso2.carbon.device.mgt.core.notification.mgt.dao.NotificationDAO; import org.wso2.carbon.device.mgt.core.notification.mgt.dao.NotificationManagementDAOFactory; import org.wso2.carbon.device.mgt.core.notification.mgt.dao.util.NotificationDAOUtil; -import java.sql.*; +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Statement; +import java.sql.Timestamp; import java.util.ArrayList; import java.util.Date; import java.util.List; @@ -94,7 +99,6 @@ public abstract class AbstractNotificationDAOImpl implements NotificationDAO { NotificationDAOUtil.cleanupResources(stmt, rs); } return notification; - } @Override diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/notification/mgt/dao/impl/GenericNotificationDAOImpl.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/notification/mgt/dao/impl/GenericNotificationDAOImpl.java index 0a57f761a5..b69a77ac42 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/notification/mgt/dao/impl/GenericNotificationDAOImpl.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/notification/mgt/dao/impl/GenericNotificationDAOImpl.java @@ -49,7 +49,7 @@ public class GenericNotificationDAOImpl extends AbstractNotificationDAOImpl { "SELECT n1.NOTIFICATION_ID, n1.DEVICE_ID, n1.OPERATION_ID, n1.STATUS, n1.DESCRIPTION," + " d.DEVICE_IDENTIFICATION, d.NAME as DEVICE_NAME, t.NAME AS DEVICE_TYPE FROM DM_DEVICE d, DM_DEVICE_TYPE t, (SELECT " + "NOTIFICATION_ID, DEVICE_ID, OPERATION_ID, STATUS, DESCRIPTION FROM DM_NOTIFICATION WHERE " + - "TENANT_ID = ?) n1 WHERE n1.DEVICE_ID = d.ID AND d.DEVICE_TYPE_ID=t.ID AND TENANT_ID = ?"; + "TENANT_ID = ?) n1 WHERE n1.DEVICE_ID = d.ID AND d.DEVICE_TYPE_ID=t.ID AND TENANT_ID = ? ORDER BY n1.NOTIFICATION_ID DESC"; sql = sql + " LIMIT ?,?"; @@ -90,7 +90,7 @@ public class GenericNotificationDAOImpl extends AbstractNotificationDAOImpl { "DM_DEVICE d, DM_DEVICE_TYPE t, (SELECT NOTIFICATION_ID, DEVICE_ID, " + "OPERATION_ID, STATUS, DESCRIPTION FROM DM_NOTIFICATION WHERE " + "TENANT_ID = ? AND STATUS = ?) n1 WHERE n1.DEVICE_ID = d.ID AND d.DEVICE_TYPE_ID=t.ID " + - "AND TENANT_ID = ?"; + "AND TENANT_ID = ? ORDER BY n1.NOTIFICATION_ID DESC"; sql = sql + " LIMIT ?,?"; diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/notification/mgt/dao/impl/OracleNotificationDAOImpl.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/notification/mgt/dao/impl/OracleNotificationDAOImpl.java index bf6360ed6e..026285dd10 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/notification/mgt/dao/impl/OracleNotificationDAOImpl.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/notification/mgt/dao/impl/OracleNotificationDAOImpl.java @@ -24,7 +24,11 @@ import org.wso2.carbon.device.mgt.common.notification.mgt.NotificationManagement import org.wso2.carbon.device.mgt.core.notification.mgt.dao.NotificationManagementDAOFactory; import org.wso2.carbon.device.mgt.core.notification.mgt.dao.util.NotificationDAOUtil; -import java.sql.*; +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Timestamp; import java.util.ArrayList; import java.util.Date; import java.util.List; @@ -33,6 +37,7 @@ import java.util.List; * This class holds the Oracle implementation of NotificationDAO which can be used to support Oracle db syntax. */ public class OracleNotificationDAOImpl extends AbstractNotificationDAOImpl { + @Override public int addNotification(int deviceId, int tenantId, Notification notification) throws NotificationManagementException { @@ -81,7 +86,7 @@ public class OracleNotificationDAOImpl extends AbstractNotificationDAOImpl { "NOTIFICATION_ID, DEVICE_ID, OPERATION_ID, STATUS, DESCRIPTION FROM DM_NOTIFICATION WHERE " + "TENANT_ID = ?) n1 WHERE n1.DEVICE_ID = d.ID AND d.DEVICE_TYPE_ID=t.ID AND TENANT_ID = ?"; - sql = sql + " ORDER BY n1.NOTIFICATION_ID OFFSET ? ROWS FETCH NEXT ? ROWS ONLY"; + sql = sql + " ORDER BY n1.NOTIFICATION_ID DESC OFFSET ? ROWS FETCH NEXT ? ROWS ONLY"; stmt = conn.prepareStatement(sql); stmt.setInt(1, tenantId); @@ -122,7 +127,7 @@ public class OracleNotificationDAOImpl extends AbstractNotificationDAOImpl { + "TENANT_ID = ? AND STATUS = ?) n1 WHERE n1.DEVICE_ID = d.ID AND d.DEVICE_TYPE_ID=t.ID " + "AND TENANT_ID = ?"; - sql = sql + " ORDER BY n1.NOTIFICATION_ID OFFSET ? ROWS FETCH NEXT ? ROWS ONLY"; + sql = sql + " ORDER BY n1.NOTIFICATION_ID DESC OFFSET ? ROWS FETCH NEXT ? ROWS ONLY"; stmt = conn.prepareStatement(sql); stmt.setInt(1, tenantId); @@ -149,4 +154,4 @@ public class OracleNotificationDAOImpl extends AbstractNotificationDAOImpl { } return notifications; } -} \ No newline at end of file +} diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/notification/mgt/dao/impl/PostgreSQLNotificationDAOImpl.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/notification/mgt/dao/impl/PostgreSQLNotificationDAOImpl.java index 744e128716..8b668064f1 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/notification/mgt/dao/impl/PostgreSQLNotificationDAOImpl.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/notification/mgt/dao/impl/PostgreSQLNotificationDAOImpl.java @@ -49,7 +49,7 @@ public class PostgreSQLNotificationDAOImpl extends AbstractNotificationDAOImpl { "SELECT n1.NOTIFICATION_ID, n1.DEVICE_ID, n1.OPERATION_ID, n1.STATUS, n1.DESCRIPTION," + " d.DEVICE_IDENTIFICATION, d.NAME as DEVICE_NAME, t.NAME AS DEVICE_TYPE FROM DM_DEVICE d, DM_DEVICE_TYPE t, (SELECT " + "NOTIFICATION_ID, DEVICE_ID, OPERATION_ID, STATUS, DESCRIPTION FROM DM_NOTIFICATION WHERE " + - "TENANT_ID = ?) n1 WHERE n1.DEVICE_ID = d.ID AND d.DEVICE_TYPE_ID=t.ID AND TENANT_ID = ?"; + "TENANT_ID = ?) n1 WHERE n1.DEVICE_ID = d.ID AND d.DEVICE_TYPE_ID=t.ID AND TENANT_ID = ? ORDER BY n1.NOTIFICATION_ID DESC"; sql = sql + " LIMIT ? OFFSET ?"; @@ -90,7 +90,7 @@ public class PostgreSQLNotificationDAOImpl extends AbstractNotificationDAOImpl { "DM_DEVICE d, DM_DEVICE_TYPE t, (SELECT NOTIFICATION_ID, DEVICE_ID, " + "OPERATION_ID, STATUS, DESCRIPTION FROM DM_NOTIFICATION WHERE " + "TENANT_ID = ? AND STATUS = ?) n1 WHERE n1.DEVICE_ID = d.ID AND d.DEVICE_TYPE_ID=t.ID " + - "AND TENANT_ID = ?"; + "AND TENANT_ID = ? ORDER BY n1.NOTIFICATION_ID DESC"; sql = sql + " LIMIT ? OFFSET ?"; diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/notification/mgt/dao/impl/SQLServerNotificationDAOImpl.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/notification/mgt/dao/impl/SQLServerNotificationDAOImpl.java index b87ee63f32..43d5969c4b 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/notification/mgt/dao/impl/SQLServerNotificationDAOImpl.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/notification/mgt/dao/impl/SQLServerNotificationDAOImpl.java @@ -51,7 +51,7 @@ public class SQLServerNotificationDAOImpl extends AbstractNotificationDAOImpl { "NOTIFICATION_ID, DEVICE_ID, OPERATION_ID, STATUS, DESCRIPTION FROM DM_NOTIFICATION WHERE " + "TENANT_ID = ?) n1 WHERE n1.DEVICE_ID = d.ID AND d.DEVICE_TYPE_ID=t.ID AND TENANT_ID = ?"; - sql = sql + " ORDER BY n1.NOTIFICATION_ID OFFSET ? ROWS FETCH NEXT ? ROWS ONLY"; + sql = sql + " ORDER BY n1.NOTIFICATION_ID DESC OFFSET ? ROWS FETCH NEXT ? ROWS ONLY"; stmt = conn.prepareStatement(sql); stmt.setInt(1, tenantId); @@ -92,7 +92,7 @@ public class SQLServerNotificationDAOImpl extends AbstractNotificationDAOImpl { "TENANT_ID = ? AND STATUS = ?) n1 WHERE n1.DEVICE_ID = d.ID AND d.DEVICE_TYPE_ID=t.ID " + "AND TENANT_ID = ?"; - sql = sql + " ORDER BY n1.NOTIFICATION_ID OFFSET ? ROWS FETCH NEXT ? ROWS ONLY"; + sql = sql + " ORDER BY n1.NOTIFICATION_ID DESC OFFSET ? ROWS FETCH NEXT ? ROWS ONLY"; stmt = conn.prepareStatement(sql); stmt.setInt(1, tenantId); diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/otp/mgt/dao/AbstractDAOImpl.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/otp/mgt/dao/AbstractDAOImpl.java new file mode 100644 index 0000000000..ea9faf7ee0 --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/otp/mgt/dao/AbstractDAOImpl.java @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2019, Entgra (pvt) Ltd. (http://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.otp.mgt.dao; + +import org.wso2.carbon.device.mgt.common.exceptions.DBConnectionException; +import org.wso2.carbon.device.mgt.core.otp.mgt.util.ConnectionManagerUtil; + +import java.sql.Connection; + +/** + * This class deals with getting the DB connection. + */ +public abstract class AbstractDAOImpl { + + protected Connection getDBConnection() throws DBConnectionException { + return ConnectionManagerUtil.getDBConnection(); + } +} diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/otp/mgt/dao/OTPManagementDAO.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/otp/mgt/dao/OTPManagementDAO.java new file mode 100644 index 0000000000..4c3690f5d0 --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/otp/mgt/dao/OTPManagementDAO.java @@ -0,0 +1,64 @@ +/* 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.otp.mgt.dao; + +import org.wso2.carbon.device.mgt.common.otp.mgt.dto.OneTimePinDTO; +import org.wso2.carbon.device.mgt.core.otp.mgt.exception.OTPManagementDAOException; + +public interface OTPManagementDAO { + + /** + * Save OTP token data and tenant details of registering user + * @param oneTimePinDTO OTPMailDTO + * @return Primary key of the newly adding data raw + * @throws OTPManagementDAOException if error occurred whule storing data + */ + int addOTPData(OneTimePinDTO oneTimePinDTO) throws OTPManagementDAOException; + + /** + * Get OTP data for requesting One Time Token + * @param oneTimeToken One Time Token + * @return {@link OneTimePinDTO} + * @throws OTPManagementDAOException if error ocured while getting OTP data for requesting one time token + */ + OneTimePinDTO getOTPDataByToken (String oneTimeToken) throws OTPManagementDAOException; + + /** + * Expire the OTP + * @param oneTimeToken OTP + * @throws OTPManagementDAOException if error occurred while updating the OTP validity. + */ + boolean expireOneTimeToken(String oneTimeToken) throws OTPManagementDAOException; + + /** + * Update OTP with renewed OTP + * @param id ID + * @param oneTimeToken One Time Token + * @throws OTPManagementDAOException if error occured while updating OTP + */ + void renewOneTimeToken(int id, String oneTimeToken) throws OTPManagementDAOException; + + /** + * To veify whether email and email type exists or not + * @param email email + * @param emailType email type + * @return true if email and email type exists otherwise returns false + * @throws OTPManagementDAOException if error occurred while verify existance of the email and email type + */ + boolean isEmailExist (String email, String emailType) throws OTPManagementDAOException; +} diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/otp/mgt/dao/OTPManagementDAOFactory.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/otp/mgt/dao/OTPManagementDAOFactory.java new file mode 100644 index 0000000000..5d7ca6c585 --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/otp/mgt/dao/OTPManagementDAOFactory.java @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2020, Entgra (pvt) Ltd. (http://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.otp.mgt.dao; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.wso2.carbon.device.mgt.common.DeviceManagementConstants; +import org.wso2.carbon.device.mgt.common.exceptions.UnsupportedDatabaseEngineException; +import org.wso2.carbon.device.mgt.core.otp.mgt.dao.impl.GenericOTPManagementDAOImpl; +import org.wso2.carbon.device.mgt.core.otp.mgt.dao.impl.OracleOTPManagementDAOImpl; +import org.wso2.carbon.device.mgt.core.otp.mgt.dao.impl.PostgreSQLOTPManagementDAOImpl; +import org.wso2.carbon.device.mgt.core.otp.mgt.dao.impl.SQLServerOTPManagementDAOImpl; +import org.wso2.carbon.device.mgt.core.otp.mgt.util.ConnectionManagerUtil; + +import javax.sql.DataSource; +import java.sql.Connection; +import java.sql.SQLException; + +/** + * This class intends to act as the primary entity that hides all DAO instantiation related complexities and logic so + * that the business objection handling layer doesn't need to be aware of the same providing seamless plug-ability of + * different data sources, connection acquisition mechanisms as well as different forms of DAO implementations to the + * high-level implementations that require Application management related metadata persistence. + */ +public class OTPManagementDAOFactory { + + private static String databaseEngine; + private static final Log log = LogFactory.getLog(OTPManagementDAOFactory.class); + + public static void init(String datasourceName) { + ConnectionManagerUtil.resolveDataSource(datasourceName); + databaseEngine = ConnectionManagerUtil.getDatabaseType(); + } + + public static void init(DataSource dtSource) { + try (Connection connection = dtSource.getConnection()) { + databaseEngine = connection.getMetaData().getDatabaseProductName(); + } catch (SQLException e) { + log.error("Error occurred while retrieving config.datasource connection", e); + } + } + + public static OTPManagementDAO getOTPManagementDAO() { + if (databaseEngine != null) { + switch (databaseEngine) { + case DeviceManagementConstants.DataBaseTypes.DB_TYPE_H2: + case DeviceManagementConstants.DataBaseTypes.DB_TYPE_MYSQL: + return new GenericOTPManagementDAOImpl(); + case DeviceManagementConstants.DataBaseTypes.DB_TYPE_POSTGRESQL: + return new PostgreSQLOTPManagementDAOImpl(); + case DeviceManagementConstants.DataBaseTypes.DB_TYPE_MSSQL: + return new SQLServerOTPManagementDAOImpl(); + case DeviceManagementConstants.DataBaseTypes.DB_TYPE_ORACLE: + return new OracleOTPManagementDAOImpl(); + default: + throw new UnsupportedDatabaseEngineException("Unsupported database engine : " + databaseEngine); + } + } + throw new IllegalStateException("Database engine has not initialized properly."); + } +} diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/otp/mgt/dao/impl/GenericOTPManagementDAOImpl.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/otp/mgt/dao/impl/GenericOTPManagementDAOImpl.java new file mode 100644 index 0000000000..273cf6c1a5 --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/otp/mgt/dao/impl/GenericOTPManagementDAOImpl.java @@ -0,0 +1,243 @@ +/* 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.otp.mgt.dao.impl; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.wso2.carbon.device.mgt.common.exceptions.DBConnectionException; +import org.wso2.carbon.device.mgt.common.otp.mgt.dto.OneTimePinDTO; +import org.wso2.carbon.device.mgt.core.otp.mgt.dao.AbstractDAOImpl; +import org.wso2.carbon.device.mgt.core.otp.mgt.dao.OTPManagementDAO; +import org.wso2.carbon.device.mgt.core.otp.mgt.exception.OTPManagementDAOException; + +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Statement; +import java.sql.Timestamp; +import java.util.Calendar; + +public class GenericOTPManagementDAOImpl extends AbstractDAOImpl implements OTPManagementDAO { + + private static final Log log = LogFactory.getLog(GenericOTPManagementDAOImpl.class); + + @Override + public int addOTPData(OneTimePinDTO oneTimePinDTO) throws OTPManagementDAOException { + if (log.isDebugEnabled()) { + log.debug("Request received in DAO Layer to create an OTP data entry"); + log.debug("OTP Details : "); + log.debug("OTP key : " + oneTimePinDTO.getOtpToken() + " Email : " + oneTimePinDTO.getEmail()); + } + + String sql = "INSERT INTO DM_OTP_DATA " + + "(OTP_TOKEN, " + + "EMAIL, " + + "EMAIL_TYPE, " + + "META_INFO, " + + "CREATED_AT," + + "TENANT_ID," + + "USERNAME) VALUES (?, ?, ?, ?, ?, ?, ?)"; + try { + Connection conn = this.getDBConnection(); + Calendar calendar = Calendar.getInstance(); + Timestamp timestamp = new Timestamp(calendar.getTime().getTime()); + try (PreparedStatement stmt = conn.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS)) { + stmt.setString(1, oneTimePinDTO.getOtpToken()); + stmt.setString(2, oneTimePinDTO.getEmail()); + stmt.setString(3, oneTimePinDTO.getEmailType()); + stmt.setString(4, oneTimePinDTO.getMetaInfo()); + stmt.setTimestamp(5, timestamp); + stmt.setInt(6, oneTimePinDTO.getTenantId()); + stmt.setString(7, oneTimePinDTO.getUsername()); + stmt.executeUpdate(); + try (ResultSet rs = stmt.getGeneratedKeys()) { + if (rs.next()) { + return rs.getInt(1); + } + return -1; + } + } + } catch (DBConnectionException e) { + String msg = "Error occurred while obtaining the DB connection to create an opt entry for email " + + oneTimePinDTO.getEmail(); + log.error(msg, e); + throw new OTPManagementDAOException(msg, e); + } catch (SQLException e) { + String msg = "Error occurred while executing SQL to create an otp entry for email " + oneTimePinDTO.getEmail(); + log.error(msg, e); + throw new OTPManagementDAOException(msg, e); + } + } + + @Override + public OneTimePinDTO getOTPDataByToken (String oneTimeToken) throws OTPManagementDAOException { + + if (log.isDebugEnabled()) { + log.debug("Request received in DAO Layer to get an OTP data entry for OTP"); + log.debug("OTP Details : OTP key : " + oneTimeToken ); + } + + String sql = "SELECT " + + "ID, " + + "OTP_TOKEN, " + + "EMAIL, " + + "EMAIL_TYPE, " + + "META_INFO, " + + "CREATED_AT, " + + "EXPIRY_TIME, " + + "IS_EXPIRED, " + + "TENANT_ID, " + + "USERNAME FROM DM_OTP_DATA " + + "WHERE OTP_TOKEN = ?"; + + try { + Connection conn = this.getDBConnection(); + try (PreparedStatement stmt = conn.prepareStatement(sql)) { + stmt.setString(1, oneTimeToken); + + try (ResultSet rs = stmt.executeQuery()) { + if (rs.next()) { + OneTimePinDTO oneTimePinDTO = new OneTimePinDTO(); + oneTimePinDTO.setId(rs.getInt("ID")); + oneTimePinDTO.setOtpToken(rs.getString("OTP_TOKEN")); + oneTimePinDTO.setEmail(rs.getString("EMAIL")); + oneTimePinDTO.setEmailType(rs.getString("EMAIL_TYPE")); + oneTimePinDTO.setMetaInfo(rs.getString("META_INFO")); + oneTimePinDTO.setCreatedAt(rs.getTimestamp("CREATED_AT")); + oneTimePinDTO.setExpiryTime(rs.getInt("EXPIRY_TIME")); + oneTimePinDTO.setExpired(rs.getBoolean("IS_EXPIRED")); + oneTimePinDTO.setTenantId(rs.getInt("TENANT_ID")); + oneTimePinDTO.setUsername(rs.getString("USERNAME")); + return oneTimePinDTO; + } + return null; + } + } + } catch (DBConnectionException e) { + String msg = "Error occurred while obtaining the DB connection to get OPT data for given OTP. OTP: " + + oneTimeToken; + log.error(msg, e); + throw new OTPManagementDAOException(msg, e); + } catch (SQLException e) { + String msg = "Error occurred while executing SQL to get OTP data for OTP. One time token: " + oneTimeToken; + log.error(msg, e); + throw new OTPManagementDAOException(msg, e); + } + } + + @Override + public boolean expireOneTimeToken(String oneTimeToken) throws OTPManagementDAOException { + if (log.isDebugEnabled()) { + log.debug("Request received in DAO Layer to update an OTP data entry for OTP"); + log.debug("OTP Details : OTP key : " + oneTimeToken ); + } + + String sql = "UPDATE DM_OTP_DATA " + + "SET " + + "IS_EXPIRED = ? " + + "WHERE OTP_TOKEN = ?"; + + try { + Connection conn = this.getDBConnection(); + try (PreparedStatement stmt = conn.prepareStatement(sql)) { + stmt.setBoolean(1, true); + stmt.setString(2, oneTimeToken); + return stmt.executeUpdate() == 1; + } + } catch (DBConnectionException e) { + String msg = "Error occurred while obtaining the DB connection to update the OTP token validity."; + log.error(msg, e); + throw new OTPManagementDAOException(msg, e); + } catch (SQLException e) { + String msg = "Error occurred when obtaining database connection for updating the OTP token validity."; + log.error(msg, e); + throw new OTPManagementDAOException(msg, e); + } + } + + @Override + public void renewOneTimeToken(int id, String oneTimeToken) throws OTPManagementDAOException { + if (log.isDebugEnabled()) { + log.debug("Request received in DAO Layer to update an OTP data entry for OTP"); + log.debug("OTP Details : OTP key : " + oneTimeToken ); + } + + String sql = "UPDATE DM_OTP_DATA " + + "SET " + + "OTP_TOKEN = ?, " + + "CREATED_AT = ? " + + "WHERE ID = ?"; + + try { + Connection conn = this.getDBConnection(); + Calendar calendar = Calendar.getInstance(); + Timestamp timestamp = new Timestamp(calendar.getTime().getTime()); + try (PreparedStatement stmt = conn.prepareStatement(sql)) { + stmt.setString(1, oneTimeToken); + stmt.setTimestamp(2, timestamp); + stmt.setInt(3, id); + stmt.executeUpdate(); + } + } catch (DBConnectionException e) { + String msg = "Error occurred while obtaining the DB connection to update the OTP token."; + log.error(msg, e); + throw new OTPManagementDAOException(msg, e); + } catch (SQLException e) { + String msg = "Error occurred when executing sql query to update the OTP token."; + log.error(msg, e); + throw new OTPManagementDAOException(msg, e); + } + } + + @Override + public boolean isEmailExist (String email, String emailType) throws OTPManagementDAOException { + + if (log.isDebugEnabled()) { + log.debug("Request received in DAO Layer to verify whether email was registed with emai type in OTP"); + log.debug("OTP Details : email : " + email + " email type: " + emailType ); + } + + String sql = "SELECT " + + "ID " + + "FROM DM_OTP_DATA " + + "WHERE EMAIL = ? AND " + + "EMAIL_TYPE = ?"; + + try { + Connection conn = this.getDBConnection(); + try (PreparedStatement stmt = conn.prepareStatement(sql)) { + stmt.setString(1, email); + stmt.setString(2, emailType); + try (ResultSet rs = stmt.executeQuery()) { + return rs.next(); + } + } + } catch (DBConnectionException e) { + String msg = "Error occurred while obtaining the DB connection to verify email and email type exist in OTP." + + " Email: " + email + "Email Type: " + emailType; + log.error(msg, e); + throw new OTPManagementDAOException(msg, e); + } catch (SQLException e) { + String msg = "Error occurred while executing SQL to verify email and email type exist in OTP. Email: " + + email + "Email Type: " + emailType; + log.error(msg, e); + throw new OTPManagementDAOException(msg, e); + } + } +} diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/otp/mgt/dao/impl/OracleOTPManagementDAOImpl.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/otp/mgt/dao/impl/OracleOTPManagementDAOImpl.java new file mode 100644 index 0000000000..c3feb1262d --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/otp/mgt/dao/impl/OracleOTPManagementDAOImpl.java @@ -0,0 +1,24 @@ +/* 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.otp.mgt.dao.impl; + +/** + * This handles OTP managing DAO methods which are specific to Oracle. + */ +public class OracleOTPManagementDAOImpl extends GenericOTPManagementDAOImpl{ +} diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/otp/mgt/dao/impl/PostgreSQLOTPManagementDAOImpl.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/otp/mgt/dao/impl/PostgreSQLOTPManagementDAOImpl.java new file mode 100644 index 0000000000..52d705736b --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/otp/mgt/dao/impl/PostgreSQLOTPManagementDAOImpl.java @@ -0,0 +1,25 @@ +/* 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.otp.mgt.dao.impl; + +/** + * This handles OTP managing DAO methods which are specific to PostgreSQL. + */ +public class PostgreSQLOTPManagementDAOImpl extends GenericOTPManagementDAOImpl{ + +} diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/otp/mgt/dao/impl/SQLServerOTPManagementDAOImpl.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/otp/mgt/dao/impl/SQLServerOTPManagementDAOImpl.java new file mode 100644 index 0000000000..222fc9fd7c --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/otp/mgt/dao/impl/SQLServerOTPManagementDAOImpl.java @@ -0,0 +1,24 @@ +/* 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.otp.mgt.dao.impl; + +/** + * This handles OTP managing DAO methods which are specific to MSSQL. + */ +public class SQLServerOTPManagementDAOImpl extends GenericOTPManagementDAOImpl{ +} diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/otp/mgt/exception/OTPManagementDAOException.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/otp/mgt/exception/OTPManagementDAOException.java new file mode 100644 index 0000000000..6815823bab --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/otp/mgt/exception/OTPManagementDAOException.java @@ -0,0 +1,31 @@ +/* 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.otp.mgt.exception; + +/** + * Exception thrown during the ApplicationDTO Management DAO operations. + */ +public class OTPManagementDAOException extends Exception { + + public OTPManagementDAOException(String message, Throwable throwable) { + super(message, throwable); + } + + public OTPManagementDAOException(String message) { + super(message, new Exception()); + } +} diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/otp/mgt/service/OTPManagementServiceImpl.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/otp/mgt/service/OTPManagementServiceImpl.java new file mode 100644 index 0000000000..9b25987e84 --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/otp/mgt/service/OTPManagementServiceImpl.java @@ -0,0 +1,461 @@ +/* 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.otp.mgt.service; + +import com.google.gson.Gson; +import org.apache.commons.lang.StringUtils; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.wso2.carbon.base.MultitenantConstants; +import org.wso2.carbon.context.CarbonContext; +import org.wso2.carbon.device.mgt.common.configuration.mgt.ConfigurationManagementException; +import org.wso2.carbon.device.mgt.common.exceptions.BadRequestException; +import org.wso2.carbon.device.mgt.common.exceptions.DBConnectionException; +import org.wso2.carbon.device.mgt.common.exceptions.DeviceManagementException; +import org.wso2.carbon.device.mgt.common.exceptions.OTPManagementException; +import org.wso2.carbon.device.mgt.common.exceptions.TransactionManagementException; +import org.wso2.carbon.device.mgt.common.exceptions.UnAuthorizedException; +import org.wso2.carbon.device.mgt.common.invitation.mgt.DeviceEnrollmentInvitation; +import org.wso2.carbon.device.mgt.common.invitation.mgt.DeviceEnrollmentInvitationDetails; +import org.wso2.carbon.device.mgt.common.invitation.mgt.DeviceEnrollmentType; +import org.wso2.carbon.device.mgt.common.metadata.mgt.Metadata; +import org.wso2.carbon.device.mgt.common.otp.mgt.OTPEmailTypes; +import org.wso2.carbon.device.mgt.common.otp.mgt.dto.OneTimePinDTO; +import org.wso2.carbon.device.mgt.common.spi.OTPManagementService; +import org.wso2.carbon.device.mgt.core.DeviceManagementConstants; +import org.wso2.carbon.device.mgt.core.config.DeviceConfigurationManager; +import org.wso2.carbon.device.mgt.core.config.DeviceManagementConfig; +import org.wso2.carbon.device.mgt.core.config.keymanager.KeyManagerConfigurations; +import org.wso2.carbon.device.mgt.core.internal.DeviceManagementDataHolder; +import org.wso2.carbon.device.mgt.core.otp.mgt.dao.OTPManagementDAO; +import org.wso2.carbon.device.mgt.common.otp.mgt.wrapper.OTPWrapper; +import org.wso2.carbon.device.mgt.core.otp.mgt.dao.OTPManagementDAOFactory; +import org.wso2.carbon.device.mgt.core.otp.mgt.exception.OTPManagementDAOException; +import org.wso2.carbon.device.mgt.core.otp.mgt.util.ConnectionManagerUtil; +import org.wso2.carbon.device.mgt.core.service.DeviceManagementProviderService; +import org.wso2.carbon.device.mgt.core.service.EmailMetaInfo; +import org.apache.commons.validator.routines.EmailValidator; +import org.wso2.carbon.device.mgt.core.util.DeviceManagerUtil; +import org.wso2.carbon.user.api.Tenant; +import org.wso2.carbon.user.api.UserStoreException; + +import static org.wso2.carbon.device.mgt.common.DeviceManagementConstants.OTPProperties; + +import java.sql.Timestamp; +import java.util.Calendar; +import java.util.List; +import java.util.Map; +import java.util.Properties; +import java.util.UUID; + +public class OTPManagementServiceImpl implements OTPManagementService { + + private static final Log log = LogFactory.getLog(OTPManagementServiceImpl.class); + private OTPManagementDAO otpManagementDAO; + + public OTPManagementServiceImpl() { + initDataAccessObjects(); + } + + private void initDataAccessObjects() { + otpManagementDAO = OTPManagementDAOFactory.getOTPManagementDAO(); + } + + @Override + public void sendUserVerifyingMail(OTPWrapper otpWrapper) throws OTPManagementException, DeviceManagementException { + Tenant tenant = validateTenantCreatingDetails(otpWrapper); + OneTimePinDTO oneTimePinDTO = createOneTimePin(otpWrapper.getEmail(), otpWrapper.getEmailType(), + otpWrapper.getUsername(), tenant, -1234); + try { + ConnectionManagerUtil.beginDBTransaction(); + if (this.otpManagementDAO.addOTPData(oneTimePinDTO) == -1) { + ConnectionManagerUtil.rollbackDBTransaction(); + String msg = "OTP data saving failed. Please, contact Administrator"; + log.error(msg); + throw new OTPManagementException(msg); + } + Properties props = new Properties(); + props.setProperty("first-name", tenant.getAdminFirstName()); + props.setProperty("otp-token", oneTimePinDTO.getOtpToken()); + sendMail(props, tenant.getEmail(), DeviceManagementConstants.EmailAttributes.USER_VERIFY_TEMPLATE); + ConnectionManagerUtil.commitDBTransaction(); + } catch (TransactionManagementException e) { + String msg = "Error occurred while disabling AutoCommit."; + log.error(msg, e); + throw new OTPManagementException(msg, e); + } catch (DBConnectionException e) { + String msg = "Error occurred while getting database connection."; + log.error(msg, e); + throw new OTPManagementException(msg, e); + } catch (OTPManagementDAOException e) { + ConnectionManagerUtil.rollbackDBTransaction(); + String msg = "Error occurred while saving the OTP data. Email address: " + oneTimePinDTO.getEmail(); + log.error(msg, e); + throw new OTPManagementException(msg, e); + } finally { + ConnectionManagerUtil.closeDBConnection(); + } + } + + @Override + public OneTimePinDTO isValidOTP(String oneTimeToken) throws OTPManagementException, BadRequestException { + if (StringUtils.isBlank(oneTimeToken)){ + String msg = "Received blank OTP to verify. OTP: " + oneTimeToken; + log.error(msg); + throw new BadRequestException(msg); + } + + OneTimePinDTO oneTimePinDTO = getOTPDataByToken(oneTimeToken); + if (oneTimePinDTO == null) { + String msg = "Couldn't found OTP data for the requesting OTP " + oneTimeToken + " In the system."; + log.error(msg); + throw new BadRequestException(msg); + } + if (oneTimePinDTO.isExpired()) { + log.warn("Token is expired. OTP: " + oneTimeToken); + return null; + } + + Calendar calendar = Calendar.getInstance(); + Timestamp currentTimestamp = new Timestamp(calendar.getTime().getTime()); + Timestamp expiredTimestamp = new Timestamp( + oneTimePinDTO.getCreatedAt().getTime() + oneTimePinDTO.getExpiryTime() * 1000); + + if (currentTimestamp.after(expiredTimestamp)) { + String renewedOTP = UUID.randomUUID().toString(); + renewOTP(oneTimePinDTO, renewedOTP); + Gson gson = new Gson(); + Tenant tenant = gson.fromJson(oneTimePinDTO.getMetaInfo(), Tenant.class); + + Properties props = new Properties(); + props.setProperty("first-name", tenant.getAdminFirstName()); + props.setProperty("otp-token", renewedOTP); + sendMail(props, oneTimePinDTO.getEmail(), DeviceManagementConstants.EmailAttributes.USER_VERIFY_TEMPLATE); + return null; + } + return oneTimePinDTO; + } + + @Override + public void completeSelfRegistration(String oneTimeToken, String email, Map properties) + throws OTPManagementException { + try { + invalidateOTP(oneTimeToken); + Properties props = new Properties(); + properties.forEach(props::setProperty); + sendMail(props, email, DeviceManagementConstants.EmailAttributes.USER_WELCOME_TEMPLATE); + } catch (OTPManagementException e) { + String msg = "Error occurred while completing the self registration via OTP"; + log.error(msg, e); + throw new OTPManagementException(msg, e); + } + } + + /** + * Invalidate the OTP + * @param oneTimeToken OTP + * @throws OTPManagementException If error occurred while invalidating the OTP + */ + private void invalidateOTP(String oneTimeToken) throws OTPManagementException { + try { + ConnectionManagerUtil.beginDBTransaction(); + if (!otpManagementDAO.expireOneTimeToken(oneTimeToken)) { + ConnectionManagerUtil.rollbackDBTransaction(); + String msg = "Couldn't find OTP entry for OTP: " + oneTimeToken; + log.error(msg); + throw new OTPManagementException(msg); + } + ConnectionManagerUtil.commitDBTransaction(); + } catch (OTPManagementDAOException e) { + ConnectionManagerUtil.rollbackDBTransaction(); + String msg = "Error occurred while invalidate the OTP: " + oneTimeToken; + log.error(msg); + throw new OTPManagementException(msg); + } catch (TransactionManagementException e) { + String msg = "Error occurred while disabling AutoCommit to invalidate OTP."; + log.error(msg, e); + throw new OTPManagementException(msg, e); + } catch (DBConnectionException e) { + String msg = "Error occurred while getting database connection to invalidate OPT."; + log.error(msg, e); + throw new OTPManagementException(msg, e); + } finally { + ConnectionManagerUtil.closeDBConnection(); + } + } + + + @Override + public void sendDeviceEnrollmentInvitationMail(DeviceEnrollmentInvitation deviceEnrollmentInvitation) + throws OTPManagementException { + DeviceManagementProviderService dms = DeviceManagementDataHolder.getInstance().getDeviceManagementProvider(); + StringBuilder enrollmentSteps = new StringBuilder(); + DeviceEnrollmentInvitationDetails deviceEnrollmentInvitationDetails; + for (DeviceEnrollmentType deviceEnrollmentType : deviceEnrollmentInvitation.getDeviceEnrollmentTypes()) { + deviceEnrollmentInvitationDetails = dms.getDeviceEnrollmentInvitationDetails( + deviceEnrollmentType.getDeviceType()); + if (deviceEnrollmentInvitationDetails != null && + deviceEnrollmentInvitationDetails.getEnrollmentDetails() != null) { + for (String enrollmentType : deviceEnrollmentType.getEnrollmentType()) { + deviceEnrollmentInvitationDetails.getEnrollmentDetails().stream() + .filter(details -> enrollmentType.equals(details.getEnrollmentType())).findFirst() + .ifPresent(details -> enrollmentSteps.append(details.getEnrollmentSteps())); + } + } + } + int tenantId = CarbonContext.getThreadLocalCarbonContext().getTenantId(); + OneTimePinDTO oneTimePinDTO; + Properties props = new Properties(); + props.setProperty("enrollment-steps", enrollmentSteps.toString()); + try { + for (String username : deviceEnrollmentInvitation.getUsernames()) { + String emailAddress = DeviceManagerUtil.getUserClaimValue( + username, DeviceManagementConstants.User.CLAIM_EMAIL_ADDRESS); + oneTimePinDTO = createOneTimePin(emailAddress, OTPEmailTypes.DEVICE_ENROLLMENT.toString(), username, + null, tenantId); + props.setProperty("first-name", DeviceManagerUtil. + getUserClaimValue(username, DeviceManagementConstants.User.CLAIM_FIRST_NAME)); + props.setProperty("username", username); + props.setProperty("otp-token", oneTimePinDTO.getOtpToken()); + sendMail(props, emailAddress, DeviceManagementConstants.EmailAttributes.USER_ENROLLMENT_TEMPLATE); + } + } catch (UserStoreException e) { + String msg = "Error occurred while getting claim values to invite user"; + log.error(msg, e); + throw new OTPManagementException(msg, e); + } + } + + + /** + * Create One Time Token + * @param email email + * @param emailType email type + * @param userName username + * @param metaDataObj meta data object + * @param tenantId tenant Id + * @return {@link OneTimePinDTO} + */ + private OneTimePinDTO createOneTimePin(String email, String emailType, String userName, Object metaDataObj, + int tenantId) { + + String otpValue = UUID.randomUUID().toString(); + + Gson gson = new Gson(); + String metaInfo = gson.toJson(metaDataObj); + + OneTimePinDTO oneTimePinDTO = new OneTimePinDTO(); + oneTimePinDTO.setEmail(email); + oneTimePinDTO.setTenantId(tenantId); + oneTimePinDTO.setUsername(userName); + oneTimePinDTO.setEmailType(emailType); + oneTimePinDTO.setMetaInfo(metaInfo); + oneTimePinDTO.setOtpToken(otpValue); + + return oneTimePinDTO; + } + + /** + * Get OTPData from DB + * @param oneTimeToken One Time Token + * @return {@link OneTimePinDTO} + * @throws OTPManagementException if error occurred while getting OTP data for given OTP in DB + */ + private OneTimePinDTO getOTPDataByToken ( String oneTimeToken) throws OTPManagementException { + try { + ConnectionManagerUtil.openDBConnection(); + return otpManagementDAO.getOTPDataByToken(oneTimeToken); + } catch (DBConnectionException e) { + String msg = "Error occurred while getting database connection to validate the given OTP."; + log.error(msg, e); + throw new OTPManagementException(msg, e); + } catch (OTPManagementDAOException e) { + String msg = "Error occurred while getting OTP data from DB. OTP: " + oneTimeToken; + log.error(msg, e); + throw new OTPManagementException(msg, e); + } finally { + ConnectionManagerUtil.closeDBConnection(); + } + } + + /** + * Validate Tenant details + * @param otpWrapper OTP-Wrapper + * @return {@link Tenant} if its valid payload otherwise throws {@link DeviceManagementException} + * @throws DeviceManagementException if invalid payload or unauthorized request received + */ + private Tenant validateTenantCreatingDetails(OTPWrapper otpWrapper) throws DeviceManagementException { + + DeviceManagementConfig deviceManagementConfig = DeviceConfigurationManager.getInstance() + .getDeviceManagementConfig(); + KeyManagerConfigurations kmConfig = deviceManagementConfig.getKeyManagerConfigurations(); + + if (StringUtils.isBlank(otpWrapper.getUsername())) { + String msg = "Received Blank username to create OTP. Username: " + otpWrapper.getUsername(); + log.error(msg); + throw new BadRequestException(msg); + } + + String[] superTenantDetails = otpWrapper.getUsername().split("@"); + if (!MultitenantConstants.SUPER_TENANT_DOMAIN_NAME.equals(superTenantDetails[superTenantDetails.length - 1]) + || !superTenantDetails[0].equals(kmConfig.getAdminUsername())) { + String msg = "You don't have required permission to create OTP"; + log.error(msg); + throw new UnAuthorizedException(msg); + } + + Tenant tenant = new Tenant(); + List properties = otpWrapper.getProperties(); + for (Metadata property : properties) { + if (property == null) { + String msg = "Received invalid property to create OTP."; + log.error(msg); + throw new BadRequestException(msg); + } + switch (property.getMetaKey()) { + case OTPProperties.FIRST_NAME: + String firstName = property.getMetaValue(); + if (StringUtils.isBlank(firstName)) { + String msg = "Received empty or blank first name field with OTP creating payload."; + log.error(msg); + throw new BadRequestException(msg); + } + tenant.setAdminFirstName(firstName); + break; + case OTPProperties.LAST_NAME: + String lastName = property.getMetaValue(); + if (StringUtils.isBlank(lastName)) { + String msg = "Received empty or blank last name field with OTP creating payload."; + log.error(msg); + throw new BadRequestException(msg); + } + tenant.setAdminLastName(lastName); + break; + case OTPProperties.TENANT_ADMIN_PASSWORD: + String pwd = property.getMetaValue(); + if (StringUtils.isBlank(pwd)) { + String msg = "Received empty or blank admin password field with OTP creating payload."; + log.error(msg); + throw new BadRequestException(msg); + } + tenant.setAdminPassword(pwd); + break; + default: + String msg = "Received invalid key with OTP properties for creating OTP."; + log.error(msg); + throw new BadRequestException(msg); + } + } + + if (StringUtils.isBlank(otpWrapper.getEmail())) { + String msg = "Received empty or blank email field with OTP creating payload."; + log.error(msg); + throw new BadRequestException(msg); + } + + EmailValidator validator = EmailValidator.getInstance(); + if (!validator.isValid(otpWrapper.getEmail())) { + String msg = "Found invalid email. Hence please verify the email address and re-try. Email: " + otpWrapper + .getEmail(); + log.error(msg); + throw new BadRequestException(msg); + } + + if (StringUtils.isBlank(otpWrapper.getEmailType())) { + String msg = "Received empty or blank email type field with OTP creating payload."; + log.error(msg); + throw new BadRequestException(msg); + } + + try { + ConnectionManagerUtil.openDBConnection(); + if (otpManagementDAO.isEmailExist(otpWrapper.getEmail(), otpWrapper.getEmailType())) { + String msg = "Email is registered to execute the same action. Hence can't proceed."; + log.error(msg); + throw new BadRequestException(msg); + } + } catch (DBConnectionException e) { + String msg = "Error occurred while getting database connection to validate the given email and email type."; + log.error(msg); + throw new DeviceManagementException(msg); + } catch (OTPManagementDAOException e) { + String msg = "Error occurred while executing SQL query to validate the given email and email type."; + log.error(msg); + throw new DeviceManagementException(msg); + } finally { + ConnectionManagerUtil.closeDBConnection(); + } + + String[] tenantUsernameDetails = otpWrapper.getEmail().split("@"); + tenant.setAdminName(tenantUsernameDetails[0]); + tenant.setDomain(tenantUsernameDetails[tenantUsernameDetails.length - 1]); + tenant.setEmail(otpWrapper.getEmail()); + return tenant; + } + + /** + * If OTP expired, resend the user verifying mail with renewed OTP + * @param props Mail body properties + * @param mailAddress Mail Address of the User + * @param template Mail template to be used + * @throws OTPManagementException if error occurred while resend the user verifying mail + */ + private void sendMail(Properties props, String mailAddress, String template) throws OTPManagementException { + try { + EmailMetaInfo metaInfo = new EmailMetaInfo(mailAddress, props); + DeviceManagementDataHolder.getInstance().getDeviceManagementProvider() + .sendEnrolmentInvitation(template, metaInfo); + } catch (DeviceManagementException e) { + String msg = "Error occurred while sending email using email template '" + template + "'."; + log.error(msg, e); + throw new OTPManagementException(msg, e); + } catch (ConfigurationManagementException e) { + String msg = "Configuration error occurred. Hence mail sending failed."; + log.error(msg, e); + throw new OTPManagementException(msg, e); + } + } + + /** + * Renew the OTP + * @param oneTimePinDTO {@link OneTimePinDTO} + * @param renewedOTP Renewed OTP + * @throws OTPManagementException if error occurred while renew the OTP + */ + private void renewOTP(OneTimePinDTO oneTimePinDTO, String renewedOTP) throws OTPManagementException { + try { + ConnectionManagerUtil.beginDBTransaction(); + this.otpManagementDAO.renewOneTimeToken(oneTimePinDTO.getId(), renewedOTP); + ConnectionManagerUtil.commitDBTransaction(); + } catch (TransactionManagementException e) { + String msg = "Error occurred while disabling AutoCommit to renew the OTP."; + log.error(msg, e); + throw new OTPManagementException(msg, e); + } catch (DBConnectionException e) { + String msg = "Error occurred while getting database connection to renew the OTP."; + log.error(msg, e); + throw new OTPManagementException(msg, e); + } catch (OTPManagementDAOException e) { + ConnectionManagerUtil.rollbackDBTransaction(); + String msg = "Error occurred while renew the OTP. OTP: " + renewedOTP; + log.error(msg, e); + throw new OTPManagementException(msg, e); + } finally { + ConnectionManagerUtil.closeDBConnection(); + } + } +} diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/otp/mgt/util/ConnectionManagerUtil.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/otp/mgt/util/ConnectionManagerUtil.java new file mode 100644 index 0000000000..9db3784dd5 --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/otp/mgt/util/ConnectionManagerUtil.java @@ -0,0 +1,211 @@ +/* + * Copyright (c) 2020, Entgra (pvt) Ltd. (http://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.otp.mgt.util; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.wso2.carbon.device.mgt.common.exceptions.DBConnectionException; +import org.wso2.carbon.device.mgt.common.exceptions.TransactionManagementException; +import org.wso2.carbon.device.mgt.common.exceptions.IllegalTransactionStateException; + +import javax.naming.InitialContext; +import javax.sql.DataSource; +import java.sql.Connection; +import java.sql.SQLException; + +/** + * ConnectionManagerUtil is responsible for handling all the datasource connections utilities. + */ +public class ConnectionManagerUtil { + + private static final Log log = LogFactory.getLog(ConnectionManagerUtil.class); + private static final ThreadLocal currentConnection = new ThreadLocal<>(); + private static DataSource dataSource; + + public static void openDBConnection() throws DBConnectionException { + Connection conn = currentConnection.get(); + if (conn != null) { + String msg = "Database connection has already been obtained."; + log.error(msg); + throw new IllegalTransactionStateException(msg); + } + try { + conn = dataSource.getConnection(); + } catch (SQLException e) { + String msg = "Failed to get a database connection."; + log.error(msg, e); + throw new DBConnectionException(msg, e); + } + currentConnection.set(conn); + } + + public static Connection getDBConnection() throws DBConnectionException { + Connection conn = currentConnection.get(); + if (conn == null) { + try { + conn = dataSource.getConnection(); + currentConnection.set(conn); + } catch (SQLException e) { + throw new DBConnectionException("Failed to get database connection.", e); + } + } + return conn; + } + + public static void beginDBTransaction() throws TransactionManagementException, DBConnectionException { + Connection conn = currentConnection.get(); + if (conn == null) { + conn = getDBConnection(); + } else if (inTransaction(conn)) { + String msg = "Transaction has already been started."; + log.error(msg); + throw new IllegalTransactionStateException(msg); + } + + try { + conn.setAutoCommit(false); + } catch (SQLException e) { + String msg = "Error occurred while starting a database transaction."; + log.error(msg, e); + throw new TransactionManagementException(msg, e); + } + } + + public static void endDBTransaction() throws TransactionManagementException { + Connection conn = currentConnection.get(); + if (conn == null) { + throw new IllegalTransactionStateException("Database connection is not active."); + } + + if (!inTransaction(conn)) { + throw new IllegalTransactionStateException("Transaction has not been started."); + } + + try { + conn.setAutoCommit(true); + } catch (SQLException e) { + throw new TransactionManagementException("Error occurred while ending database transaction.", e); + } + } + + public static void commitDBTransaction() { + Connection conn = currentConnection.get(); + if (conn == null) { + throw new IllegalTransactionStateException("Database connection is not active."); + } + + if (!inTransaction(conn)) { + throw new IllegalTransactionStateException("Transaction has not been started."); + } + + try { + conn.commit(); + } catch (SQLException e) { + log.error("Error occurred while committing the transaction", e); + } + } + + public static void rollbackDBTransaction() { + Connection conn = currentConnection.get(); + if (conn == null) { + throw new IllegalTransactionStateException("Database connection is not active."); + } + + if (!inTransaction(conn)) { + throw new IllegalTransactionStateException("Transaction has not been started."); + } + + try { + conn.rollback(); + } catch (SQLException e) { + log.warn("Error occurred while roll-backing the transaction", e); + } + } + + public static void closeDBConnection() { + Connection conn = currentConnection.get(); + if (conn == null) { + throw new IllegalTransactionStateException("Database connection is not active."); + } + try { + conn.close(); + } catch (SQLException e) { + log.error("Error occurred while closing the connection", e); + } + currentConnection.remove(); + } + + private static boolean inTransaction(Connection conn) { + boolean inTransaction = true; + try { + if (conn.getAutoCommit()) { + inTransaction = false; + } + } catch (SQLException e) { + throw new IllegalTransactionStateException("Failed to get transaction state."); + } + return inTransaction; + } + + public static boolean isTransactionStarted() throws DBConnectionException { + Connection connection = getDBConnection(); + return inTransaction(connection); + } + + /** + * Resolve the datasource from the datasource definition. + * + * @param dataSourceName Name of the datasource + * @return DataSource resolved by the datasource name + */ + public static DataSource resolveDataSource(String dataSourceName) { + try { + dataSource = InitialContext.doLookup(dataSourceName); + } catch (Exception e) { + throw new RuntimeException("Error in looking up data source: " + e.getMessage(), e); + } + return dataSource; + } + + public static String getDatabaseType() { + try (Connection connection = dataSource.getConnection()) { + return connection.getMetaData().getDatabaseProductName(); + } catch (SQLException e) { + log.error("Error occurred while retrieving config.datasource connection", e); + } + return null; + } + + /** + * To check whether particular database that is used for application management supports batch query execution. + * + * @return true if batch query is supported, otherwise false. + */ + public static boolean isBatchQuerySupported() { + try (Connection connection = dataSource.getConnection()) { + return connection.getMetaData().supportsBatchUpdates(); + } catch (SQLException e) { + log.error("Error occurred while checking whether database supports batch updates", e); + } + return false; + } + + public static void init(DataSource dtSource) { + dataSource = dtSource; + } +} diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/service/DeviceManagementProviderService.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/service/DeviceManagementProviderService.java index 54c7c04805..3a79a9cd42 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/service/DeviceManagementProviderService.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/service/DeviceManagementProviderService.java @@ -14,8 +14,8 @@ * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. - */ -/* + * + * * Copyright (c) 2019, Entgra (pvt) Ltd. (http://entgra.io) All Rights Reserved. * * Entgra (pvt) Ltd. licenses this file to you under the Apache License, @@ -32,23 +32,6 @@ * specific language governing permissions and limitations * under the License. */ -/* - * Copyright (c) 2020, Entgra (pvt) Ltd. (http://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.service; @@ -76,6 +59,7 @@ import org.wso2.carbon.device.mgt.common.configuration.mgt.ConfigurationManageme import org.wso2.carbon.device.mgt.common.configuration.mgt.DeviceConfiguration; import org.wso2.carbon.device.mgt.common.configuration.mgt.PlatformConfiguration; import org.wso2.carbon.device.mgt.common.device.details.DeviceData; +import org.wso2.carbon.device.mgt.common.invitation.mgt.DeviceEnrollmentInvitationDetails; import org.wso2.carbon.device.mgt.common.license.mgt.License; import org.wso2.carbon.device.mgt.common.operation.mgt.Activity; import org.wso2.carbon.device.mgt.common.operation.mgt.Operation; @@ -89,7 +73,6 @@ import org.wso2.carbon.device.mgt.core.dto.DeviceType; import org.wso2.carbon.device.mgt.core.dto.DeviceTypeVersion; import org.wso2.carbon.device.mgt.core.geo.GeoCluster; import org.wso2.carbon.device.mgt.core.geo.geoHash.GeoCoordinate; -import org.wso2.carbon.device.mgt.core.operation.mgt.CommandOperation; import java.sql.SQLException; import java.util.Date; @@ -927,4 +910,12 @@ public interface DeviceManagementProviderService { */ List getDeviceByIdList(List deviceIdentifiers) throws DeviceManagementException; + + /** + * Retrieve device enrollment details to be sent device enrollment invitation. + * This has the relevant enrollment steps of each enrollment types. + * @param deviceType Device type of the required device enrollment details + * @return enrollment steps of each enrollment types which are provided in the device type xml file + */ + DeviceEnrollmentInvitationDetails getDeviceEnrollmentInvitationDetails(String deviceType); } diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/service/DeviceManagementProviderServiceImpl.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/service/DeviceManagementProviderServiceImpl.java index 1ad270361b..5e28129390 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/service/DeviceManagementProviderServiceImpl.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/service/DeviceManagementProviderServiceImpl.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.service; @@ -74,6 +91,7 @@ import org.wso2.carbon.device.mgt.common.group.mgt.DeviceGroup; import org.wso2.carbon.device.mgt.common.group.mgt.DeviceGroupConstants; import org.wso2.carbon.device.mgt.common.group.mgt.GroupAlreadyExistException; import org.wso2.carbon.device.mgt.common.group.mgt.GroupManagementException; +import org.wso2.carbon.device.mgt.common.invitation.mgt.DeviceEnrollmentInvitationDetails; import org.wso2.carbon.device.mgt.common.license.mgt.License; import org.wso2.carbon.device.mgt.common.license.mgt.LicenseManagementException; import org.wso2.carbon.device.mgt.common.operation.mgt.Activity; @@ -226,8 +244,7 @@ public class DeviceManagementProviderServiceImpl implements DeviceManagementProv } return false; } - EnrollmentConfiguration enrollmentConfiguration = DeviceManagerUtil.getEnrollmentConfigurationEntry( - this.getConfiguration(device.getType())); + EnrollmentConfiguration enrollmentConfiguration = DeviceManagerUtil.getEnrollmentConfigurationEntry(); String deviceSerialNumber = null; if (enrollmentConfiguration != null) { deviceSerialNumber = DeviceManagerUtil.getPropertyString(device.getProperties(), @@ -4188,4 +4205,11 @@ public class DeviceManagementProviderServiceImpl implements DeviceManagementProv DeviceManagementDAOFactory.closeConnection(); } } + + @Override + public DeviceEnrollmentInvitationDetails getDeviceEnrollmentInvitationDetails(String deviceType) { + int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(); + DeviceManagementService dms = pluginRepository.getDeviceManagementService(deviceType, tenantId); + return dms.getDeviceEnrollmentInvitationDetails(); + } } 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 92fac25875..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,12 +14,28 @@ * 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; import com.fasterxml.jackson.databind.ObjectMapper; import com.google.gson.Gson; -import org.apache.commons.lang.StringUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.http.HttpResponse; @@ -80,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; @@ -887,21 +904,15 @@ public final class DeviceManagerUtil { /** * Retrieve the Enrollment Configuration entry added to the Platform Configuration - * @param platformConfiguration which has all the platform configurations added to the tenant * @return enrollment configuration */ - public static EnrollmentConfiguration getEnrollmentConfigurationEntry(PlatformConfiguration platformConfiguration) { - if (platformConfiguration != null) { - String enrollmentConfigEntry = platformConfiguration.getConfiguration().stream() - .filter(configurationEntry -> DeviceManagementConstants.Common.ENROLLMENT_CONFIGURATION - .equals(configurationEntry.getName())) - .findFirst() - .map(configurationEntry -> configurationEntry.getValue().toString()).orElse(null); - if (!StringUtils.isBlank(enrollmentConfigEntry)) { + public static EnrollmentConfiguration getEnrollmentConfigurationEntry() { + Object enrollmentConfigEntry = DeviceManagerUtil.getConfiguration( + DeviceManagementConstants.Common.ENROLLMENT_CONFIGURATION); + if (enrollmentConfigEntry != null) { Gson gson = new Gson(); - return gson.fromJson(enrollmentConfigEntry, EnrollmentConfiguration.class); + return gson.fromJson(enrollmentConfigEntry.toString(), EnrollmentConfiguration.class); } - } return null; } @@ -911,8 +922,9 @@ public final class DeviceManagerUtil { * Validation happens in two ways, * 1. List of Serial Numbers - If this is available checks if the device to be enrolled serial number is * in the given list of serial numbers - * 2. List of Serial Numbers against a User - If [1] is missing and this is available checks if the device - * to be enrolled serial number is in the list of serial numbers which are against a User + * 2. List of Serial Numbers against a User - If [1] is not configured or the device serial number is not + * in the [1] then this checks if the device to be enrolled serial number is in the list of serial numbers + * which are against a User * @param enrollmentConfiguration which has the enrollment configurations of a tenant * @param deviceSerialNumber device serial number to be validated * @return a boolean value if the device can be enrolled @@ -928,36 +940,44 @@ public final class DeviceManagerUtil { return true; } else { List enrollmentConfigSerialNumbers = enrollmentConfiguration.getSerialNumbers(); + boolean isDeviceEnrollable = false; if (enrollmentConfigSerialNumbers != null && !enrollmentConfigSerialNumbers.isEmpty()) { if (log.isDebugEnabled()) { log.debug("List of serial numbers '" + enrollmentConfigSerialNumbers.toString() + "' has been" + " added for enrollment configuration under platform configuration to validate " + "the serial number '" + deviceSerialNumber + "'."); } - return enrollmentConfigSerialNumbers.stream().anyMatch(deviceSerialNumber::equals); - } else { - String username = PrivilegedCarbonContext.getThreadLocalCarbonContext().getUsername(); - List userConfigurations = enrollmentConfiguration - .getUserConfigurations(); - if (userConfigurations != null && !userConfigurations.isEmpty()) { - if (log.isDebugEnabled()) { - log.debug("List of serial numbers against users has been added for enrollment " - + "configuration under platform configuration."); - } - return userConfigurations.stream() - .filter(userConfiguration -> username.equals(userConfiguration.getUsername())).findFirst() - .filter(userConfiguration -> userConfiguration.getSerialNumbers().stream() - .anyMatch(deviceSerialNumber::equals)).isPresent(); - } else { - if (log.isDebugEnabled()) { - log.debug("Enrollment configuration has been but configuration does not contain any " - + "serial number based validation. It may be having the configuration to push " - + "devices to a specific group after a successful enrollment."); - } - // enrollment configuration has been set only to add device to a specific group and not to - // validate device against serial number - return true; + isDeviceEnrollable = enrollmentConfigSerialNumbers.stream().anyMatch(deviceSerialNumber::equals); + } + if (isDeviceEnrollable) { + return true; + } + String username = PrivilegedCarbonContext.getThreadLocalCarbonContext().getUsername(); + List userConfigurations = enrollmentConfiguration + .getUserConfigurations(); + if (userConfigurations != null && !userConfigurations.isEmpty()) { + if (log.isDebugEnabled()) { + log.debug("List of serial numbers against users has been added for enrollment " + + "configuration under platform configuration."); } + return userConfigurations.stream() + .filter(userConfiguration -> username.equals(userConfiguration.getUsername())).findFirst() + .filter(userConfiguration -> userConfiguration.getSerialNumbers().stream() + .anyMatch(deviceSerialNumber::equals)).isPresent(); + } else { + if (enrollmentConfigSerialNumbers != null && !enrollmentConfigSerialNumbers.isEmpty()) { + // serial number of the device is not in the serial number based configuration nor in the serial + // numbers against user based configuration + return false; + } + if (log.isDebugEnabled()) { + log.debug("Enrollment configuration has been but configuration does not contain any " + + "serial number based validation. It may be having the configuration to push " + + "devices to a specific group after a successful enrollment."); + } + // enrollment configuration has been set only to add device to a specific group and not to + // validate device against serial number + return true; } } } @@ -1045,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); + } } diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/util/DeviceMgtTenantMgtListener.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/util/DeviceMgtTenantMgtListener.java new file mode 100644 index 0000000000..5e0e0cff93 --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/util/DeviceMgtTenantMgtListener.java @@ -0,0 +1,148 @@ +/* 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; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.wso2.carbon.context.PrivilegedCarbonContext; +import org.wso2.carbon.device.mgt.common.permission.mgt.PermissionManagementException; +import org.wso2.carbon.device.mgt.common.roles.config.Role; +import org.wso2.carbon.device.mgt.core.config.DeviceConfigurationManager; +import org.wso2.carbon.device.mgt.core.config.DeviceManagementConfig; +import org.wso2.carbon.device.mgt.core.internal.DeviceManagementDataHolder; +import org.wso2.carbon.device.mgt.core.permission.mgt.PermissionUtils; +import org.wso2.carbon.registry.core.exceptions.RegistryException; +import org.wso2.carbon.stratos.common.beans.TenantInfoBean; +import org.wso2.carbon.stratos.common.listeners.TenantMgtListener; +import org.wso2.carbon.user.api.Permission; +import org.wso2.carbon.user.api.UserStoreException; +import org.wso2.carbon.user.api.UserStoreManager; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class DeviceMgtTenantMgtListener implements TenantMgtListener { + private static final Log log = LogFactory.getLog(DeviceMgtTenantMgtListener.class); + private static final int EXEC_ORDER = 10; + private static final String PERMISSION_ACTION = "ui.execute"; + + @Override + public void onTenantCreate(TenantInfoBean tenantInfoBean) { + DeviceManagementConfig config = DeviceConfigurationManager.getInstance().getDeviceManagementConfig(); + if (config.getDefaultRoles().isEnabled()) { + Map> roleMap = getValidRoleMap(config); + try { + PrivilegedCarbonContext.startTenantFlow(); + PrivilegedCarbonContext.getThreadLocalCarbonContext() + .setTenantDomain(tenantInfoBean.getTenantDomain(), true); + UserStoreManager userStoreManager = DeviceManagementDataHolder.getInstance().getRealmService() + .getTenantUserRealm(tenantInfoBean.getTenantId()).getUserStoreManager(); + + roleMap.forEach((key, value) -> { + try { + userStoreManager.addRole(key, null, value.toArray(new Permission[0])); + } catch (UserStoreException e) { + log.error("Error occurred while adding default roles into user store.", e); + } + }); + } catch (UserStoreException e) { + log.error("Error occurred while getting user store manager.", e); + } finally { + PrivilegedCarbonContext.endTenantFlow(); + } + } + } + + @Override + public void onTenantUpdate(TenantInfoBean tenantInfoBean) { + // doing nothing + } + + @Override + public void onTenantDelete(int i) { + // doing nothing + } + + @Override + public void onTenantRename(int i, String s, String s1) { + // doing nothing + } + + @Override + public void onTenantInitialActivation(int i) { + // doing nothing + } + + @Override + public void onTenantActivation(int i) { + // doing nothing + } + + @Override + public void onTenantDeactivation(int i) { + // doing nothing + } + + @Override + public void onSubscriptionPlanChange(int i, String s, String s1) { + // doing nothing + } + + @Override + public int getListenerOrder() { + return EXEC_ORDER; + } + + @Override + public void onPreDelete(int i) { + // doing nothing + } + + /** + * Use the default roles defined in the cdm-config and evaluate the defined permissions. If permissions does not + * exist then exclude them and return role map which contains defined roles in the cdm-config and existing + * permission list as a roleMap + * @param config cdm-config + * @return {@link Map} key is role name and value is list of permissions which needs to be assigned to the role + * defined in the key. + */ + private Map> getValidRoleMap(DeviceManagementConfig config) { + Map> roleMap = new HashMap<>(); + try { + for (Role role : config.getDefaultRoles().getRoles()) { + List permissionList = new ArrayList<>(); + for (String permissionPath : role.getPermissions()) { + if (PermissionUtils.checkResourceExists(permissionPath)) { + Permission permission = new Permission(permissionPath, PERMISSION_ACTION); + + permissionList.add(permission); + } else { + log.warn("Permission " + permissionPath + " does not exist. Hence it will not add to role " + + role.getName()); + } + } + roleMap.put(role.getName(), permissionList); + } + } catch (PermissionManagementException | RegistryException e) { + log.error("Error occurred while checking permission existence.", e); + } + return roleMap; + } +} diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/test/java/org/wso2/carbon/device/mgt/core/TestDeviceManagementService.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/test/java/org/wso2/carbon/device/mgt/core/TestDeviceManagementService.java index 580ed77161..c3789d47fa 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/test/java/org/wso2/carbon/device/mgt/core/TestDeviceManagementService.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/test/java/org/wso2/carbon/device/mgt/core/TestDeviceManagementService.java @@ -37,6 +37,7 @@ import org.wso2.carbon.device.mgt.common.*; import org.wso2.carbon.device.mgt.common.app.mgt.ApplicationManager; import org.wso2.carbon.device.mgt.common.exceptions.DeviceManagementException; import org.wso2.carbon.device.mgt.common.general.GeneralConfig; +import org.wso2.carbon.device.mgt.common.invitation.mgt.DeviceEnrollmentInvitationDetails; import org.wso2.carbon.device.mgt.common.policy.mgt.PolicyMonitoringManager; import org.wso2.carbon.device.mgt.common.pull.notification.PullNotificationSubscriber; import org.wso2.carbon.device.mgt.common.push.notification.PushNotificationConfig; @@ -142,4 +143,9 @@ public class TestDeviceManagementService implements DeviceManagementService { public DeviceTypePlatformDetails getDeviceTypePlatformDetails() { return null; } + + @Override + public DeviceEnrollmentInvitationDetails getDeviceEnrollmentInvitationDetails() { + return null; + } } diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.extensions/src/main/java/org/wso2/carbon/device/mgt/extensions/device/type/template/DeviceTypeManagerService.java b/components/device-mgt/org.wso2.carbon.device.mgt.extensions/src/main/java/org/wso2/carbon/device/mgt/extensions/device/type/template/DeviceTypeManagerService.java index 67b79bfeb4..5896039d99 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.extensions/src/main/java/org/wso2/carbon/device/mgt/extensions/device/type/template/DeviceTypeManagerService.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.extensions/src/main/java/org/wso2/carbon/device/mgt/extensions/device/type/template/DeviceTypeManagerService.java @@ -48,6 +48,7 @@ import org.wso2.carbon.device.mgt.common.app.mgt.ApplicationManager; import org.wso2.carbon.device.mgt.common.configuration.mgt.ConfigurationEntry; import org.wso2.carbon.device.mgt.common.configuration.mgt.PlatformConfiguration; import org.wso2.carbon.device.mgt.common.general.GeneralConfig; +import org.wso2.carbon.device.mgt.common.invitation.mgt.DeviceEnrollmentInvitationDetails; import org.wso2.carbon.device.mgt.common.policy.mgt.PolicyMonitoringManager; import org.wso2.carbon.device.mgt.common.pull.notification.PullNotificationSubscriber; import org.wso2.carbon.device.mgt.common.push.notification.PushNotificationConfig; @@ -92,6 +93,7 @@ public class DeviceTypeManagerService implements DeviceManagementService { private PullNotificationSubscriber pullNotificationSubscriber; private final DeviceStatusTaskPluginConfig deviceStatusTaskPluginConfig; private DeviceTypePlatformDetails deviceTypePlatformDetails; + private DeviceEnrollmentInvitationDetails deviceEnrollmentInvitationDetails; private GeneralConfig generalConfig; private boolean isRegistryBasedConfigs = false; private boolean isScheduled = false; @@ -116,6 +118,8 @@ public class DeviceTypeManagerService implements DeviceManagementService { this.setPolicyMonitoringManager(deviceTypeConfiguration.getPolicyMonitoring()); this.setPullNotificationSubscriber(deviceTypeConfiguration.getPullNotificationSubscriberConfig()); this.setGeneralConfig(deviceTypeConfiguration); + this.deviceEnrollmentInvitationDetails = new DeviceEnrollmentInvitationDetails(); + this.setDeviceEnrollmentInvitationDetails(deviceTypeConfiguration); } @Override @@ -259,6 +263,11 @@ public class DeviceTypeManagerService implements DeviceManagementService { return generalConfig; } + @Override + public DeviceEnrollmentInvitationDetails getDeviceEnrollmentInvitationDetails() { + return deviceEnrollmentInvitationDetails; + } + private void setProvisioningConfig(String tenantDomain, DeviceTypeConfiguration deviceTypeConfiguration) { if (deviceTypeConfiguration.getProvisioningConfig() != null) { boolean sharedWithAllTenants = deviceTypeConfiguration.getProvisioningConfig().isSharedWithAllTenants(); @@ -354,4 +363,13 @@ public class DeviceTypeManagerService implements DeviceManagementService { deviceTypePlatformDetails.setDeviceTypePlatformVersion(deviceTypeVersions.getDeviceTypePlatformVersion()); } } + + public void setDeviceEnrollmentInvitationDetails(DeviceTypeConfiguration deviceTypeConfiguration) { + DeviceEnrollmentInvitationDetails deviceEnrollmentInvitationDetailsFromConfig = deviceTypeConfiguration + .getDeviceEnrollmentInvitationDetails(); + if (deviceEnrollmentInvitationDetailsFromConfig != null) { + deviceEnrollmentInvitationDetails.setEnrollmentDetails( + deviceEnrollmentInvitationDetailsFromConfig.getEnrollmentDetails()); + } + } } diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.extensions/src/main/java/org/wso2/carbon/device/mgt/extensions/device/type/template/config/DeviceTypeConfiguration.java b/components/device-mgt/org.wso2.carbon.device.mgt.extensions/src/main/java/org/wso2/carbon/device/mgt/extensions/device/type/template/config/DeviceTypeConfiguration.java index f1c470829e..098baec3e3 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.extensions/src/main/java/org/wso2/carbon/device/mgt/extensions/device/type/template/config/DeviceTypeConfiguration.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.extensions/src/main/java/org/wso2/carbon/device/mgt/extensions/device/type/template/config/DeviceTypeConfiguration.java @@ -34,6 +34,7 @@ */ package org.wso2.carbon.device.mgt.extensions.device.type.template.config; +import org.wso2.carbon.device.mgt.common.invitation.mgt.DeviceEnrollmentInvitationDetails; import org.wso2.carbon.device.mgt.common.type.mgt.DeviceTypePlatformDetails; import javax.xml.bind.annotation.XmlElement; @@ -107,6 +108,8 @@ public class DeviceTypeConfiguration { protected List operations; @XmlElement(name = "DeviceTypePlatformDetails", required = true) protected DeviceTypePlatformDetails deviceTypePlatformDetails; + @XmlElement(name = "DeviceEnrollmentInvitationDetails", required = true) + protected DeviceEnrollmentInvitationDetails deviceEnrollmentInvitationDetails; public DeviceTypePlatformDetails getDeviceTypePlatformDetails() { return deviceTypePlatformDetails; @@ -414,4 +417,21 @@ public class DeviceTypeConfiguration { public void setStartupOperations(List startupOperations) { this.startupOperations = startupOperations; } + + /** + * Gets the value of device enrollment invitation details which has enrollment steps of enrollment types + * @return device enrollment invitation details + */ + public DeviceEnrollmentInvitationDetails getDeviceEnrollmentInvitationDetails() { + return deviceEnrollmentInvitationDetails; + } + + /** + * Sets the value of device enrollment invitation details from the relevant device type xml file + * @param deviceEnrollmentInvitationDetails {@link DeviceEnrollmentInvitationDetails} object + */ + public void setDeviceEnrollmentInvitationDetails( + DeviceEnrollmentInvitationDetails deviceEnrollmentInvitationDetails) { + this.deviceEnrollmentInvitationDetails = deviceEnrollmentInvitationDetails; + } } diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/pages/cdmf.page.users/public/js/listing.js b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/pages/cdmf.page.users/public/js/listing.js index 05f582844a..9e3733481e 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/pages/cdmf.page.users/public/js/listing.js +++ b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/pages/cdmf.page.users/public/js/listing.js @@ -112,10 +112,11 @@ $("a#invite-user-link").click(function () { * Function to get selected usernames. */ function getSelectedUsernames() { - var usernameList = []; - var userList = $("#user-grid").find("tr.DTTT_selected"); - userList.each(function () { - usernameList.push($(this).data('username')); + const tbl = $('#user-grid').DataTable(); + let usernameList = []; + let userList = $("#user-grid").find("tr.DTTT_selected"); + userList.each(function (idx, el) { + usernameList.push(tbl.row(el).data().username); }); return usernameList; } diff --git a/components/policy-mgt/org.wso2.carbon.policy.mgt.core/src/main/java/org/wso2/carbon/policy/mgt/core/mgt/impl/PolicyManagerImpl.java b/components/policy-mgt/org.wso2.carbon.policy.mgt.core/src/main/java/org/wso2/carbon/policy/mgt/core/mgt/impl/PolicyManagerImpl.java index c8737f1468..e39f061a65 100644 --- a/components/policy-mgt/org.wso2.carbon.policy.mgt.core/src/main/java/org/wso2/carbon/policy/mgt/core/mgt/impl/PolicyManagerImpl.java +++ b/components/policy-mgt/org.wso2.carbon.policy.mgt.core/src/main/java/org/wso2/carbon/policy/mgt/core/mgt/impl/PolicyManagerImpl.java @@ -89,7 +89,6 @@ public class PolicyManagerImpl implements PolicyManager { @Override public Policy addPolicy(Policy policy) throws PolicyManagementException { - try { PolicyManagementDAOFactory.beginTransaction(); if (policy.getProfile() != null && policy.getProfile().getProfileId() == 0) { @@ -107,19 +106,15 @@ public class PolicyManagerImpl implements PolicyManager { if (policy.getUsers() != null) { policyDAO.addPolicyToUser(policy.getUsers(), policy); } - if (policy.getRoles() != null) { policyDAO.addPolicyToRole(policy.getRoles(), policy); } - if (policy.getDevices() != null) { policyDAO.addPolicyToDevice(policy.getDevices(), policy); } - if (policy.getDeviceGroups() != null && !policy.getDeviceGroups().isEmpty()) { policyDAO.addDeviceGroupsToPolicy(policy); } - if (policy.getPolicyCriterias() != null) { List criteria = policy.getPolicyCriterias(); for (PolicyCriterion criterion : criteria) { @@ -139,7 +134,6 @@ public class PolicyManagerImpl implements PolicyManager { policyDAO.addPolicyCriteria(policy); policyDAO.addPolicyCriteriaProperties(policy.getPolicyCriterias()); } - if (policy.getCorrectiveActions() != null && !policy.getCorrectiveActions().isEmpty()) { if (log.isDebugEnabled()) { log.debug("Adding corrective actions for policy " + policy.getPolicyName() + @@ -147,17 +141,14 @@ public class PolicyManagerImpl implements PolicyManager { } policyDAO.addCorrectiveActionsOfPolicy(policy.getCorrectiveActions(), policy.getId()); } - if (policy.isActive()) { policyDAO.activatePolicy(policy.getId()); } PolicyManagementDAOFactory.commitTransaction(); - } catch (PolicyManagerDAOException e) { PolicyManagementDAOFactory.rollbackTransaction(); throw new PolicyManagementException("Error occurred while adding the policy (" + policy.getId() + " - " + policy.getPolicyName() + ")", e); - } catch (ProfileManagerDAOException e) { PolicyManagementDAOFactory.rollbackTransaction(); throw new PolicyManagementException("Error occurred while adding the profile related to policy (" + @@ -174,7 +165,6 @@ public class PolicyManagerImpl implements PolicyManager { @Override public Policy updatePolicy(Policy policy) throws PolicyManagementException { - try { // Previous policy needs to be obtained before beginning the transaction Policy previousPolicy = this.getPolicy(policy.getId()); @@ -183,15 +173,12 @@ public class PolicyManagerImpl implements PolicyManager { // This will keep track of the policies updated. policyDAO.recordUpdatedPolicy(policy); - List existingFeaturesList = new ArrayList<>(); List newFeaturesList = new ArrayList<>(); List featuresToDelete = new ArrayList<>(); List temp = new ArrayList<>(); List updateDFes = new ArrayList<>(); - List updatedFeatureList = policy.getProfile().getProfileFeaturesList(); - List existingProfileFeaturesList = previousPolicy.getProfile().getProfileFeaturesList(); // Checks for the existing features @@ -232,27 +219,20 @@ public class PolicyManagerImpl implements PolicyManager { if (!newFeaturesList.isEmpty()) { featureDAO.addProfileFeatures(newFeaturesList, profileId); } - if (!featuresToDelete.isEmpty()) { for (ProfileFeature pf : featuresToDelete) featureDAO.deleteProfileFeatures(pf.getId()); } - policyDAO.deleteCriteriaAndDeviceRelatedConfigs(policy.getId()); - - if (policy.getUsers() != null) { policyDAO.updateUserOfPolicy(policy.getUsers(), previousPolicy); } - if (policy.getRoles() != null) { policyDAO.updateRolesOfPolicy(policy.getRoles(), previousPolicy); } - if (policy.getDevices() != null) { policyDAO.addPolicyToDevice(policy.getDevices(), previousPolicy); } - if (policy.getDeviceGroups() != null && !policy.getDeviceGroups().isEmpty()) { policyDAO.addDeviceGroupsToPolicy(policy); } @@ -308,19 +288,15 @@ public class PolicyManagerImpl implements PolicyManager { log.debug("Updating corrective actions for policy " + policy.getPolicyName() + " having policy id " + policy.getId()); } - if (!correctiveActionsToUpdate.isEmpty()) { policyDAO.updateCorrectiveActionsOfPolicy(correctiveActionsToUpdate, previousPolicy.getId()); } - if (!correctiveActionsToAdd.isEmpty()) { policyDAO.addCorrectiveActionsOfPolicy(correctiveActionsToAdd, previousPolicy.getId()); } - if (!correctiveActionsToDelete.isEmpty()) { policyDAO.deleteCorrectiveActionsOfPolicy(correctiveActionsToDelete, previousPolicy.getId()); } - PolicyManagementDAOFactory.commitTransaction(); } catch (PolicyManagerDAOException e) { PolicyManagementDAOFactory.rollbackTransaction(); @@ -345,7 +321,6 @@ public class PolicyManagerImpl implements PolicyManager { public boolean updatePolicyPriorities(List policies) throws PolicyManagementException { boolean bool; try { -// List existingPolicies = this.getPolicies(); List existingPolicies; if (policyConfiguration.getCacheEnable()) { existingPolicies = PolicyCacheManagerImpl.getInstance().getAllPolicies(); @@ -405,7 +380,6 @@ public class PolicyManagerImpl implements PolicyManager { @Override public boolean deletePolicy(int policyId) throws PolicyManagementException { boolean bool; - List policies = this.getPolicies(); Policy pol = null; for (Policy p : policies) { @@ -433,7 +407,6 @@ public class PolicyManagerImpl implements PolicyManager { } featureDAO.deleteFeaturesOfProfile(policy.getProfileId()); - profileDAO.deleteProfile(policy.getProfileId()); PolicyManagementDAOFactory.commitTransaction(); return bool; @@ -491,7 +464,6 @@ public class PolicyManagerImpl implements PolicyManager { @Override public Policy addPolicyToDevice(List deviceIdentifierList, Policy policy) throws PolicyManagementException { - List deviceList = new ArrayList<>(); DeviceManagementProviderService deviceManagementService = PolicyManagementDataHolder .getInstance().getDeviceManagementService(); @@ -566,7 +538,6 @@ public class PolicyManagerImpl implements PolicyManager { @Override public Policy addPolicyToUser(List usernameList, Policy policy) throws PolicyManagementException { - try { PolicyManagementDAOFactory.beginTransaction(); if (policy.getId() == 0) { @@ -598,22 +569,17 @@ public class PolicyManagerImpl implements PolicyManager { @Override public Policy getPolicyByProfileID(int profileId) throws PolicyManagementException { - Policy policy; Profile profile; List deviceList; List roleNames; - try { PolicyManagementDAOFactory.openConnection(); policy = policyDAO.getPolicyByProfileID(profileId); - roleNames = policyDAO.getPolicyAppliedRoles(policy.getId()); profile = profileDAO.getProfile(profileId); policy.setProfile(profile); policy.setRoles(roleNames); - - } catch (PolicyManagerDAOException e) { throw new PolicyManagementException("Error occurred while getting the policy related to profile ID (" + profileId + ")", e); @@ -634,7 +600,6 @@ public class PolicyManagerImpl implements PolicyManager { @Override public Policy getPolicy(int policyId) throws PolicyManagementException { - Policy policy; List deviceList; List roleNames; @@ -642,13 +607,8 @@ public class PolicyManagerImpl implements PolicyManager { try { PolicyManagementDAOFactory.openConnection(); policy = policyDAO.getPolicy(policyId); - roleNames = policyDAO.getPolicyAppliedRoles(policyId); userNames = policyDAO.getPolicyAppliedUsers(policyId); - - //Profile profile = profileDAO.getProfile(policy.getProfileId()); - - policy.setRoles(roleNames); policy.setUsers(userNames); @@ -657,18 +617,11 @@ public class PolicyManagerImpl implements PolicyManager { " having policy id " + policy.getId()); } policy.setCorrectiveActions(policyDAO.getCorrectiveActionsOfPolicy(policyId)); - } catch (PolicyManagerDAOException e) { throw new PolicyManagementException("Error occurred while getting the policy related to policy ID (" + policyId + ")", e); -// } catch (ProfileManagerDAOException e) { -// throw new PolicyManagementException("Error occurred while getting the profile related to policy ID (" + -// policyId + ")", e); } catch (SQLException e) { throw new PolicyManagementException("Error occurred while opening a connection to the data source", e); -// } catch (ProfileManagementException e) { -// throw new PolicyManagementException("Error occurred while getting the profile related to policy ID (" + -// policyId + ")", e); } finally { PolicyManagementDAOFactory.closeConnection(); } @@ -678,24 +631,17 @@ public class PolicyManagerImpl implements PolicyManager { policy.setDevices(deviceList); try { - // PolicyManagementDAOFactory.openConnection(); Profile profile = profileManager.getProfile(policy.getProfileId()); policy.setProfile(profile); } catch (ProfileManagementException e) { throw new PolicyManagementException("Error occurred while getting the profile related to policy ID (" + policyId + ")", e); -// } catch (SQLException e) { -// throw new PolicyManagementException("Error occurred while opening a connection to the data source", e); -// } finally { -// PolicyManagementDAOFactory.closeConnection(); } - return policy; } @Override public List getPolicies() throws PolicyManagementException { - List policyList; List profileList; try { @@ -718,20 +664,16 @@ public class PolicyManagerImpl implements PolicyManager { } // Following is done because connection close has been implemented in every method. - for (Policy policy : policyList) { policy.setDevices(this.getPolicyAppliedDevicesIds(policy.getId())); } - return policyList; } @Override public List getPoliciesOfDevice(DeviceIdentifier deviceIdentifier) throws PolicyManagementException { - List policyIdList; List policies = new ArrayList<>(); - DeviceManagementProviderService deviceManagementService = PolicyManagementDataHolder .getInstance().getDeviceManagementService(); Device device; @@ -754,7 +696,6 @@ public class PolicyManagerImpl implements PolicyManager { PolicyManagementDAOFactory.closeConnection(); } -// List tempPolicyList = this.getPolicies(); List tempPolicyList; if (policyConfiguration.getCacheEnable()) { tempPolicyList = PolicyCacheManagerImpl.getInstance().getAllPolicies(); @@ -777,9 +718,6 @@ public class PolicyManagerImpl implements PolicyManager { @Override public List getPoliciesOfDeviceType(String deviceTypeName) throws PolicyManagementException { List policies = new ArrayList<>(); -// try { - // List profileList = profileManager.getProfilesOfDeviceType(deviceTypeName); -// List allPolicies = this.getPolicies(); List allPolicies; if (policyConfiguration.getCacheEnable()) { allPolicies = PolicyCacheManagerImpl.getInstance().getAllPolicies(); @@ -792,28 +730,14 @@ public class PolicyManagerImpl implements PolicyManager { policies.add(policy); } } - -// for (Profile profile : profileList) { -// for (Policy policy : allPolicies) { -// if (policy.getProfileId() == profile.getProfileId()) { -// policy.setProfile(profile); -// policies.add(policy); -// } -// } -// } Collections.sort(policies); -// } catch (ProfileManagementException e) { -// throw new PolicyManagementException("Error occurred while getting all the profile features.", e); -// } return policies; } @Override public List getPoliciesOfRole(String roleName) throws PolicyManagementException { - List policies = new ArrayList<>(); List policyIdList; - try { PolicyManagementDAOFactory.openConnection(); policyIdList = policyDAO.getPolicyOfRole(roleName); @@ -825,7 +749,6 @@ public class PolicyManagerImpl implements PolicyManager { PolicyManagementDAOFactory.closeConnection(); } -// List tempPolicyList = this.getPolicies(); List tempPolicyList; if (policyConfiguration.getCacheEnable()) { tempPolicyList = PolicyCacheManagerImpl.getInstance().getAllPolicies(); @@ -846,10 +769,8 @@ public class PolicyManagerImpl implements PolicyManager { @Override public List getPoliciesOfUser(String username) throws PolicyManagementException { - List policies = new ArrayList<>(); List policyIdList; - try { PolicyManagementDAOFactory.openConnection(); policyIdList = policyDAO.getPolicyOfUser(username); @@ -860,7 +781,6 @@ public class PolicyManagerImpl implements PolicyManager { } finally { PolicyManagementDAOFactory.closeConnection(); } -// List tempPolicyList = this.getPolicies(); List tempPolicyList; if (policyConfiguration.getCacheEnable()) { tempPolicyList = PolicyCacheManagerImpl.getInstance().getAllPolicies(); @@ -881,7 +801,6 @@ public class PolicyManagerImpl implements PolicyManager { @Override public List getPolicyAppliedDevicesIds(int policyId) throws PolicyManagementException { - List deviceList = new ArrayList<>(); List deviceIds; DeviceManagementProviderService deviceManagementService = PolicyManagementDataHolder @@ -930,8 +849,9 @@ public class PolicyManagerImpl implements PolicyManager { try { device = deviceManagementService.getDevice(deviceIdentifier, false); } catch (DeviceManagementException e) { - throw new PolicyManagementException("Error occurred while getting the device details (" + - deviceIdentifier.getId() + ")", e); + String msg = "Error occurred while getting the device details (" + deviceIdentifier.getId() + ")"; + log.error(msg, e); + throw new PolicyManagementException(msg, e); } int deviceId = device.getId(); try { @@ -954,17 +874,11 @@ public class PolicyManagerImpl implements PolicyManager { @Override public UpdatedPolicyDeviceListBean applyChangesMadeToPolicies() throws PolicyManagementException { - List changedDeviceTypes = new ArrayList<>(); List updatedPolicies = new ArrayList<>(); List updatedPolicyIds = new ArrayList<>(); boolean transactionDone = false; try { - //HashMap map = policyDAO.getUpdatedPolicyIdandDeviceTypeId(); -// List activePolicies = new ArrayList<>(); -// List inactivePolicies = new ArrayList<>(); - -// List allPolicies = this.getPolicies(); List allPolicies; if (policyConfiguration.getCacheEnable()) { allPolicies = PolicyCacheManagerImpl.getInstance().getAllPolicies(); @@ -979,11 +893,6 @@ public class PolicyManagerImpl implements PolicyManager { changedDeviceTypes.add(policy.getProfile().getDeviceType()); } } -// if (policy.isActive()) { -// activePolicies.add(policy); -// } else { -// inactivePolicies.add(policy); -// } } PolicyManagementDAOFactory.beginTransaction(); transactionDone = true; @@ -1067,7 +976,6 @@ public class PolicyManagerImpl implements PolicyManager { @Override public boolean checkPolicyAvailable(DeviceIdentifier deviceIdentifier) throws PolicyManagementException { - boolean exist; DeviceManagementProviderService deviceManagementService = PolicyManagementDataHolder .getInstance().getDeviceManagementService(); @@ -1094,7 +1002,6 @@ public class PolicyManagerImpl implements PolicyManager { @Override public boolean setPolicyApplied(DeviceIdentifier deviceIdentifier) throws PolicyManagementException { - DeviceManagementProviderService deviceManagementService = PolicyManagementDataHolder .getInstance().getDeviceManagementService(); Device device; @@ -1104,7 +1011,6 @@ public class PolicyManagerImpl implements PolicyManager { throw new PolicyManagementException("Error occurred while getting the device details (" + deviceIdentifier.getId() + ")", e); } - try { PolicyManagementDAOFactory.openConnection(); policyDAO.setPolicyApplied(device.getId(), device.getEnrolmentInfo().getId()); @@ -1158,7 +1064,6 @@ public class PolicyManagerImpl implements PolicyManager { public Policy getAppliedPolicyToDevice(Device device) throws PolicyManagementException { Policy policy; try { - //int policyId = policyDAO.getAppliedPolicyId(device.getId()); PolicyManagementDAOFactory.openConnection(); policy = policyDAO.getAppliedPolicy(device.getId(), device.getEnrolmentInfo().getId()); } catch (PolicyManagerDAOException e) { @@ -1210,8 +1115,8 @@ public class PolicyManagerImpl implements PolicyManager { private void addPolicyRevokeOperation(List deviceIdentifiers) throws PolicyManagementException { try { - String type = null; - if (deviceIdentifiers.size() > 0) { + String type; + if (!deviceIdentifiers.isEmpty()) { type = deviceIdentifiers.get(0).getType(); PolicyManagementDataHolder.getInstance().getDeviceManagementService().addOperation(type, this.getPolicyRevokeOperation(), deviceIdentifiers); @@ -1263,11 +1168,9 @@ public class PolicyManagerImpl implements PolicyManager { } finally { PolicyManagementDAOFactory.closeConnection(); } - for (Policy policy : policyList) { policy.setDevices(this.getPolicyAppliedDevicesIds(policy.getId())); } - return policyList; } @@ -1282,7 +1185,6 @@ public class PolicyManagerImpl implements PolicyManager { policy.setRoles(policyDAO.getPolicyAppliedRoles(policy.getId())); policy.setUsers(policyDAO.getPolicyAppliedUsers(policy.getId())); policy.setPolicyCriterias(policyDAO.getPolicyCriteria(policy.getId())); - List deviceGroupWrappers = policyDAO.getDeviceGroupsOfPolicy(policy.getId()); if (!deviceGroupWrappers.isEmpty()) { deviceGroupWrappers = this.getDeviceGroupNames(deviceGroupWrappers); diff --git a/components/policy-mgt/org.wso2.carbon.policy.mgt.core/src/test/java/org/wso2/carbon/policy/mgt/core/mock/TypeXDeviceManagementService.java b/components/policy-mgt/org.wso2.carbon.policy.mgt.core/src/test/java/org/wso2/carbon/policy/mgt/core/mock/TypeXDeviceManagementService.java index 9bcd089eb0..de7a16c0b1 100644 --- a/components/policy-mgt/org.wso2.carbon.policy.mgt.core/src/test/java/org/wso2/carbon/policy/mgt/core/mock/TypeXDeviceManagementService.java +++ b/components/policy-mgt/org.wso2.carbon.policy.mgt.core/src/test/java/org/wso2/carbon/policy/mgt/core/mock/TypeXDeviceManagementService.java @@ -44,6 +44,7 @@ import org.wso2.carbon.device.mgt.common.ProvisioningConfig; import org.wso2.carbon.device.mgt.common.StartupOperationConfig; import org.wso2.carbon.device.mgt.common.app.mgt.ApplicationManager; import org.wso2.carbon.device.mgt.common.general.GeneralConfig; +import org.wso2.carbon.device.mgt.common.invitation.mgt.DeviceEnrollmentInvitationDetails; import org.wso2.carbon.device.mgt.common.policy.mgt.PolicyMonitoringManager; import org.wso2.carbon.device.mgt.common.pull.notification.PullNotificationSubscriber; import org.wso2.carbon.device.mgt.common.push.notification.PushNotificationConfig; @@ -131,4 +132,9 @@ public class TypeXDeviceManagementService implements DeviceManagementService { public DeviceTypePlatformDetails getDeviceTypePlatformDetails() { return null; } + + @Override + public DeviceEnrollmentInvitationDetails getDeviceEnrollmentInvitationDetails() { + return null; + } } diff --git a/components/ui-request-interceptor/io.entgra.ui.request.interceptor/src/main/java/io/entgra/ui/request/interceptor/DefaultTokenHandler.java b/components/ui-request-interceptor/io.entgra.ui.request.interceptor/src/main/java/io/entgra/ui/request/interceptor/DefaultTokenHandler.java new file mode 100644 index 0000000000..1cff1d9d11 --- /dev/null +++ b/components/ui-request-interceptor/io.entgra.ui.request.interceptor/src/main/java/io/entgra/ui/request/interceptor/DefaultTokenHandler.java @@ -0,0 +1,134 @@ +/* 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 io.entgra.ui.request.interceptor; + +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import com.google.gson.JsonParser; +import io.entgra.ui.request.interceptor.beans.AuthData; +import io.entgra.ui.request.interceptor.util.HandlerConstants; +import io.entgra.ui.request.interceptor.util.HandlerUtil; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.http.HttpHeaders; +import org.apache.http.HttpStatus; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.entity.ContentType; +import org.wso2.carbon.device.application.mgt.common.ProxyResponse; + +import javax.servlet.annotation.MultipartConfig; +import javax.servlet.annotation.WebServlet; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.servlet.http.HttpSession; +import java.io.IOException; + +@MultipartConfig +@WebServlet("/default-credentials") +public class DefaultTokenHandler extends HttpServlet { + private static final Log log = LogFactory.getLog(DefaultTokenHandler.class); + + + @Override + protected void doGet(HttpServletRequest req, HttpServletResponse resp) { + try { + HttpSession httpSession = req.getSession(false); + + if (httpSession != null) { + AuthData authData = (AuthData) httpSession.getAttribute(HandlerConstants.SESSION_AUTH_DATA_KEY); + if (authData == null) { + HandlerUtil.sendUnAuthorizeResponse(resp); + return; + } + + AuthData defaultAuthData = (AuthData) httpSession + .getAttribute(HandlerConstants.SESSION_DEFAULT_AUTH_DATA_KEY); + if (defaultAuthData != null) { + HandlerUtil.handleSuccess(resp, constructSuccessProxyResponse(defaultAuthData.getAccessToken())); + return; + } + + String clientId = authData.getClientId(); + String clientSecret = authData.getClientSecret(); + + String iotsCorePort = System.getProperty("iot.core.https.port"); + if (HandlerConstants.HTTP_PROTOCOL.equals(req.getScheme())) { + iotsCorePort = System.getProperty("iot.core.http.port"); + } + + String tokenUrl = + req.getScheme() + HandlerConstants.SCHEME_SEPARATOR + System.getProperty("iot.core.host") + + HandlerConstants.COLON + iotsCorePort + "/api/device-mgt/v1.0/devices/" + clientId + + "/" + clientSecret + "/default-token"; + + HttpGet defaultTokenRequest = new HttpGet(tokenUrl); + defaultTokenRequest + .setHeader(HttpHeaders.AUTHORIZATION, HandlerConstants.BEARER + authData.getAccessToken()); + defaultTokenRequest + .setHeader(HttpHeaders.CONTENT_TYPE, ContentType.APPLICATION_FORM_URLENCODED.toString()); + ProxyResponse tokenResultResponse = HandlerUtil.execute(defaultTokenRequest); + + if (tokenResultResponse.getExecutorResponse().contains(HandlerConstants.EXECUTOR_EXCEPTION_PREFIX)) { + log.error("Error occurred while invoking the API to get default token data."); + HandlerUtil.handleError(resp, tokenResultResponse); + return; + } + String tokenResult = tokenResultResponse.getData(); + if (tokenResult == null) { + log.error("Invalid default token response is received."); + HandlerUtil.handleError(resp, tokenResultResponse); + return; + } + + JsonParser jsonParser = new JsonParser(); + JsonElement jTokenResult = jsonParser.parse(tokenResult); + if (jTokenResult.isJsonObject()) { + JsonObject jTokenResultAsJsonObject = jTokenResult.getAsJsonObject(); + AuthData newDefaultAuthData = new AuthData(); + newDefaultAuthData.setClientId(clientId); + newDefaultAuthData.setClientSecret(clientSecret); + + String defaultToken = jTokenResultAsJsonObject.get("accessToken").getAsString(); + newDefaultAuthData.setAccessToken(defaultToken); + newDefaultAuthData.setRefreshToken(jTokenResultAsJsonObject.get("refreshToken").getAsString()); + newDefaultAuthData.setScope(jTokenResultAsJsonObject.get("scopes").getAsString()); + httpSession.setAttribute(HandlerConstants.SESSION_DEFAULT_AUTH_DATA_KEY, newDefaultAuthData); + + HandlerUtil.handleSuccess(resp, constructSuccessProxyResponse(defaultToken)); + } + } else { + HandlerUtil.sendUnAuthorizeResponse(resp); + } + } catch (IOException e) { + log.error("Error occurred when processing GET request to get default token.", e); + } + } + + /** + * Get Success Proxy Response + * @param responseString Response String + * @return {@link ProxyResponse} + */ + private ProxyResponse constructSuccessProxyResponse (String responseString) { + ProxyResponse proxyResponse = new ProxyResponse(); + proxyResponse.setCode(HttpStatus.SC_OK); + proxyResponse.setData(responseString); + return proxyResponse; + } +} diff --git a/components/ui-request-interceptor/io.entgra.ui.request.interceptor/src/main/java/io/entgra/ui/request/interceptor/LoginHandler.java b/components/ui-request-interceptor/io.entgra.ui.request.interceptor/src/main/java/io/entgra/ui/request/interceptor/LoginHandler.java index b9f5403acc..53faa63eda 100644 --- a/components/ui-request-interceptor/io.entgra.ui.request.interceptor/src/main/java/io/entgra/ui/request/interceptor/LoginHandler.java +++ b/components/ui-request-interceptor/io.entgra.ui.request.interceptor/src/main/java/io/entgra/ui/request/interceptor/LoginHandler.java @@ -72,7 +72,6 @@ public class LoginHandler extends HttpServlet { httpSession.setMaxInactiveInterval(Math.toIntExact(HandlerConstants.TIMEOUT)); HttpGet uiConfigEndpoint = new HttpGet(uiConfigUrl); - JsonParser jsonParser = new JsonParser(); ProxyResponse uiConfigResponse = HandlerUtil.execute(uiConfigEndpoint); String executorResponse = uiConfigResponse.getExecutorResponse(); if (!StringUtils.isEmpty(executorResponse) && executorResponse @@ -88,6 +87,7 @@ public class LoginHandler extends HttpServlet { HandlerUtil.handleError(resp, null); return; } + JsonParser jsonParser = new JsonParser(); JsonElement uiConfigJsonElement = jsonParser.parse(uiConfigResponse.getData()); JsonObject uiConfigJsonObject = null; if (uiConfigJsonElement.isJsonObject()) { diff --git a/components/ui-request-interceptor/io.entgra.ui.request.interceptor/src/main/java/io/entgra/ui/request/interceptor/LogoutHandler.java b/components/ui-request-interceptor/io.entgra.ui.request.interceptor/src/main/java/io/entgra/ui/request/interceptor/LogoutHandler.java index 771341cb41..8ebacf1cb7 100644 --- a/components/ui-request-interceptor/io.entgra.ui.request.interceptor/src/main/java/io/entgra/ui/request/interceptor/LogoutHandler.java +++ b/components/ui-request-interceptor/io.entgra.ui.request.interceptor/src/main/java/io/entgra/ui/request/interceptor/LogoutHandler.java @@ -18,7 +18,6 @@ package io.entgra.ui.request.interceptor; -import io.entgra.ui.request.interceptor.util.HandlerConstants; import io.entgra.ui.request.interceptor.util.HandlerUtil; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; diff --git a/components/ui-request-interceptor/io.entgra.ui.request.interceptor/src/main/java/io/entgra/ui/request/interceptor/OTPInvokerHandler.java b/components/ui-request-interceptor/io.entgra.ui.request.interceptor/src/main/java/io/entgra/ui/request/interceptor/OTPInvokerHandler.java new file mode 100644 index 0000000000..624814f327 --- /dev/null +++ b/components/ui-request-interceptor/io.entgra.ui.request.interceptor/src/main/java/io/entgra/ui/request/interceptor/OTPInvokerHandler.java @@ -0,0 +1,270 @@ +/* + * 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 io.entgra.ui.request.interceptor; + +import io.entgra.ui.request.interceptor.util.HandlerConstants; +import io.entgra.ui.request.interceptor.util.HandlerUtil; +import org.apache.commons.fileupload.FileItem; +import org.apache.commons.fileupload.FileUploadException; +import org.apache.commons.fileupload.disk.DiskFileItemFactory; +import org.apache.commons.fileupload.servlet.ServletFileUpload; +import org.apache.commons.lang.StringUtils; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.http.HttpHeaders; +import org.apache.http.HttpStatus; +import org.apache.http.client.methods.HttpDelete; +import org.apache.http.client.methods.HttpEntityEnclosingRequestBase; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.client.methods.HttpHead; +import org.apache.http.client.methods.HttpPost; +import org.apache.http.client.methods.HttpPut; +import org.apache.http.client.methods.HttpRequestBase; +import org.apache.http.cookie.SM; +import org.apache.http.entity.ContentType; +import org.apache.http.entity.InputStreamEntity; +import org.apache.http.entity.mime.HttpMultipartMode; +import org.apache.http.entity.mime.MultipartEntityBuilder; +import org.apache.http.entity.mime.content.InputStreamBody; +import org.wso2.carbon.device.application.mgt.common.ProxyResponse; + +import javax.servlet.annotation.WebServlet; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.util.Enumeration; +import java.util.List; + +@WebServlet( + name = "OTPRequestHandlerServlet", + description = "This servlet intercepts the otp-api requests initiated from the user interface and validate " + + "before forwarding to the backend", + urlPatterns = { + "/otp-invoke/*" + } +) +public class OTPInvokerHandler extends HttpServlet { + private static final Log log = LogFactory.getLog(OTPInvokerHandler.class); + private static final long serialVersionUID = 3109569827313066220L; + private static String apiEndpoint; + + @Override + protected void doPost(HttpServletRequest req, HttpServletResponse resp) { + try { + if (validateRequest(req, resp)) { + HttpPost postRequest = new HttpPost(HandlerUtil.generateBackendRequestURL(req, apiEndpoint)); + generateRequestEntity(req, postRequest); + ProxyResponse proxyResponse = HandlerUtil.execute(postRequest); + + if (proxyResponse.getExecutorResponse().contains(HandlerConstants.EXECUTOR_EXCEPTION_PREFIX)) { + log.error("Error occurred while invoking the POST API endpoint."); + HandlerUtil.handleError(resp, proxyResponse); + return; + } + HandlerUtil.handleSuccess(resp, proxyResponse); + } + } catch (FileUploadException e) { + log.error("Error occurred when processing Multipart POST request.", e); + } catch (IOException e) { + log.error("Error occurred when processing POST request.", e); + } + } + + @Override + protected void doGet(HttpServletRequest req, HttpServletResponse resp) { + try { + if (validateRequest(req, resp)) { + HttpGet getRequest = new HttpGet(HandlerUtil.generateBackendRequestURL(req, apiEndpoint)); + copyRequestHeaders(req, getRequest, false); + ProxyResponse proxyResponse = HandlerUtil.execute(getRequest); + + if (proxyResponse.getExecutorResponse().contains(HandlerConstants.EXECUTOR_EXCEPTION_PREFIX)) { + log.error("Error occurred while invoking the GET API endpoint."); + HandlerUtil.handleError(resp, proxyResponse); + return; + } + HandlerUtil.handleSuccess(resp, proxyResponse); + } + } catch (IOException e) { + log.error("Error occurred when processing GET request.", e); + } + } + + @Override + protected void doHead(HttpServletRequest req, HttpServletResponse resp) { + try { + if (validateRequest(req, resp)) { + HttpHead headRequest = new HttpHead(HandlerUtil.generateBackendRequestURL(req, apiEndpoint)); + copyRequestHeaders(req, headRequest, false); + ProxyResponse proxyResponse = HandlerUtil.execute(headRequest); + + if (proxyResponse.getExecutorResponse().contains(HandlerConstants.EXECUTOR_EXCEPTION_PREFIX)) { + log.error("Error occurred while invoking the HEAD API endpoint."); + HandlerUtil.handleError(resp, proxyResponse); + return; + } + HandlerUtil.handleSuccess(resp, proxyResponse); + } + } catch (IOException e) { + log.error("Error occurred when processing HEAD request.", e); + } + } + + @Override + protected void doPut(HttpServletRequest req, HttpServletResponse resp) { + try { + if (validateRequest(req, resp)) { + HttpPut putRequest = new HttpPut(HandlerUtil.generateBackendRequestURL(req, apiEndpoint)); + generateRequestEntity(req, putRequest); + ProxyResponse proxyResponse = HandlerUtil.execute(putRequest); + + if (proxyResponse.getExecutorResponse().contains(HandlerConstants.EXECUTOR_EXCEPTION_PREFIX)) { + log.error("Error occurred while invoking the PUT API endpoint."); + HandlerUtil.handleError(resp, proxyResponse); + return; + } + HandlerUtil.handleSuccess(resp, proxyResponse); + } + } catch (FileUploadException e) { + log.error("Error occurred when processing Multipart PUT request.", e); + } catch (IOException e) { + log.error("Error occurred when processing PUT request.", e); + } + } + + @Override + protected void doDelete(HttpServletRequest req, HttpServletResponse resp) { + try { + if (validateRequest(req, resp)) { + HttpDelete deleteRequest = new HttpDelete(HandlerUtil.generateBackendRequestURL(req, apiEndpoint)); + copyRequestHeaders(req, deleteRequest, false); + ProxyResponse proxyResponse = HandlerUtil.execute(deleteRequest); + + if (proxyResponse.getExecutorResponse().contains(HandlerConstants.EXECUTOR_EXCEPTION_PREFIX)) { + log.error("Error occurred while invoking the DELETE API endpoint."); + HandlerUtil.handleError(resp, proxyResponse); + return; + } + HandlerUtil.handleSuccess(resp, proxyResponse); + } + } catch (IOException e) { + log.error("Error occurred when processing DELETE request.", e); + } + } + + /** + * Generate te request entity for POST and PUT requests from the incoming request. + * + * @param req incoming {@link HttpServletRequest}. + * @param proxyRequest proxy request instance. + * @throws FileUploadException If unable to parse the incoming request for multipart content extraction. + * @throws IOException If error occurred while generating the request body. + */ + private void generateRequestEntity(HttpServletRequest req, HttpEntityEnclosingRequestBase proxyRequest) + throws FileUploadException, IOException { + if (ServletFileUpload.isMultipartContent(req)) { + ServletFileUpload servletFileUpload = new ServletFileUpload(new DiskFileItemFactory()); + List fileItemList = servletFileUpload.parseRequest(req); + MultipartEntityBuilder entityBuilder = MultipartEntityBuilder.create(); + entityBuilder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE); + for (FileItem item: fileItemList) { + if (!item.isFormField()) { + entityBuilder.addPart(item.getFieldName(), new InputStreamBody(item.getInputStream(), + ContentType.create(item.getContentType()), item.getName())); + } else { + entityBuilder.addTextBody(item.getFieldName(), item.getString()); + } + } + proxyRequest.setEntity(entityBuilder.build()); + copyRequestHeaders(req, proxyRequest, false); + } else { + if (StringUtils.isNotEmpty(req.getHeader(HttpHeaders.CONTENT_LENGTH)) || + StringUtils.isNotEmpty(req.getHeader(HttpHeaders.TRANSFER_ENCODING))) { + InputStreamEntity entity = new InputStreamEntity(req.getInputStream(), + Long.parseLong(req.getHeader(HttpHeaders.CONTENT_LENGTH))); + proxyRequest.setEntity(entity); + } + copyRequestHeaders(req, proxyRequest, true); + } + } + + /** + * Copy incoming request headers to the proxy request. + * + * @param req incoming {@link HttpServletRequest} + * @param httpRequest proxy request instance. + * @param preserveContentType true if content type header needs to be preserved. + * This should be set to false when handling multipart requests as Http + * client will generate the Content-Type header automatically. + */ + private void copyRequestHeaders(HttpServletRequest req, HttpRequestBase httpRequest, boolean preserveContentType) { + Enumeration headerNames = req.getHeaderNames(); + while (headerNames.hasMoreElements()) { + String headerName = headerNames.nextElement(); + if (headerName.equalsIgnoreCase(HttpHeaders.CONTENT_LENGTH) || + headerName.equalsIgnoreCase(SM.COOKIE) || + (!preserveContentType && headerName.equalsIgnoreCase(HttpHeaders.CONTENT_TYPE))) { + continue; + } + Enumeration headerValues = req.getHeaders(headerName); + while (headerValues.hasMoreElements()) { + httpRequest.setHeader(headerName, headerValues.nextElement()); + } + } + } + + /*** + * Validates the incoming request. + * + * @param req {@link HttpServletRequest} + * @param resp {@link HttpServletResponse} + * @return If request is a valid one, returns TRUE, otherwise return FALSE + * @throws IOException If and error occurs while witting error response to client side + */ + private static boolean validateRequest(HttpServletRequest req, HttpServletResponse resp) + throws IOException { + String schema = req.getScheme(); + apiEndpoint = schema + HandlerConstants.SCHEME_SEPARATOR + System.getProperty("iot.core.host") + + HandlerConstants.COLON + HandlerUtil.getCorePort(schema); + + if (StringUtils.isBlank(req.getHeader(HandlerConstants.OTP_HEADER))) { + log.error("Unauthorized, Please provide OTP token."); + handleError(resp, HttpStatus.SC_UNAUTHORIZED); + return false; + } + return true; + } + + /** + * Handle error requests + * + * @param resp {@link HttpServletResponse} + * @param errorCode HTTP error status code + * @throws IOException If error occurred when trying to send the error response. + */ + private static void handleError(HttpServletResponse resp, int errorCode) + throws IOException { + ProxyResponse proxyResponse = new ProxyResponse(); + proxyResponse.setCode(errorCode); + proxyResponse.setExecutorResponse( + HandlerConstants.EXECUTOR_EXCEPTION_PREFIX + HandlerUtil.getStatusKey(errorCode)); + HandlerUtil.handleError(resp, proxyResponse); + } +} diff --git a/components/ui-request-interceptor/io.entgra.ui.request.interceptor/src/main/java/io/entgra/ui/request/interceptor/UserHandler.java b/components/ui-request-interceptor/io.entgra.ui.request.interceptor/src/main/java/io/entgra/ui/request/interceptor/UserHandler.java index 0464488e56..d35e495835 100644 --- a/components/ui-request-interceptor/io.entgra.ui.request.interceptor/src/main/java/io/entgra/ui/request/interceptor/UserHandler.java +++ b/components/ui-request-interceptor/io.entgra.ui.request.interceptor/src/main/java/io/entgra/ui/request/interceptor/UserHandler.java @@ -56,13 +56,13 @@ public class UserHandler extends HttpServlet { + HandlerConstants.COLON + HandlerUtil.getGatewayPort(req.getScheme()); HttpSession httpSession = req.getSession(false); if (httpSession == null) { - sendUnAuthorizeResponse(resp); + HandlerUtil.sendUnAuthorizeResponse(resp); return; } AuthData authData = (AuthData) httpSession.getAttribute(HandlerConstants.SESSION_AUTH_DATA_KEY); if (authData == null) { - sendUnAuthorizeResponse(resp); + HandlerUtil.sendUnAuthorizeResponse(resp); return; } @@ -91,7 +91,7 @@ public class UserHandler extends HttpServlet { if (jTokenResult.isJsonObject()) { JsonObject jTokenResultAsJsonObject = jTokenResult.getAsJsonObject(); if (!jTokenResultAsJsonObject.get("active").getAsBoolean()) { - sendUnAuthorizeResponse(resp); + HandlerUtil.sendUnAuthorizeResponse(resp); return; } ProxyResponse proxyResponse = new ProxyResponse(); @@ -106,18 +106,4 @@ public class UserHandler extends HttpServlet { log.error("Error occurred while parsing the response. ", e); } } - - /** - * Send UnAuthorized Response to the user - * - * @param resp HttpServletResponse object - */ - private void sendUnAuthorizeResponse(HttpServletResponse resp) - throws IOException { - ProxyResponse proxyResponse = new ProxyResponse(); - proxyResponse.setCode(HttpStatus.SC_UNAUTHORIZED); - proxyResponse.setExecutorResponse( - HandlerConstants.EXECUTOR_EXCEPTION_PREFIX + HandlerUtil.getStatusKey(HttpStatus.SC_UNAUTHORIZED)); - HandlerUtil.handleError(resp, proxyResponse); - } } diff --git a/components/ui-request-interceptor/io.entgra.ui.request.interceptor/src/main/java/io/entgra/ui/request/interceptor/util/HandlerConstants.java b/components/ui-request-interceptor/io.entgra.ui.request.interceptor/src/main/java/io/entgra/ui/request/interceptor/util/HandlerConstants.java index 261a28bb4b..b691eaa315 100644 --- a/components/ui-request-interceptor/io.entgra.ui.request.interceptor/src/main/java/io/entgra/ui/request/interceptor/util/HandlerConstants.java +++ b/components/ui-request-interceptor/io.entgra.ui.request.interceptor/src/main/java/io/entgra/ui/request/interceptor/util/HandlerConstants.java @@ -30,6 +30,7 @@ public class HandlerConstants { public static final String TAGS_KEY = "tags"; public static final String APP_NAME_KEY = "applicationName"; public static final String SESSION_AUTH_DATA_KEY = "authInfo"; + public static final String SESSION_DEFAULT_AUTH_DATA_KEY = "defaultAuthInfo"; public static final String UI_CONFIG_KEY = "ui-config"; public static final String PLATFORM = "platform"; public static final String USERNAME = "username"; @@ -46,4 +47,6 @@ public class HandlerConstants { public static final int INTERNAL_ERROR_CODE = 500; public static final long TIMEOUT = 1200; + + public static final String OTP_HEADER = "one-time-token"; } diff --git a/components/ui-request-interceptor/io.entgra.ui.request.interceptor/src/main/java/io/entgra/ui/request/interceptor/util/HandlerUtil.java b/components/ui-request-interceptor/io.entgra.ui.request.interceptor/src/main/java/io/entgra/ui/request/interceptor/util/HandlerUtil.java index f35c0700ee..592806f338 100644 --- a/components/ui-request-interceptor/io.entgra.ui.request.interceptor/src/main/java/io/entgra/ui/request/interceptor/util/HandlerUtil.java +++ b/components/ui-request-interceptor/io.entgra.ui.request.interceptor/src/main/java/io/entgra/ui/request/interceptor/util/HandlerUtil.java @@ -19,7 +19,6 @@ package io.entgra.ui.request.interceptor.util; import com.google.gson.Gson; -import com.google.gson.JsonObject; import org.apache.commons.lang.StringUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -37,7 +36,6 @@ import org.wso2.carbon.device.application.mgt.common.ProxyResponse; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; -import javax.servlet.http.HttpSession; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; @@ -206,7 +204,7 @@ public class HandlerUtil { } /** - * Get gatway port according to request recieved scheme + * Get gateway port according to request received scheme * @param scheme https or https * @return {@link String} gateway port */ @@ -218,6 +216,19 @@ public class HandlerUtil { return gatewayPort; } + /** + * Get core port according to request received scheme + * @param scheme https or https + * @return {@link String} gateway port + */ + public static String getCorePort(String scheme) { + String productCorePort = System.getProperty("iot.core.https.port"); + if (HandlerConstants.HTTP_PROTOCOL.equals(scheme)) { + productCorePort = System.getProperty("iot.core.https.por"); + } + return productCorePort; + } + /** * Retrieve Http client based on hostname verification. * @return {@link CloseableHttpClient} http client @@ -232,4 +243,34 @@ public class HandlerUtil { } } + /** + * Send UnAuthorized Response to the user + * + * @param resp HttpServletResponse object + */ + public static void sendUnAuthorizeResponse(HttpServletResponse resp) + throws IOException { + ProxyResponse proxyResponse = new ProxyResponse(); + proxyResponse.setCode(HttpStatus.SC_UNAUTHORIZED); + proxyResponse.setExecutorResponse( + HandlerConstants.EXECUTOR_EXCEPTION_PREFIX + HandlerUtil.getStatusKey(HttpStatus.SC_UNAUTHORIZED)); + handleError(resp, proxyResponse); + } + + /** + * Generates the target URL for the proxy request. + * + * @param req incoming {@link HttpServletRequest} + * @param apiEndpoint API Endpoint URL + * @return Target URL + */ + public static String generateBackendRequestURL(HttpServletRequest req, String apiEndpoint) { + StringBuilder urlBuilder = new StringBuilder(); + urlBuilder.append(apiEndpoint).append(HandlerConstants.API_COMMON_CONTEXT) + .append(req.getPathInfo().replace(" ", "%20")); + if (StringUtils.isNotEmpty(req.getQueryString())) { + urlBuilder.append("?").append(req.getQueryString()); + } + return urlBuilder.toString(); + } } diff --git a/components/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework/pom.xml b/components/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework/pom.xml index d2c8bb4dec..24cbfecefb 100644 --- a/components/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework/pom.xml +++ b/components/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework/pom.xml @@ -93,7 +93,7 @@ org.apache.axis2.transport.http, org.wso2.carbon.certificate.mgt.core.*, org.wso2.carbon.device.mgt.core.permission.mgt, - org.wso2.carbon.device.mgt.common, + org.wso2.carbon.device.mgt.common.*, org.wso2.carbon.device.mgt.common.permission.mgt, org.apache.axis2, org.apache.axis2.client, diff --git a/components/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework/src/main/java/org/wso2/carbon/webapp/authenticator/framework/Constants.java b/components/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework/src/main/java/org/wso2/carbon/webapp/authenticator/framework/Constants.java index 2694ea069a..6426c53f47 100644 --- a/components/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework/src/main/java/org/wso2/carbon/webapp/authenticator/framework/Constants.java +++ b/components/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework/src/main/java/org/wso2/carbon/webapp/authenticator/framework/Constants.java @@ -31,6 +31,7 @@ public final class Constants { public static final String HEADER_HTTP_ACCEPT = "Accept"; public static final String HEADER_HTTP_AUTHORIZATION = "Authorization"; + public static final String ONE_TIME_TOKEN_HEADER = "one-time-token"; } public static final class ContentTypes { diff --git a/components/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework/src/main/java/org/wso2/carbon/webapp/authenticator/framework/authenticator/OneTimeTokenAuthenticator.java b/components/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework/src/main/java/org/wso2/carbon/webapp/authenticator/framework/authenticator/OneTimeTokenAuthenticator.java new file mode 100644 index 0000000000..9d290c51da --- /dev/null +++ b/components/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework/src/main/java/org/wso2/carbon/webapp/authenticator/framework/authenticator/OneTimeTokenAuthenticator.java @@ -0,0 +1,91 @@ +/* + * 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.webapp.authenticator.framework.authenticator; + +import org.apache.catalina.connector.Response; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.wso2.carbon.device.mgt.common.otp.mgt.dto.OneTimePinDTO; +import org.wso2.carbon.device.mgt.common.spi.OTPManagementService; +import org.wso2.carbon.webapp.authenticator.framework.AuthenticationInfo; +import org.wso2.carbon.webapp.authenticator.framework.Constants; +import org.wso2.carbon.webapp.authenticator.framework.Utils.Utils; +import org.wso2.carbon.webapp.authenticator.framework.internal.AuthenticatorFrameworkDataHolder; + +import java.util.Properties; + +public class OneTimeTokenAuthenticator implements WebappAuthenticator { + private static final Log log = LogFactory.getLog(OneTimeTokenAuthenticator.class); + + + @Override + public void init() { + + } + + public boolean canHandle(org.apache.catalina.connector.Request request) { + return request.getHeader(Constants.HTTPHeaders.ONE_TIME_TOKEN_HEADER) != null; + } + + public AuthenticationInfo authenticate(org.apache.catalina.connector.Request request, Response response) { + + AuthenticationInfo authenticationInfo = new AuthenticationInfo(); + + try { + OTPManagementService otpManagementService = AuthenticatorFrameworkDataHolder.getInstance() + .getOtpManagementService(); + OneTimePinDTO validOTP = otpManagementService.isValidOTP(request.getHeader(Constants.HTTPHeaders + .ONE_TIME_TOKEN_HEADER)); + if (validOTP != null) { + authenticationInfo.setStatus(Status.CONTINUE); + authenticationInfo.setTenantId(validOTP.getTenantId()); + authenticationInfo.setTenantDomain(Utils.getTenantDomain(validOTP.getTenantId())); + authenticationInfo.setUsername(validOTP.getUsername()); + } else { + authenticationInfo.setStatus(Status.FAILURE); + authenticationInfo.setMessage("Invalid OTP token."); + } + } catch (Exception e) { + String msg = "OTP Token Validation Failed."; + log.error(msg, e); + authenticationInfo.setStatus(Status.FAILURE); + authenticationInfo.setMessage(msg); + } + return authenticationInfo; + } + + public String getName() { + return "One-Time-Token"; + } + + @Override + public void setProperties(Properties properties) { + + } + + @Override + public Properties getProperties() { + return null; + } + + @Override + public String getProperty(String name) { + return null; + } + +} diff --git a/components/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework/src/main/java/org/wso2/carbon/webapp/authenticator/framework/internal/AuthenticatorFrameworkDataHolder.java b/components/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework/src/main/java/org/wso2/carbon/webapp/authenticator/framework/internal/AuthenticatorFrameworkDataHolder.java index 8607d02239..a95b4fadb6 100644 --- a/components/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework/src/main/java/org/wso2/carbon/webapp/authenticator/framework/internal/AuthenticatorFrameworkDataHolder.java +++ b/components/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework/src/main/java/org/wso2/carbon/webapp/authenticator/framework/internal/AuthenticatorFrameworkDataHolder.java @@ -20,6 +20,7 @@ package org.wso2.carbon.webapp.authenticator.framework.internal; import org.wso2.carbon.certificate.mgt.core.scep.SCEPManager; import org.wso2.carbon.certificate.mgt.core.service.CertificateManagementService; +import org.wso2.carbon.device.mgt.common.spi.OTPManagementService; import org.wso2.carbon.identity.oauth2.OAuth2TokenValidationService; import org.wso2.carbon.registry.core.service.TenantRegistryLoader; import org.wso2.carbon.registry.indexing.service.TenantIndexingLoader; @@ -35,6 +36,7 @@ public class AuthenticatorFrameworkDataHolder { private OAuth2TokenValidationService oAuth2TokenValidationService; private TenantIndexingLoader tenantIndexingLoader; private TenantRegistryLoader tenantRegistryLoader; + private OTPManagementService otpManagementService; private static AuthenticatorFrameworkDataHolder thisInstance = new AuthenticatorFrameworkDataHolder(); @@ -114,4 +116,10 @@ public class AuthenticatorFrameworkDataHolder { public TenantRegistryLoader getTenantRegistryLoader() { return tenantRegistryLoader; } + + public OTPManagementService getOtpManagementService() { return otpManagementService; } + + public void setOtpManagementService(OTPManagementService otpManagementService) { + this.otpManagementService = otpManagementService; + } } diff --git a/components/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework/src/main/java/org/wso2/carbon/webapp/authenticator/framework/internal/WebappAuthenticatorFrameworkServiceComponent.java b/components/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework/src/main/java/org/wso2/carbon/webapp/authenticator/framework/internal/WebappAuthenticatorFrameworkServiceComponent.java index 36dd1c09c6..49eff0503b 100644 --- a/components/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework/src/main/java/org/wso2/carbon/webapp/authenticator/framework/internal/WebappAuthenticatorFrameworkServiceComponent.java +++ b/components/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework/src/main/java/org/wso2/carbon/webapp/authenticator/framework/internal/WebappAuthenticatorFrameworkServiceComponent.java @@ -25,6 +25,7 @@ import org.osgi.framework.BundleContext; import org.osgi.service.component.ComponentContext; import org.wso2.carbon.certificate.mgt.core.scep.SCEPManager; import org.wso2.carbon.certificate.mgt.core.service.CertificateManagementService; +import org.wso2.carbon.device.mgt.common.spi.OTPManagementService; import org.wso2.carbon.identity.oauth2.OAuth2TokenValidationService; import org.wso2.carbon.registry.core.service.TenantRegistryLoader; import org.wso2.carbon.registry.indexing.service.TenantIndexingLoader; @@ -80,7 +81,14 @@ import java.util.Properties; * cardinality="1..1" policy="dynamic" * bind="setTenantRegistryLoader" * unbind="unsetTenantRegistryLoader" + * @scr.reference name="org.wso2.carbon.device.manager" + * interface="org.wso2.carbon.device.mgt.common.spi.OTPManagementService" + * cardinality="1..1" + * policy="dynamic" + * bind="setOTPManagementService" + * unbind="unsetOTPManagementService" */ + public class WebappAuthenticatorFrameworkServiceComponent { private static final Log log = LogFactory.getLog(WebappAuthenticatorFrameworkServiceComponent.class); @@ -211,4 +219,18 @@ public class WebappAuthenticatorFrameworkServiceComponent { protected void unsetTenantRegistryLoader(TenantRegistryLoader tenantRegistryLoader) { AuthenticatorFrameworkDataHolder.getInstance().setTenantRegistryLoader(null); } + + protected void setOTPManagementService(OTPManagementService otpManagementService) { + if (log.isDebugEnabled()) { + log.debug("Setting OTP Management OSGI Service"); + } + AuthenticatorFrameworkDataHolder.getInstance().setOtpManagementService(otpManagementService); + } + + protected void unsetOTPManagementService(OTPManagementService otpManagementService) { + if (log.isDebugEnabled()) { + log.debug("Removing OTP Management OSGI Service"); + } + AuthenticatorFrameworkDataHolder.getInstance().setOtpManagementService(null); + } } diff --git a/components/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework/src/test/resources/config/etc/webapp-authenticator-config.xml b/components/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework/src/test/resources/config/etc/webapp-authenticator-config.xml index 5099328df7..93830ca169 100644 --- a/components/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework/src/test/resources/config/etc/webapp-authenticator-config.xml +++ b/components/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework/src/test/resources/config/etc/webapp-authenticator-config.xml @@ -24,5 +24,9 @@ CertificateAuth org.wso2.carbon.webapp.authenticator.framework.authenticator.CertificateAuthenticator + + OTPAuth + org.wso2.carbon.webapp.authenticator.framework.authenticator.OneTimeTokenAuthenticator + diff --git a/features/application-mgt/org.wso2.carbon.device.application.mgt.server.feature/src/main/resources/conf/application-mgt.xml b/features/application-mgt/org.wso2.carbon.device.application.mgt.server.feature/src/main/resources/conf/application-mgt.xml index d0d02a058a..aa48301903 100644 --- a/features/application-mgt/org.wso2.carbon.device.application.mgt.server.feature/src/main/resources/conf/application-mgt.xml +++ b/features/application-mgt/org.wso2.carbon.device.application.mgt.server.feature/src/main/resources/conf/application-mgt.xml @@ -77,13 +77,13 @@ true true true - /app-mgt/life-cycle/application/create + /permission/admin/app-mgt/life-cycle/application/create In-Review - /app-mgt/life-cycle/application/review + /permission/admin/app-mgt/life-cycle/application/review Rejected Approved @@ -91,7 +91,7 @@ - /app-mgt/life-cycle/application/approve + /permission/admin/app-mgt/life-cycle/application/approve In-Review Published @@ -99,28 +99,28 @@ true - /app-mgt/life-cycle/application/reject + /permission/admin/app-mgt/life-cycle/application/reject In-Review true - /app-mgt/life-cycle/application/publish + /permission/admin/app-mgt/life-cycle/application/publish Blocked Deprecated - /app-mgt/life-cycle/application/block + /permission/admin/app-mgt/life-cycle/application/block Published Deprecated - /app-mgt/life-cycle/application/deprecate + /permission/admin/app-mgt/life-cycle/application/deprecate Published Retired @@ -128,7 +128,7 @@ true - /app-mgt/life-cycle/application/retire + /permission/admin/app-mgt/life-cycle/application/retire diff --git a/features/device-mgt/org.wso2.carbon.device.mgt.basics.feature/src/main/resources/conf/cdm-config.xml b/features/device-mgt/org.wso2.carbon.device.mgt.basics.feature/src/main/resources/conf/cdm-config.xml index 925c5da5b4..bef658a615 100644 --- a/features/device-mgt/org.wso2.carbon.device.mgt.basics.feature/src/main/resources/conf/cdm-config.xml +++ b/features/device-mgt/org.wso2.carbon.device.mgt.basics.feature/src/main/resources/conf/cdm-config.xml @@ -159,5 +159,16 @@ org.wso2.carbon.device.mgt.common.enrollment.notification.EnrollmentNotifier http://localhost:8280 + + false + + + test_role + + /permission/admin/Login + + + + diff --git a/features/device-mgt/org.wso2.carbon.device.mgt.basics.feature/src/main/resources/conf/mdm-ui-config.xml b/features/device-mgt/org.wso2.carbon.device.mgt.basics.feature/src/main/resources/conf/mdm-ui-config.xml index 1a39fe704e..e9c88e3321 100644 --- a/features/device-mgt/org.wso2.carbon.device.mgt.basics.feature/src/main/resources/conf/mdm-ui-config.xml +++ b/features/device-mgt/org.wso2.carbon.device.mgt.basics.feature/src/main/resources/conf/mdm-ui-config.xml @@ -169,6 +169,7 @@ perm:android:set-password-policy perm:android:change-lock-code perm:android:upgrade-firmware + perm:android:send-notification device-mgt diff --git a/features/device-mgt/org.wso2.carbon.device.mgt.basics.feature/src/main/resources/dbscripts/cdm/h2.sql b/features/device-mgt/org.wso2.carbon.device.mgt.basics.feature/src/main/resources/dbscripts/cdm/h2.sql index 4d16db5abe..623bd6b374 100644 --- a/features/device-mgt/org.wso2.carbon.device.mgt.basics.feature/src/main/resources/dbscripts/cdm/h2.sql +++ b/features/device-mgt/org.wso2.carbon.device.mgt.basics.feature/src/main/resources/dbscripts/cdm/h2.sql @@ -572,6 +572,23 @@ CREATE TABLE IF NOT EXISTS DM_METADATA ( ); -- END OF METADATA TABLE -- +-- DM_OTP_DATA TABLE -- +CREATE TABLE IF NOT EXISTS DM_OTP_DATA ( + ID INT AUTO_INCREMENT NOT NULL, + OTP_TOKEN VARCHAR(100) NOT NULL, + TENANT_ID INT NOT NULL, + USERNAME VARCHAR(500) DEFAULT NOT NULL, + EMAIL VARCHAR(100) NOT NULL, + EMAIL_TYPE VARCHAR(20) NOT NULL, + META_INFO VARCHAR(20000) NOT NULL, + CREATED_AT TIMESTAMP NOT NULL, + EXPIRY_TIME INT NOT NULL DEFAULT 3600, + IS_EXPIRED BOOLEAN DEFAULT false, + PRIMARY KEY (ID), + CONSTRAINT email_type_uk UNIQUE (EMAIL, EMAIL_TYPE) +); +-- END OF DM_OTP_DATA TABLE -- + -- DASHBOARD RELATED VIEWS -- CREATE VIEW POLICY_COMPLIANCE_INFO AS SELECT diff --git a/features/device-mgt/org.wso2.carbon.device.mgt.basics.feature/src/main/resources/dbscripts/cdm/mssql.sql b/features/device-mgt/org.wso2.carbon.device.mgt.basics.feature/src/main/resources/dbscripts/cdm/mssql.sql index 8739701915..058bceb53b 100644 --- a/features/device-mgt/org.wso2.carbon.device.mgt.basics.feature/src/main/resources/dbscripts/cdm/mssql.sql +++ b/features/device-mgt/org.wso2.carbon.device.mgt.basics.feature/src/main/resources/dbscripts/cdm/mssql.sql @@ -614,6 +614,23 @@ CREATE TABLE DM_METADATA ( ); -- END OF METADATA TABLE -- +-- DM_OTP_DATA TABLE -- +CREATE TABLE DM_OTP_DATA ( + ID INT IDENTITY NOT NULL, + OTP_TOKEN VARCHAR(100) NOT NULL, + TENANT_ID INTEGER NOT NULL, + USERNAME VARCHAR(500) NOT NULL, + EMAIL VARCHAR(100) NOT NULL, + EMAIL_TYPE VARCHAR(20) NOT NULL, + META_INFO VARCHAR(20000) NOT NULL, + CREATED_AT DATETIME2(0) NOT NULL, + EXPIRY_TIME INT NOT NULL DEFAULT 3600, + IS_EXPIRED BIT DEFAULT false, + PRIMARY KEY (ID), + CONSTRAINT email_type_uk UNIQUE (EMAIL, EMAIL_TYPE) +); +-- END OF DM_OTP_DATA TABLE -- + -- DASHBOARD RELATED VIEWS -- IF NOT EXISTS (SELECT * FROM SYS.VIEWS WHERE NAME = 'POLICY_COMPLIANCE_INFO') diff --git a/features/device-mgt/org.wso2.carbon.device.mgt.basics.feature/src/main/resources/dbscripts/cdm/mysql.sql b/features/device-mgt/org.wso2.carbon.device.mgt.basics.feature/src/main/resources/dbscripts/cdm/mysql.sql index ba57c26757..f1244dd87e 100644 --- a/features/device-mgt/org.wso2.carbon.device.mgt.basics.feature/src/main/resources/dbscripts/cdm/mysql.sql +++ b/features/device-mgt/org.wso2.carbon.device.mgt.basics.feature/src/main/resources/dbscripts/cdm/mysql.sql @@ -630,6 +630,23 @@ CREATE TABLE IF NOT EXISTS DM_METADATA ( ) ENGINE=InnoDB; -- END OF METADATA TABLE -- +-- DM_OTP_DATA TABLE -- +CREATE TABLE IF NOT EXISTS DM_OTP_DATA ( + ID INT AUTO_INCREMENT NOT NULL, + OTP_TOKEN VARCHAR(100) NOT NULL, + TENANT_ID INT NOT NULL, + USERNAME VARCHAR(500) NOT NULL, + EMAIL VARCHAR(100) NOT NULL, + EMAIL_TYPE VARCHAR(20) NOT NULL, + META_INFO VARCHAR(20000) NOT NULL, + CREATED_AT TIMESTAMP NOT NULL, + EXPIRY_TIME INT NOT NULL DEFAULT 3600, + IS_EXPIRED BOOLEAN DEFAULT false, + PRIMARY KEY (ID), + CONSTRAINT email_type_uk UNIQUE (EMAIL, EMAIL_TYPE) +); +-- END OF DM_OTP_DATA TABLE -- + -- DASHBOARD RELATED VIEWS -- CREATE VIEW DEVICE_INFO_VIEW AS diff --git a/features/device-mgt/org.wso2.carbon.device.mgt.basics.feature/src/main/resources/dbscripts/cdm/oracle.sql b/features/device-mgt/org.wso2.carbon.device.mgt.basics.feature/src/main/resources/dbscripts/cdm/oracle.sql index 3ca15d3f38..325bb770b3 100644 --- a/features/device-mgt/org.wso2.carbon.device.mgt.basics.feature/src/main/resources/dbscripts/cdm/oracle.sql +++ b/features/device-mgt/org.wso2.carbon.device.mgt.basics.feature/src/main/resources/dbscripts/cdm/oracle.sql @@ -978,6 +978,34 @@ END; / -- END OF METADATA TABLE -- +-- OPT-DATA TABLE -- +CREATE TABLE DM_OTP_DATA ( + ID NUMBER(10) NOT NULL, + OTP_TOKEN VARCHAR2(100) NOT NULL, + TENANT_ID INTEGER NOT NULL, + USERNAME VARCHAR(500) NOT NULL, + EMAIL VARCHAR2(100) NOT NULL, + EMAIL_TYPE VARCHAR2(20) NOT NULL, + META_INFO VARCHAR2(20000) NOT NULL, + CREATED_AT TIMESTAMP(0) NOT NULL, + EXPIRY_TIME NUMBER(10) DEFAULT 3600 NOT NULL, + IS_EXPIRED CHAR(1) DEFAULT false, + PRIMARY KEY (ID), + CONSTRAINT email_type_uk UNIQUE (EMAIL, EMAIL_TYPE) +); + +-- Generate ID using sequence and trigger +CREATE SEQUENCE DM_OTP_DATA_seq START WITH 1 INCREMENT BY 1; + +CREATE OR REPLACE TRIGGER DM_OTP_DATA_seq_tr + BEFORE INSERT ON DM_OTP_DATA FOR EACH ROW + WHEN (NEW.ID IS NULL) +BEGIN +SELECT DM_OTP_DATA_seq.NEXTVAL INTO :NEW.ID FROM DUAL; +END; +/ +-- END OF OTP-DATA TABLE -- + -- DASHBOARD RELATED VIEWS -- CREATE VIEW POLICY_COMPLIANCE_INFO AS diff --git a/features/device-mgt/org.wso2.carbon.device.mgt.basics.feature/src/main/resources/dbscripts/cdm/postgresql.sql b/features/device-mgt/org.wso2.carbon.device.mgt.basics.feature/src/main/resources/dbscripts/cdm/postgresql.sql index dc3d264cfd..d695625575 100644 --- a/features/device-mgt/org.wso2.carbon.device.mgt.basics.feature/src/main/resources/dbscripts/cdm/postgresql.sql +++ b/features/device-mgt/org.wso2.carbon.device.mgt.basics.feature/src/main/resources/dbscripts/cdm/postgresql.sql @@ -617,6 +617,26 @@ CREATE TABLE IF NOT EXISTS DM_METADATA ( ); -- END OF METADATA TABLE -- +-- OPT-DATA TABLE -- +CREATE SEQUENCE DM_OTP_DATA_seq; + +CREATE TABLE IF NOT EXISTS DM_OTP_DATA ( + ID INT DEFAULT NEXTVAL ('DM_OTP_DATA_seq') NOT NULL, + OTP_TOKEN VARCHAR(100) NOT NULL, + TENANT_ID INTEGER NOT NULL, + USERNAME VARCHAR(500) NOT NULL, + EMAIL VARCHAR(100) NOT NULL, + EMAIL_TYPE VARCHAR(20) NOT NULL, + META_INFO VARCHAR(20000) NOT NULL, + CREATED_AT TIMESTAMP(0) NOT NULL, + EXPIRY_TIME INT NOT NULL DEFAULT 3600, + IS_EXPIRED BOOLEAN DEFAULT false, + PRIMARY KEY (ID), + CONSTRAINT email_type_uk UNIQUE (EMAIL, EMAIL_TYPE) +); + +-- END OF OPT-DATA TABLE -- + -- DASHBOARD RELATED VIEWS -- CREATE VIEW DEVICE_INFO_VIEW AS diff --git a/features/device-mgt/org.wso2.carbon.device.mgt.basics.feature/src/main/resources/email/templates/user-enrollment.vm b/features/device-mgt/org.wso2.carbon.device.mgt.basics.feature/src/main/resources/email/templates/user-enrollment.vm index 69aad7b830..d74e28ab7b 100644 --- a/features/device-mgt/org.wso2.carbon.device.mgt.basics.feature/src/main/resources/email/templates/user-enrollment.vm +++ b/features/device-mgt/org.wso2.carbon.device.mgt.basics.feature/src/main/resources/email/templates/user-enrollment.vm @@ -26,10 +26,9 @@
-
+
- WSO2 + entgra
@@ -50,18 +49,9 @@

- WSO2 IoT Server Administrator + Entgra IoT Administrator

-
- - - - -
WSO2
-
diff --git a/features/device-mgt/org.wso2.carbon.device.mgt.basics.feature/src/main/resources/email/templates/user-registration.vm b/features/device-mgt/org.wso2.carbon.device.mgt.basics.feature/src/main/resources/email/templates/user-registration.vm index ca20e42d7f..906869a286 100644 --- a/features/device-mgt/org.wso2.carbon.device.mgt.basics.feature/src/main/resources/email/templates/user-registration.vm +++ b/features/device-mgt/org.wso2.carbon.device.mgt.basics.feature/src/main/resources/email/templates/user-registration.vm @@ -26,10 +26,9 @@
-
+
- WSO2 + entgra
@@ -60,18 +59,9 @@

- WSO2 IoT Server Administrator + Entgra IoT Administrator

-
- - - - -
WSO2
-
diff --git a/features/email-sender/org.wso2.carbon.email.sender.feature/src/main/resources/email/templates/default-enrollment-invitation.vm b/features/email-sender/org.wso2.carbon.email.sender.feature/src/main/resources/email/templates/default-enrollment-invitation.vm index 6084f37ec1..fff7afa9de 100644 --- a/features/email-sender/org.wso2.carbon.email.sender.feature/src/main/resources/email/templates/default-enrollment-invitation.vm +++ b/features/email-sender/org.wso2.carbon.email.sender.feature/src/main/resources/email/templates/default-enrollment-invitation.vm @@ -26,178 +26,9 @@
-
+
- entgra.io + entgra
diff --git a/features/email-sender/org.wso2.carbon.email.sender.feature/src/main/resources/email/templates/user-enrollment.vm b/features/email-sender/org.wso2.carbon.email.sender.feature/src/main/resources/email/templates/user-enrollment.vm index 0c29e86b4b..6c53701a63 100644 --- a/features/email-sender/org.wso2.carbon.email.sender.feature/src/main/resources/email/templates/user-enrollment.vm +++ b/features/email-sender/org.wso2.carbon.email.sender.feature/src/main/resources/email/templates/user-enrollment.vm @@ -14,6 +14,22 @@ KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + + Copyright (c) 2019, 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. *# You have been invited to enroll your device in Entgra IoT @@ -26,178 +42,9 @@
-
+
- entgra.io + entgra
@@ -206,7 +53,13 @@ TkSuQmCC"

You have been invited to enrol your device in Entgra IoT Server. - Click here to begin device enrolment.

+ Click here to begin device enrolment.

+ +

+ Enrollment Steps are as below, +

+ + $enrollment-steps

Should you need assistance, please contact your administrator. diff --git a/features/email-sender/org.wso2.carbon.email.sender.feature/src/main/resources/email/templates/user-registration.vm b/features/email-sender/org.wso2.carbon.email.sender.feature/src/main/resources/email/templates/user-registration.vm index 5d4592007e..0593f32166 100644 --- a/features/email-sender/org.wso2.carbon.email.sender.feature/src/main/resources/email/templates/user-registration.vm +++ b/features/email-sender/org.wso2.carbon.email.sender.feature/src/main/resources/email/templates/user-registration.vm @@ -26,178 +26,9 @@

-
+
- entgra.io + entgra
diff --git a/features/email-sender/org.wso2.carbon.email.sender.feature/src/main/resources/email/templates/user-verify.vm b/features/email-sender/org.wso2.carbon.email.sender.feature/src/main/resources/email/templates/user-verify.vm new file mode 100644 index 0000000000..858503fd8a --- /dev/null +++ b/features/email-sender/org.wso2.carbon.email.sender.feature/src/main/resources/email/templates/user-verify.vm @@ -0,0 +1,61 @@ +#* + 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. +*# + + Verify email to register with Entgra IoTS + + + + Entgra IoT Server + + +
+
+
+
+ entgra +
+
+
+

+ Hi $first-name, +

+

+ Congratulations!!! Thank you for registering with Entgra cloud. Please click and log in to the + following link to complete your registration with us. Click here. +

+ +

+ If you need further assistance, please contact your administrator. +

+ +

+ Regards, +

+ +

+ Entgra IoT Administrator +

+
+
+
+ + + ]]> + +
diff --git a/features/email-sender/org.wso2.carbon.email.sender.feature/src/main/resources/email/templates/user-welcome.vm b/features/email-sender/org.wso2.carbon.email.sender.feature/src/main/resources/email/templates/user-welcome.vm new file mode 100644 index 0000000000..5ce4611964 --- /dev/null +++ b/features/email-sender/org.wso2.carbon.email.sender.feature/src/main/resources/email/templates/user-welcome.vm @@ -0,0 +1,98 @@ +#* + 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. +*# + + Welcome to Entgra Evaluation Cloud + + + + Entgra IoT Server + + +
+
+
+
+ entgra +
+
+
+

+ Hi $first-name, +

+
+

+ Welcome to Entgra Evaluation Cloud!! Entgra server support offers managing Android, iOS and Windows + devices along with a wide range of features that support cooperate (COPE) or personal device (BYOD) + enrollments. +

+
+
+

Access different portals

+

Your log-in credentials to any of our portals(endpoint-mgt, store, publisher) are,

+

Username: $portal-username

+

Password: password provided at registration for an evaluation account.

+

Endpoint management portal URL: $base-url-https/endpoint-mgt/

+

+ This is the portal used to send operations and policies to devices and overall management of + the server. +

+

Application store portal URL: $base-url-https/store

+

+ This is an in-house corporate app store where you can host all your corporate applications. + Users may browse apps and install them to their devices if the administrator has made the apps + publicly visible to users. Administrator can install, uninstall and update apps in the user + device or device groups. +

+

Application publishing portal URL: $base-url-https/publisher

+

+ The portal for publishing new applications for internal use. This is the developer view of the + enterprise application store that comes with the product. +

+
+
+

Enroll a device

+

+ Please find here a set of videos on how to enroll and onboard devices to our Cloud platform. + [Cloud Enrollment Guide] + When enrolling a device, Make sure to use the following log-in format: +

+

Organisation: $tenant-domain

+

Username: $agent-username

+

Password: password provided at registration.

+
+
+

+ If you have any further questions, please reach out to us using your registered mail to + bizdev-group@entgra.io. Looking forward to working with you. +

+

+ Best Regards, +

+

+ Entgra Cloud Team +

+
+
+
+
+ + + ]]> + +
diff --git a/features/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework.server.feature/src/main/resources/conf/webapp-authenticator-config.xml b/features/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework.server.feature/src/main/resources/conf/webapp-authenticator-config.xml index 4b727a28c2..dfea5c07ac 100644 --- a/features/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework.server.feature/src/main/resources/conf/webapp-authenticator-config.xml +++ b/features/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework.server.feature/src/main/resources/conf/webapp-authenticator-config.xml @@ -31,6 +31,10 @@ CertificateAuth org.wso2.carbon.webapp.authenticator.framework.authenticator.CertificateAuthenticator + + OTPAuth + org.wso2.carbon.webapp.authenticator.framework.authenticator.OneTimeTokenAuthenticator + BST org.wso2.carbon.webapp.authenticator.framework.authenticator.BSTAuthenticator diff --git a/pom.xml b/pom.xml index eb0b4f8e53..d12b76d9f4 100644 --- a/pom.xml +++ b/pom.xml @@ -1772,6 +1772,11 @@ maven-checkstyle-plugin ${maven.checkstyle.vesion} + + commons-validator + commons-validator + ${apache.validator.version} + @@ -2219,6 +2224,9 @@ 2.3.2 + + 1.7 + 2.1.7-wso2v7 1.5.11.wso2v15 @@ -2249,11 +2257,10 @@ 1.21 2.6.5 1.7.6 - v10.15.3 - 6.9.0 + v12.18.1 3.1.0 - + 7.0.85 1.0