use of org.eclipse.kapua.service.device.registry.connection.DeviceConnection in project kapua by eclipse.
the class KapuaSecurityBrokerFilter method removeConnection.
@Override
public void removeConnection(ConnectionContext context, ConnectionInfo info, Throwable error) throws Exception {
if (!isPassThroughConnection(context)) {
Context loginRemoveConnectionTimeContext = metricLoginRemoveConnectionTime.time();
try {
KapuaSecurityContext kapuaSecurityContext = getKapuaSecurityContext(context);
// TODO fix the kapua session when run as feature will be implemented
KapuaPrincipal kapuaPrincipal = ((KapuaPrincipal) kapuaSecurityContext.getMainPrincipal());
KapuaSession kapuaSession = new KapuaSession(null, kapuaPrincipal.getAccountId(), kapuaPrincipal.getAccountId(), kapuaPrincipal.getUserId(), kapuaPrincipal.getName());
KapuaSecurityUtils.setSession(kapuaSession);
String clientId = kapuaPrincipal.getClientId();
KapuaId accountId = kapuaPrincipal.getAccountId();
String username = kapuaSecurityContext.getUserName();
String remoteAddress = (context.getConnection() != null) ? context.getConnection().getRemoteAddress() : "";
KapuaId scopeId = ((KapuaPrincipal) kapuaSecurityContext.getMainPrincipal()).getAccountId();
// multiple account stealing link fix
String fullClientId = MessageFormat.format(AclConstants.MULTI_ACCOUNT_CLIENT_ID, accountId, clientId);
if (!isAdminUser(username)) {
// Stealing link check
ConnectionId connectionId = connectionMap.get(fullClientId);
boolean stealingLinkDetected = false;
if (connectionId != null) {
stealingLinkDetected = !connectionId.equals(info.getConnectionId());
} else {
logger.error("Cannot find connection id for client id {} on connection map. Currect connection id is {} - IP: {}", new Object[] { clientId, info.getConnectionId(), info.getClientIp() });
}
if (stealingLinkDetected) {
metricLoginStealingLinkDisconnect.inc();
// stealing link detected, skip info
logger.warn("Detected Stealing link for cliend id {} - account id {} - last connection id was {} - current connection id is {} - IP: {} - No disconnection info will be added!", new Object[] { clientId, accountId, connectionId, info.getConnectionId(), info.getClientIp() });
} else {
KapuaId deviceConnectionId = kapuaSecurityContext.getConnectionId();
DeviceConnection deviceConnection = null;
try {
deviceConnection = KapuaSecurityUtils.doPriviledge(new Callable<DeviceConnection>() {
@Override
public DeviceConnection call() throws Exception {
return deviceConnectionService.findByClientId(scopeId, clientId);
}
});
} catch (Exception e) {
throw new ShiroException("Error while updating the device connection!", e);
}
// the device connection must be not null
// cleanup stealing link detection map
connectionMap.remove(fullClientId);
final DeviceConnection deviceConnectionToUpdate = deviceConnection;
if (error == null) {
// update device connection
deviceConnectionToUpdate.setStatus(DeviceConnectionStatus.DISCONNECTED);
try {
KapuaSecurityUtils.doPriviledge(() -> {
deviceConnectionService.update(deviceConnectionToUpdate);
return null;
});
} catch (Exception e) {
throw new ShiroException("Error while updating the device connection status!", e);
}
} else {
// send missing message
// update device connection
deviceConnectionToUpdate.setStatus(DeviceConnectionStatus.MISSING);
try {
KapuaSecurityUtils.doPriviledge(() -> {
deviceConnectionService.update(deviceConnectionToUpdate);
return null;
});
} catch (Exception e) {
throw new ShiroException("Error while updating the device connection status!", e);
}
}
}
metricClientDisconnectionClient.inc();
} else {
metricClientDisconnectionKapuasys.inc();
}
// multiple account stealing link fix
info.setClientId(fullClientId);
context.setClientId(fullClientId);
} finally {
loginRemoveConnectionTimeContext.stop();
authenticationService.logout();
}
}
super.removeConnection(context, info, error);
context.setSecurityContext(null);
}
use of org.eclipse.kapua.service.device.registry.connection.DeviceConnection in project kapua by eclipse.
the class KapuaSecurityBrokerFilter method addExternalConnection.
private void addExternalConnection(ConnectionContext context, ConnectionInfo info) throws Exception {
// Clean-up credentials possibly associated with the current thread by previous connection.
ThreadContext.unbindSubject();
Context loginTotalContext = metricLoginAddConnectionTime.time();
String username = info.getUserName();
String password = info.getPassword();
String clientId = info.getClientId();
String clientIp = info.getClientIp();
ConnectionId connectionId = info.getConnectionId();
List<String> authDestinations = null;
if (logger.isDebugEnabled()) {
authDestinations = new ArrayList<>();
}
try {
// Build KapuaUsername
// User username = User.parse(username);//KapuaUserName
logger.info("User name {} - client id {}", new Object[] { username, clientId });
Context loginPreCheckTimeContext = metricLoginPreCheckTime.time();
// 1) validate client id
// Check the device Mqtt ClientId
// TODO move to deviceservice
// MqttUtils.checkDeviceClientId(clientId);
loginPreCheckTimeContext.stop();
Context loginShiroLoginTimeContext = metricLoginShiroLoginTime.time();
AuthenticationCredentials credentials = credentialsFactory.newInstance(username, password.toCharArray());
AccessToken accessToken = authenticationService.login(credentials);
KapuaId scopeId = accessToken.getScopeId();
KapuaId userId = accessToken.getUserId();
final Account account;
try {
account = KapuaSecurityUtils.doPriviledge(() -> accountService.find(scopeId));
} catch (Exception e) {
// to preserve the original exception message (if possible)
if (e instanceof AuthenticationException) {
throw (AuthenticationException) e;
} else {
throw new ShiroException("Error while find account!", e);
}
}
String accountName = account.getName();
loginShiroLoginTimeContext.stop();
// if a user acts as a child MOVED INSIDE KapuaAuthorizingRealm otherwise through REST API and console this @accountName won't work
// get account id and name from kapua session methods that check for the run as
//
// String accountName = kapuaSession.getSessionAccountName();
// long accountId = kapuaSession.getSessionAccountId();
// multiple account stealing link fix
String fullClientId = MessageFormat.format(AclConstants.MULTI_ACCOUNT_CLIENT_ID, scopeId.getId().longValue(), clientId);
KapuaPrincipal principal = new KapuaPrincipalImpl(accessToken, username, clientId, clientIp);
DeviceConnection deviceConnection = null;
// 3) check authorization
DefaultAuthorizationMap authMap = null;
if (isAdminUser(username)) {
metricLoginKapuasysTokenAttempt.inc();
// 3-1) admin authMap
authMap = buildAdminAuthMap(authDestinations, principal, fullClientId);
metricClientConnectedKapuasys.inc();
} else {
Context loginNormalUserTimeContext = metricLoginNormalUserTime.time();
metricLoginNormalUserAttempt.inc();
// 3-3) check permissions
Context loginCheckAccessTimeContext = metricLoginCheckAccessTime.time();
boolean[] hasPermissions = new boolean[] { // TODO check the permissions... move them to a constants class?
authorizationService.isPermitted(permissionFactory.newPermission(DeviceLifecycleDomain.DEVICE_LIFECYCLE, Actions.connect, scopeId)), authorizationService.isPermitted(permissionFactory.newPermission(DeviceManagementDomain.DEVICE_MANAGEMENT, Actions.write, scopeId)), authorizationService.isPermitted(permissionFactory.newPermission(DatastoreDomain.DATA_STORE, Actions.read, scopeId)), authorizationService.isPermitted(permissionFactory.newPermission(DatastoreDomain.DATA_STORE, Actions.write, scopeId)) };
if (!hasPermissions[AclConstants.BROKER_CONNECT_IDX]) {
throw new KapuaIllegalAccessException(permissionFactory.newPermission(DeviceLifecycleDomain.DEVICE_LIFECYCLE, Actions.connect, scopeId).toString());
}
loginCheckAccessTimeContext.stop();
// 3-4) build authMap
authMap = buildAuthMap(authDestinations, principal, hasPermissions, accountName, clientId, fullClientId);
// 4) find device
Context loginFindClientIdTimeContext = metricLoginFindClientIdTime.time();
deviceConnection = deviceConnectionService.findByClientId(scopeId, clientId);
loginFindClientIdTimeContext.stop();
Context loginFindDevTimeContext = metricLoginFindDevTime.time();
// send connect message
ConnectionId previousConnectionId = connectionMap.get(fullClientId);
boolean stealingLinkDetected = (previousConnectionId != null);
// Update map for stealing link detection on disconnect
connectionMap.put(fullClientId, info.getConnectionId());
if (deviceConnection == null) {
DeviceConnectionCreator deviceConnectionCreator = deviceConnectionFactory.newCreator(scopeId);
deviceConnectionCreator.setClientId(clientId);
deviceConnectionCreator.setClientIp(clientIp);
deviceConnectionCreator.setProtocol("MQTT");
// TODO to be filled with the proper value
deviceConnectionCreator.setServerIp(null);
deviceConnectionCreator.setUserId(userId);
deviceConnection = deviceConnectionService.create(deviceConnectionCreator);
} else {
deviceConnection.setClientIp(clientIp);
deviceConnection.setProtocol("MQTT");
// TODO to be filled with the proper value
deviceConnection.setServerIp(null);
deviceConnection.setUserId(userId);
deviceConnection.setStatus(DeviceConnectionStatus.CONNECTED);
deviceConnectionService.update(deviceConnection);
// TODO manage the stealing link event (may be a good idea to use different connect status (connect -stealing)?
if (stealingLinkDetected) {
metricLoginStealingLinkConnect.inc();
// stealing link detected, skip info
logger.warn("Detected Stealing link for cliend id {} - account - last connection id was {} - current connection id is {} - IP: {} - No connection status changes!", new Object[] { clientId, accountName, previousConnectionId, info.getConnectionId(), info.getClientIp() });
}
}
loginFindDevTimeContext.stop();
loginNormalUserTimeContext.stop();
Context loginSendLogingUpdateMsgTimeContex = metricLoginSendLoginUpdateMsgTime.time();
loginSendLogingUpdateMsgTimeContex.stop();
metricClientConnectedClient.inc();
}
logAuthDestinationToLog(authDestinations);
ConnectorDescriptor connectorDescriptor = connectorsDescriptorMap.get((((TransportConnector) context.getConnector()).getName()));
KapuaSecurityContext securityCtx = new KapuaSecurityContext(principal, authMap, (deviceConnection != null ? deviceConnection.getId() : null), connectionId, connectorDescriptor);
context.setSecurityContext(securityCtx);
// multiple account stealing link fix
info.setClientId(fullClientId);
context.setClientId(fullClientId);
} catch (Exception e) {
metricLoginFailure.inc();
// fix ENTMQ-731
if (e instanceof KapuaAuthenticationException) {
KapuaAuthenticationException kapuaException = (KapuaAuthenticationException) e;
KapuaErrorCode errorCode = kapuaException.getCode();
if (errorCode.equals(KapuaAuthenticationErrorCodes.INVALID_USERNAME) || errorCode.equals(KapuaAuthenticationErrorCodes.INVALID_CREDENTIALS) || errorCode.equals(KapuaAuthenticationErrorCodes.INVALID_CREDENTIALS_TOKEN_PROVIDED)) {
logger.warn("Invalid username or password for user {} ({})", username, e.getMessage());
// activeMQ will map CredentialException into a CONNECTION_REFUSED_BAD_USERNAME_OR_PASSWORD message (see javadoc on top of this method)
CredentialException ce = new CredentialException("Invalid username and/or password or disabled or expired account!");
ce.setStackTrace(e.getStackTrace());
metricLoginInvalidUserPassword.inc();
throw ce;
} else if (errorCode.equals(KapuaAuthenticationErrorCodes.LOCKED_USERNAME) || errorCode.equals(KapuaAuthenticationErrorCodes.DISABLED_USERNAME) || errorCode.equals(KapuaAuthenticationErrorCodes.EXPIRED_CREDENTIALS)) {
logger.warn("User {} not authorized ({})", username, e.getMessage());
// activeMQ-MQ will map SecurityException into a CONNECTION_REFUSED_NOT_AUTHORIZED message (see javadoc on top of this method)
SecurityException se = new SecurityException("User not authorized!");
se.setStackTrace(e.getStackTrace());
throw se;
}
}
// Excluded CredentialException, InvalidClientIDException, SecurityException all others exceptions will be mapped by activeMQ to a CONNECTION_REFUSED_SERVER_UNAVAILABLE message (see
// javadoc on top of this method)
// Not trapped exception now:
// KapuaException
logger.info("@@ error", e);
throw e;
} finally {
// 7) logout
Context loginShiroLogoutTimeContext = metricLoginShiroLogoutTime.time();
authenticationService.logout();
ThreadContext.unbindSubject();
loginShiroLogoutTimeContext.stop();
loginTotalContext.stop();
}
}
use of org.eclipse.kapua.service.device.registry.connection.DeviceConnection in project kapua by eclipse.
the class DeviceConnectionServiceImpl method update.
@Override
public DeviceConnection update(DeviceConnection deviceConnection) throws KapuaException {
//
// Argument Validation
ArgumentValidator.notNull(deviceConnection, "deviceConnection");
ArgumentValidator.notNull(deviceConnection.getId(), "deviceConnection.id");
ArgumentValidator.notNull(deviceConnection.getScopeId(), "deviceConnection.scopeId");
//
// Check Access
KapuaLocator locator = KapuaLocator.getInstance();
AuthorizationService authorizationService = locator.getService(AuthorizationService.class);
PermissionFactory permissionFactory = locator.getFactory(PermissionFactory.class);
authorizationService.checkPermission(permissionFactory.newPermission(DeviceConnectionDomain.DEVICE_CONNECTION, Actions.write, deviceConnection.getScopeId()));
//
// Do update
DeviceConnection deviceConnectionUpdated = null;
EntityManager em = DeviceEntityManagerFactory.getEntityManager();
try {
if (DeviceConnectionDAO.find(em, deviceConnection.getId()) == null) {
throw new KapuaEntityNotFoundException(DeviceConnection.TYPE, deviceConnection.getId());
}
em.beginTransaction();
deviceConnectionUpdated = DeviceConnectionDAO.update(em, deviceConnection);
em.commit();
} catch (Exception e) {
em.rollback();
throw KapuaExceptionUtils.convertPersistenceException(e);
} finally {
em.close();
}
return deviceConnectionUpdated;
}
use of org.eclipse.kapua.service.device.registry.connection.DeviceConnection in project kapua by eclipse.
the class DeviceConnectionServiceImpl method findByClientId.
@Override
public DeviceConnection findByClientId(KapuaId scopeId, String clientId) throws KapuaException {
//
// Argument Validation
ArgumentValidator.notNull(scopeId, "scopeId");
ArgumentValidator.notEmptyOrNull(clientId, "clientId");
//
// Build query
DeviceConnectionQueryImpl query = new DeviceConnectionQueryImpl(scopeId);
KapuaPredicate predicate = new AttributePredicate<String>(DeviceConnectionPredicates.CLIENT_ID, clientId);
query.setPredicate(predicate);
//
// Query and parse result
DeviceConnection device = null;
DeviceConnectionListResult result = query(query);
if (result.getSize() == 1) {
device = result.getItem(0);
}
return device;
}
use of org.eclipse.kapua.service.device.registry.connection.DeviceConnection in project kapua by eclipse.
the class GwtDeviceServiceImpl method findDeviceProfile.
public ListLoadResult<GwtGroupedNVPair> findDeviceProfile(String scopeIdString, String clientId) throws GwtKapuaException {
List<GwtGroupedNVPair> pairs = new ArrayList<GwtGroupedNVPair>();
KapuaLocator locator = KapuaLocator.getInstance();
DeviceRegistryService drs = locator.getService(DeviceRegistryService.class);
DeviceConnectionService dcs = locator.getService(DeviceConnectionService.class);
try {
KapuaId scopeId = KapuaEid.parseShortId(scopeIdString);
Device device = drs.findByClientId(scopeId, clientId);
if (device != null) {
pairs.add(new GwtGroupedNVPair("devInfo", "devStatus", device.getStatus().toString()));
DeviceConnection deviceConnection = dcs.findByClientId(scopeId, device.getClientId());
DeviceConnectionStatus connectionStatus = null;
if (deviceConnection != null) {
connectionStatus = deviceConnection.getStatus();
} else {
connectionStatus = DeviceConnectionStatus.DISCONNECTED;
}
pairs.add(new GwtGroupedNVPair("devInfo", "devConnectionStatus", connectionStatus.toString()));
pairs.add(new GwtGroupedNVPair("devInfo", "devClientId", device.getClientId()));
pairs.add(new GwtGroupedNVPair("devInfo", "devDisplayName", device.getDisplayName()));
String lastEventType = device.getLastEventType() != null ? device.getLastEventType().toString() : "";
pairs.add(new GwtGroupedNVPair("devInfo", "devLastEventType", lastEventType));
if (device.getLastEventOn() != null) {
pairs.add(new GwtGroupedNVPair("devInfo", "devLastEventOn", String.valueOf(device.getLastEventOn().getTime())));
} else {
pairs.add(new GwtGroupedNVPair("devInfo", "devLastEventOn", null));
}
if (device.getPreferredUserId() != null) {
pairs.add(new GwtGroupedNVPair("devInfo", "devLastUserUsed", device.getPreferredUserId().getShortId()));
}
pairs.add(new GwtGroupedNVPair("devInfo", "devApps", device.getApplicationIdentifiers()));
pairs.add(new GwtGroupedNVPair("devInfo", "devAccEnc", device.getAcceptEncoding()));
pairs.add(new GwtGroupedNVPair("devAttributesInfo", "devCustomAttribute1", device.getCustomAttribute1()));
pairs.add(new GwtGroupedNVPair("devAttributesInfo", "devCustomAttribute2", device.getCustomAttribute2()));
pairs.add(new GwtGroupedNVPair("devAttributesInfo", "devCustomAttribute3", device.getCustomAttribute3()));
pairs.add(new GwtGroupedNVPair("devAttributesInfo", "devCustomAttribute4", device.getCustomAttribute4()));
pairs.add(new GwtGroupedNVPair("devAttributesInfo", "devCustomAttribute5", device.getCustomAttribute5()));
// Credentials tight
pairs.add(new GwtGroupedNVPair("devSecurity", "devSecurityCredentialsTight", GwtDeviceCredentialsTight.valueOf(device.getCredentialsMode().name()).getLabel()));
pairs.add(new GwtGroupedNVPair("devSecurity", "devSecurityAllowCredentialsChange", device.getPreferredUserId() == null ? "Yes" : "No"));
pairs.add(new GwtGroupedNVPair("devHw", "devModelName", device.getModelId()));
pairs.add(new GwtGroupedNVPair("devHw", "devModelId", device.getModelId()));
pairs.add(new GwtGroupedNVPair("devHw", "devSerialNumber", device.getSerialNumber()));
pairs.add(new GwtGroupedNVPair("devSw", "devFirmwareVersion", device.getFirmwareVersion()));
pairs.add(new GwtGroupedNVPair("devSw", "devBiosVersion", device.getBiosVersion()));
pairs.add(new GwtGroupedNVPair("devSw", "devOsVersion", device.getOsVersion()));
pairs.add(new GwtGroupedNVPair("devJava", "devJvmVersion", device.getJvmVersion()));
pairs.add(new GwtGroupedNVPair("netInfo", "netConnIp", deviceConnection.getClientIp()));
pairs.add(new GwtGroupedNVPair("gpsInfo", "gpsLat", String.valueOf(device.getGpsLatitude())));
pairs.add(new GwtGroupedNVPair("gpsInfo", "gpsLong", String.valueOf(device.getGpsLongitude())));
pairs.add(new GwtGroupedNVPair("modemInfo", "modemImei", device.getImei()));
pairs.add(new GwtGroupedNVPair("modemInfo", "modemImsi", device.getImsi()));
pairs.add(new GwtGroupedNVPair("modemInfo", "modemIccid", device.getIccid()));
}
} catch (Throwable t) {
KapuaExceptionHandler.handle(t);
}
return new BaseListLoadResult<GwtGroupedNVPair>(pairs);
}
Aggregations