Merge branch 'develop' of https://github.com/4treesCH/strolch.git into develop
This commit is contained in:
commit
4b5d8e559e
|
@ -62,38 +62,36 @@ public class AuthenticationService {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|
||||||
StringBuilder sb = new StringBuilder();
|
if (!login.has("username") || login.get("username").getAsString().length() < 2) {
|
||||||
JsonElement usernameE = login.get("username");
|
logger.error("Authentication failed: Username was not given or is too short!");
|
||||||
if (usernameE == null || usernameE.getAsString().length() < 2) {
|
loginResult.addProperty("msg", MessageFormat.format("Could not log in due to: {0}",
|
||||||
sb.append("Username was not given or is too short!"); //$NON-NLS-1$
|
"Username was not given or is too short!")); //$NON-NLS-2$
|
||||||
|
return Response.status(Status.BAD_REQUEST).entity(loginResult.toString()).build();
|
||||||
}
|
}
|
||||||
|
|
||||||
JsonElement passwordE = login.get("password");
|
if (!login.has("password") || login.get("password").getAsString().length() < 3) {
|
||||||
if (passwordE == null) {
|
logger.error("Authentication failed: Password was not given or is too short!");
|
||||||
if (sb.length() > 0)
|
loginResult.addProperty("msg", MessageFormat.format("Could not log in due to: {0}",
|
||||||
sb.append("\n");
|
"Password was not given or is too short!")); //$NON-NLS-2$
|
||||||
sb.append("Password was not given!"); //$NON-NLS-1$
|
return Response.status(Status.BAD_REQUEST).entity(loginResult.toString()).build();
|
||||||
}
|
}
|
||||||
|
|
||||||
char[] password = passwordE == null ?
|
String username = login.get("username").getAsString();
|
||||||
new char[] {} :
|
String passwordEncoded = login.get("password").getAsString();
|
||||||
new String(Base64.getDecoder().decode(passwordE.getAsString())).toCharArray();
|
|
||||||
|
byte[] decode = Base64.getDecoder().decode(passwordEncoded);
|
||||||
|
char[] password = new String(decode).toCharArray();
|
||||||
|
|
||||||
if (password.length < 3) {
|
if (password.length < 3) {
|
||||||
if (sb.length() > 0)
|
logger.error("Authentication failed: Password was not given or is too short!");
|
||||||
sb.append("\n");
|
loginResult.addProperty("msg", MessageFormat.format("Could not log in due to: {0}",
|
||||||
sb.append("Password not given or too short!"); //$NON-NLS-1$
|
"Password was not given or is too short!")); //$NON-NLS-2$
|
||||||
}
|
|
||||||
|
|
||||||
if (sb.length() != 0) {
|
|
||||||
logger.error("Authentication failed due to: " + sb.toString());
|
|
||||||
loginResult.addProperty("msg",
|
|
||||||
MessageFormat.format("Could not log in due to: {0}", sb.toString())); //$NON-NLS-2$
|
|
||||||
return Response.status(Status.BAD_REQUEST).entity(loginResult.toString()).build();
|
return Response.status(Status.BAD_REQUEST).entity(loginResult.toString()).build();
|
||||||
}
|
}
|
||||||
|
|
||||||
StrolchSessionHandler sessionHandler = RestfulStrolchComponent.getInstance().getSessionHandler();
|
StrolchSessionHandler sessionHandler = RestfulStrolchComponent.getInstance().getSessionHandler();
|
||||||
String source = getRemoteIp(request);
|
String source = getRemoteIp(request);
|
||||||
Certificate certificate = sessionHandler.authenticate(usernameE.getAsString(), password, source);
|
Certificate certificate = sessionHandler.authenticate(username, password, source);
|
||||||
|
|
||||||
return getAuthenticationResponse(request, loginResult, certificate, source);
|
return getAuthenticationResponse(request, loginResult, certificate, source);
|
||||||
|
|
||||||
|
|
|
@ -48,6 +48,8 @@ import li.strolch.service.JsonServiceArgument;
|
||||||
import li.strolch.service.api.ServiceHandler;
|
import li.strolch.service.api.ServiceHandler;
|
||||||
import li.strolch.service.api.ServiceResult;
|
import li.strolch.service.api.ServiceResult;
|
||||||
import li.strolch.service.privilege.users.*;
|
import li.strolch.service.privilege.users.*;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Robert von Burg <eitch@eitchnet.ch>
|
* @author Robert von Burg <eitch@eitchnet.ch>
|
||||||
|
@ -55,6 +57,8 @@ import li.strolch.service.privilege.users.*;
|
||||||
@Path("strolch/privilege/users")
|
@Path("strolch/privilege/users")
|
||||||
public class PrivilegeUsersService {
|
public class PrivilegeUsersService {
|
||||||
|
|
||||||
|
private static final Logger logger = LoggerFactory.getLogger(PrivilegeUsersService.class);
|
||||||
|
|
||||||
private PrivilegeHandler getPrivilegeHandler() {
|
private PrivilegeHandler getPrivilegeHandler() {
|
||||||
ComponentContainer container = RestfulStrolchComponent.getInstance().getContainer();
|
ComponentContainer container = RestfulStrolchComponent.getInstance().getContainer();
|
||||||
return container.getPrivilegeHandler().getPrivilegeHandler();
|
return container.getPrivilegeHandler().getPrivilegeHandler();
|
||||||
|
@ -270,26 +274,38 @@ public class PrivilegeUsersService {
|
||||||
@Context HttpServletRequest request) {
|
@Context HttpServletRequest request) {
|
||||||
Certificate cert = (Certificate) request.getAttribute(StrolchRestfulConstants.STROLCH_CERTIFICATE);
|
Certificate cert = (Certificate) request.getAttribute(StrolchRestfulConstants.STROLCH_CERTIFICATE);
|
||||||
|
|
||||||
String password = new JsonParser().parse(data).getAsJsonObject().get("password").getAsString();
|
try {
|
||||||
char[] passwordChars = new String(Base64.getDecoder().decode(password)).toCharArray();
|
|
||||||
|
|
||||||
ServiceHandler svcHandler = RestfulStrolchComponent.getInstance().getComponent(ServiceHandler.class);
|
JsonObject jsonObject = new JsonParser().parse(data).getAsJsonObject();
|
||||||
PrivilegeSetUserPasswordService svc = new PrivilegeSetUserPasswordService();
|
|
||||||
PrivilegeSetUserPasswordArgument arg = new PrivilegeSetUserPasswordArgument();
|
|
||||||
arg.username = username;
|
|
||||||
arg.password = passwordChars;
|
|
||||||
|
|
||||||
ServiceResult svcResult = svcHandler.doService(cert, svc, arg);
|
String passwordEncoded = jsonObject.get("password").getAsString();
|
||||||
if (svcResult.isNok())
|
byte[] decode = Base64.getDecoder().decode(passwordEncoded);
|
||||||
return ResponseUtil.toResponse(svcResult);
|
String passwordString = new String(decode);
|
||||||
|
|
||||||
// if user changes their own password, then invalidate the session
|
ServiceHandler svcHandler = RestfulStrolchComponent.getInstance().getComponent(ServiceHandler.class);
|
||||||
if (cert.getUsername().equals(username)) {
|
PrivilegeSetUserPasswordService svc = new PrivilegeSetUserPasswordService();
|
||||||
StrolchSessionHandler sessionHandler = RestfulStrolchComponent.getInstance().getSessionHandler();
|
PrivilegeSetUserPasswordArgument arg = new PrivilegeSetUserPasswordArgument();
|
||||||
sessionHandler.invalidate(cert);
|
arg.username = username;
|
||||||
|
arg.password = passwordString.toCharArray();
|
||||||
|
|
||||||
|
ServiceResult svcResult = svcHandler.doService(cert, svc, arg);
|
||||||
|
if (svcResult.isNok())
|
||||||
|
return ResponseUtil.toResponse(svcResult);
|
||||||
|
|
||||||
|
// if user changes their own password, then invalidate the session
|
||||||
|
if (cert.getUsername().equals(username)) {
|
||||||
|
StrolchSessionHandler sessionHandler = RestfulStrolchComponent.getInstance().getSessionHandler();
|
||||||
|
sessionHandler.invalidate(cert);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ResponseUtil.toResponse();
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
logger.error(e.getMessage(), e);
|
||||||
|
String msg = e.getMessage();
|
||||||
|
return ResponseUtil.toResponse("Failed to set password: ",
|
||||||
|
MessageFormat.format("{0}: {1}", e.getClass().getName(), msg));
|
||||||
}
|
}
|
||||||
|
|
||||||
return ResponseUtil.toResponse();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private Response handleServiceResult(PrivilegeUserResult svcResult) {
|
private Response handleServiceResult(PrivilegeUserResult svcResult) {
|
||||||
|
|
|
@ -43,7 +43,7 @@ public class SetActionToClosedCommand extends ExecutionCommand {
|
||||||
tx().lock(getResourceLocator(this.action));
|
tx().lock(getResourceLocator(this.action));
|
||||||
|
|
||||||
if (this.action.getState() == State.CLOSED) {
|
if (this.action.getState() == State.CLOSED) {
|
||||||
logger.warn("Action " + this.action.getLocator() + " is already in CLOSED! Not changing.");
|
logger.warn("Action " + this.action.getLocator() + " is already in state CLOSED! Not changing.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -43,7 +43,7 @@ public class SetActionToCreatedCommand extends ExecutionCommand {
|
||||||
tx().lock(getResourceLocator(this.action));
|
tx().lock(getResourceLocator(this.action));
|
||||||
|
|
||||||
if (this.action.getState() == State.CREATED) {
|
if (this.action.getState() == State.CREATED) {
|
||||||
logger.warn("Action " + this.action.getLocator() + " is already in CREATED! Not changing.");
|
logger.warn("Action " + this.action.getLocator() + " is already in state CREATED! Not changing.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -43,7 +43,7 @@ public class SetActionToErrorCommand extends ExecutionCommand {
|
||||||
tx().lock(getResourceLocator(this.action));
|
tx().lock(getResourceLocator(this.action));
|
||||||
|
|
||||||
if (this.action.getState() == State.ERROR) {
|
if (this.action.getState() == State.ERROR) {
|
||||||
logger.warn("Action " + this.action.getLocator() + " is already in ERROR! Not changing.");
|
logger.warn("Action " + this.action.getLocator() + " is already in state ERROR! Not changing.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -43,7 +43,7 @@ public class SetActionToExecutedCommand extends ExecutionCommand {
|
||||||
tx().lock(getResourceLocator(this.action));
|
tx().lock(getResourceLocator(this.action));
|
||||||
|
|
||||||
if (this.action.getState() == State.EXECUTED) {
|
if (this.action.getState() == State.EXECUTED) {
|
||||||
logger.warn("Action " + this.action.getLocator() + " is already in EXECUTED! Not changing.");
|
logger.warn("Action " + this.action.getLocator() + " is already in state EXECUTED! Not changing.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -43,7 +43,7 @@ public class SetActionToPlannedCommand extends ExecutionCommand {
|
||||||
tx().lock(getResourceLocator(this.action));
|
tx().lock(getResourceLocator(this.action));
|
||||||
|
|
||||||
if (this.action.getState() == State.PLANNED) {
|
if (this.action.getState() == State.PLANNED) {
|
||||||
logger.warn("Action " + this.action.getLocator() + " is already in PLANNED! Not changing.");
|
logger.warn("Action " + this.action.getLocator() + " is already in state PLANNED! Not changing.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -43,7 +43,7 @@ public class SetActionToPlanningCommand extends ExecutionCommand {
|
||||||
tx().lock(getResourceLocator(this.action));
|
tx().lock(getResourceLocator(this.action));
|
||||||
|
|
||||||
if (this.action.getState() == State.PLANNING) {
|
if (this.action.getState() == State.PLANNING) {
|
||||||
logger.warn("Action " + this.action.getLocator() + " is already in PLANNING! Not changing.");
|
logger.warn("Action " + this.action.getLocator() + " is already in state PLANNING! Not changing.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -43,7 +43,7 @@ public class SetActionToStoppedCommand extends ExecutionCommand {
|
||||||
tx().lock(getResourceLocator(this.action));
|
tx().lock(getResourceLocator(this.action));
|
||||||
|
|
||||||
if (this.action.getState() == State.STOPPED) {
|
if (this.action.getState() == State.STOPPED) {
|
||||||
logger.warn("Action " + this.action.getLocator() + " is already in STOPPED! Not changing.");
|
logger.warn("Action " + this.action.getLocator() + " is already in state STOPPED! Not changing.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -43,7 +43,7 @@ public class SetActionToWarningCommand extends ExecutionCommand {
|
||||||
tx().lock(getResourceLocator(this.action));
|
tx().lock(getResourceLocator(this.action));
|
||||||
|
|
||||||
if (this.action.getState() == State.WARNING) {
|
if (this.action.getState() == State.WARNING) {
|
||||||
logger.warn("Action " + this.action.getLocator() + " is already in WARNING! Not changing.");
|
logger.warn("Action " + this.action.getLocator() + " is already in state WARNING! Not changing.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -11,6 +11,12 @@ import li.strolch.service.api.ServiceArgument;
|
||||||
* @author Robert von Burg <eitch@eitchnet.ch>
|
* @author Robert von Burg <eitch@eitchnet.ch>
|
||||||
*/
|
*/
|
||||||
public class JsonServiceArgument extends ServiceArgument {
|
public class JsonServiceArgument extends ServiceArgument {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* the objectType - its context is defined by the service
|
||||||
|
*/
|
||||||
|
public String objectType;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* the objectId - its context is defined by the service
|
* the objectId - its context is defined by the service
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -34,6 +34,7 @@ public class WebSocketClient implements MessageHandler.Whole<String> {
|
||||||
private ComponentContainer container;
|
private ComponentContainer container;
|
||||||
private final Session session;
|
private final Session session;
|
||||||
private final EndpointConfig config;
|
private final EndpointConfig config;
|
||||||
|
private String remoteIp;
|
||||||
|
|
||||||
private Certificate certificate;
|
private Certificate certificate;
|
||||||
private Map<String, WebSocketObserverHandler> observerHandlersByRealm;
|
private Map<String, WebSocketObserverHandler> observerHandlersByRealm;
|
||||||
|
@ -42,6 +43,7 @@ public class WebSocketClient implements MessageHandler.Whole<String> {
|
||||||
this.container = container;
|
this.container = container;
|
||||||
this.session = session;
|
this.session = session;
|
||||||
this.config = config;
|
this.config = config;
|
||||||
|
this.remoteIp = WebSocketRemoteIp.get();
|
||||||
this.observerHandlersByRealm = new HashMap<>(1);
|
this.observerHandlersByRealm = new HashMap<>(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -50,6 +52,7 @@ public class WebSocketClient implements MessageHandler.Whole<String> {
|
||||||
|
|
||||||
JsonObject jsonObject = new JsonParser().parse(message).getAsJsonObject();
|
JsonObject jsonObject = new JsonParser().parse(message).getAsJsonObject();
|
||||||
String msgType = jsonObject.get(MSG_TYPE).getAsString();
|
String msgType = jsonObject.get(MSG_TYPE).getAsString();
|
||||||
|
logger.info("Handling message " + msgType);
|
||||||
|
|
||||||
switch (msgType) {
|
switch (msgType) {
|
||||||
|
|
||||||
|
@ -75,13 +78,13 @@ public class WebSocketClient implements MessageHandler.Whole<String> {
|
||||||
|
|
||||||
if (this.certificate == null) {
|
if (this.certificate == null) {
|
||||||
logger.error("Received " + type + " request, but not yet authed!");
|
logger.error("Received " + type + " request, but not yet authed!");
|
||||||
close(CloseReason.CloseCodes.UNEXPECTED_CONDITION, "Not yet authed!");
|
close(CloseReason.CloseCodes.PROTOCOL_ERROR, "Not yet authed!");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
StrolchSessionHandler sessionHandler = RestfulStrolchComponent.getInstance().getSessionHandler();
|
StrolchSessionHandler sessionHandler = RestfulStrolchComponent.getInstance().getSessionHandler();
|
||||||
sessionHandler.validate(this.certificate);
|
sessionHandler.validate(this.certificate, this.remoteIp);
|
||||||
} catch (RuntimeException e) {
|
} catch (RuntimeException e) {
|
||||||
logger.error("Received " + type + " request, but authentication is not valid anymore: " + ExceptionHelper
|
logger.error("Received " + type + " request, but authentication is not valid anymore: " + ExceptionHelper
|
||||||
.getExceptionMessage(e));
|
.getExceptionMessage(e));
|
||||||
|
@ -144,13 +147,14 @@ public class WebSocketClient implements MessageHandler.Whole<String> {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
StrolchSessionHandler sessionHandler = RestfulStrolchComponent.getInstance().getSessionHandler();
|
StrolchSessionHandler sessionHandler = RestfulStrolchComponent.getInstance().getSessionHandler();
|
||||||
this.certificate = sessionHandler.validate(authToken, WebSocketRemoteIp.get());
|
this.certificate = sessionHandler.validate(authToken, this.remoteIp);
|
||||||
if (!this.certificate.getUsername().equals(username)) {
|
if (!this.certificate.getUsername().equals(username)) {
|
||||||
logger.error("Invalid authentication for " + username);
|
logger.error("Invalid authentication for " + username);
|
||||||
close(CloseReason.CloseCodes.UNEXPECTED_CONDITION, "Invalid authentication");
|
close(CloseReason.CloseCodes.UNEXPECTED_CONDITION, "Invalid authentication");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
|
logger.error("Failed to authenticate user " + username, e);
|
||||||
close(CloseReason.CloseCodes.UNEXPECTED_CONDITION, "Invalid authentication");
|
close(CloseReason.CloseCodes.UNEXPECTED_CONDITION, "Invalid authentication");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue