use of won.owner.model.User in project webofneeds by researchstudio-sat.
the class WonWebSocketHandler method handleTextMessage.
/**
* Receives a message from the client and passes it on to the WoN node.
*/
@Override
@Transactional(propagation = Propagation.SUPPORTS, isolation = Isolation.READ_COMMITTED)
public void handleTextMessage(WebSocketSession session, TextMessage message) throws IOException {
logger.debug("OA Server - WebSocket message received: {}", message.getPayload());
updateSession(session);
if (!message.isLast()) {
// we have an intermediate part of the current message.
session.getAttributes().putIfAbsent(SESSION_ATTRIBUTE_PARTIAL_MESSAGE, new StringBuilder());
}
// now check if we have the partial message string builder in the session.
// if we do, we're processing a partial message, and we have to append the
// current message payload
StringBuilder sb = (StringBuilder) session.getAttributes().get(SESSION_ATTRIBUTE_PARTIAL_MESSAGE);
// will hold the final message
String completePayload = null;
if (sb == null) {
// No string builder found in the session - we're not processing a partial
// message.
// The complete payload is in the current message. Get it and continue.
completePayload = message.getPayload();
} else {
// the string builder is there - we're processing a partial message. append the
// current piece
sb.append(message.getPayload());
if (message.isLast()) {
// we've received the last part. pass it on to the next processing steps.
completePayload = sb.toString();
// also, we do not atom the string builder in the session any longer. remove it:
session.getAttributes().remove(SESSION_ATTRIBUTE_PARTIAL_MESSAGE);
} else {
// next part
return;
}
}
final String ECHO_STRING = "e";
if (completePayload.equals(ECHO_STRING)) {
return;
}
WonMessage wonMessage = null;
URI atomUri = null;
try {
wonMessage = WonMessageDecoder.decodeFromJsonLd(completePayload);
// remember which user or (if not logged in) which atomUri the session is bound
// to
User user = getUserForSession(session);
if (user != null) {
logger.debug("binding session to user {}", user.getId());
this.webSocketSessionService.addMapping(user, session);
}
// anyway, we have to bind the URI to the session, otherwise we can't handle
// incoming server->client messages
atomUri = wonMessage.getSenderAtomURI();
if (user != null && atomUri != null) {
this.userAtomService.updateUserAtomAssociation(wonMessage, user);
}
logger.debug("binding session to atom URI {}", atomUri);
this.webSocketSessionService.addMapping(atomUri, session);
} catch (Exception e) {
// ignore this message
LoggingUtils.logMessageAsInfoAndStacktraceAsDebug(logger, e, "Ignoring WonMessage received via Websocket that caused an Exception");
WebSocketMessage<String> wsMsg = new TextMessage("{'error':'Error processing WonMessage: " + e.getMessage() + "'}");
return;
}
try {
AuthenticationThreadLocal.setAuthentication((Authentication) session.getPrincipal());
wonMessage = ownerApplicationService.prepareMessage(wonMessage);
ownerApplicationService.sendMessage(wonMessage);
if (wonMessage.getMessageType() == WonMessageType.DELETE) {
// (receiving success response for delete msg)
try {
userAtomService.setAtomDeleted(atomUri);
/*
* //Get the user from owner application db user =
* userRepository.findOne(user.getId()); //Delete atom in users atom list and
* save changes user.deleteAtomUri(userAtom); userRepository.save(user);
* //Delete atom in atom repository userAtomRepository.delete(userAtom.getId());
*/
} catch (Exception e) {
logger.debug("Could not delete atom with uri {} because of {}", atomUri, e);
}
}
} finally {
// be sure to remove the principal from the threadlocal
AuthenticationThreadLocal.remove();
}
}
use of won.owner.model.User in project webofneeds by researchstudio-sat.
the class WonWebSocketHandler method process.
/**
* Sends a message coming from the WoN node to the client.
*/
@Override
@Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.READ_COMMITTED)
public WonMessage process(final WonMessage wonMessage) {
try {
logger.debug("processing message {} incoming from node", wonMessage.getMessageURI());
String wonMessageJsonLdString = WonMessageEncoder.encodeAsJsonLd(wonMessage);
WebSocketMessage<String> webSocketMessage = new TextMessage(wonMessageJsonLdString);
logger.debug("determining which owned atom is to be informed of message {} ", wonMessage.getMessageURI());
URI atomUri = getOwnedAtomURIForMessageFromNode(wonMessage);
logger.debug("obtaining WebSocketSessions for message {} ", wonMessage.getMessageURI());
Set<WebSocketSession> webSocketSessions = webSocketSessionService.getWebSocketSessions(atomUri);
Optional<User> userOpt = webSocketSessions == null ? Optional.empty() : webSocketSessions.stream().filter(s -> s.isOpen()).findFirst().map(s -> getUserForSession(s));
logger.debug("found {} sessions for message {} ", webSocketSessions.size(), wonMessage.getMessageURI());
logger.debug("found user for message {} via session: {} ", wonMessage.getMessageURI(), userOpt.isPresent());
if (!userOpt.isPresent()) {
userOpt = Optional.ofNullable(userRepository.findByAtomUri(atomUri));
}
logger.debug("found user for message {} atom uri: {} ", wonMessage.getMessageURI(), userOpt.isPresent());
// it's quite possible that we don't find the user object this way.
User user = userOpt.orElse(null);
// Methods below can handle that.
logger.debug("updating user-atom association for message {}, user has been found:{} ", wonMessage.getMessageURI(), userOpt.isPresent());
userAtomService.updateUserAtomAssociation(wonMessage, user);
logger.debug("trying to find WebSocketSessions for message{}, atom {}, user has been found:{}", new Object[] { wonMessage.getMessageURI(), atomUri, userOpt.isPresent() });
webSocketSessions = webSocketSessionService.findWebSocketSessionsForAtomAndUser(atomUri, user);
// check if we can deliver the message. If not, send email.
if (webSocketSessions.size() == 0) {
if (logger.isDebugEnabled()) {
logger.debug("cannot deliver message {}: no websocket session found. Trying to send message by email.", wonMessage.toShortStringForDebug());
}
notifyUserOnDifferentChannel(wonMessage, atomUri, user);
return wonMessage;
}
// we can send it - pre-cache the delivery chain:
logger.debug("put message {} into cache before sending on websocket", wonMessage.getMessageURI());
eagerlyCachePopulatingProcessor.process(wonMessage);
// send to owner webapp
int successfullySent = 0;
for (WebSocketSession session : webSocketSessions) {
logger.debug("sending message {} via websocket session", wonMessage.getMessageURI());
successfullySent += sendMessageForSession(wonMessage, webSocketMessage, session, atomUri, user) ? 1 : 0;
}
logger.debug("sent message {} via {} websocket sessions", wonMessage.getMessageURI(), successfullySent);
if (successfullySent == 0) {
// we did not manage to send the message via the websocket, send it by email.
if (logger.isDebugEnabled()) {
logger.debug("cannot deliver message {}: none of the associated websocket sessions worked. Trying to send message by webpush and email.", wonMessage.toShortStringForDebug());
}
// TODO: ideally in this case
// 1. collect multiple events occurring in close succession
// 2. try to push
// 3. email only if push was not successful
notifyUserOnDifferentChannel(wonMessage, atomUri, user);
} else {
// Always send possible pushNotifications:
// - maybe session is active -> message was send, but Tab is not focused
// - Browser is running in background -> user needs to get push notification
Optional<URI> connectionURI = WonLinkedDataUtils.getConnectionURIForIncomingMessage(wonMessage, linkedDataSource);
if (connectionURI.isPresent()) {
logger.debug("notifying user per web push for message {}", wonMessage.getMessageURI());
UserAtom userAtom = getAtomOfUser(user, atomUri);
if (userAtom == null) {
userOpt = Optional.ofNullable(userRepository.findByAtomUri(atomUri));
user = userOpt.orElse(null);
}
notifyPerPush(user, atomUri, wonMessage, connectionURI.get());
}
logger.debug("cannot notify user: cannot determine connection URI");
}
return wonMessage;
} finally {
// in any case, let the serversideactionservice do its work, if there is any to
// do:
logger.debug("processing server side actions for message {} if any are registered", wonMessage.getMessageURI());
serverSideActionService.process(wonMessage);
}
}
use of won.owner.model.User in project webofneeds by researchstudio-sat.
the class RestUserController method resetPassword.
/**
* Resets the user's password using the recovery key.
*
* @param resetPasswordPojo password changing data
* @param errors
* @return ResponseEntity with Http Status Code
*/
@ResponseBody
@RequestMapping(value = "/resetPassword", produces = MediaType.APPLICATION_JSON_VALUE, method = RequestMethod.POST)
// TODO: move transactionality annotation into the service layer
@Transactional(propagation = Propagation.REQUIRED)
public ResponseEntity resetPassword(@RequestBody ResetPasswordPojo resetPasswordPojo, Errors errors, HttpServletRequest request, HttpServletResponse response) {
logger.debug("processing request to /resetPassword");
try {
resetPasswordValidator.validate(resetPasswordPojo, errors);
if (errors.hasErrors()) {
if (errors.getFieldErrorCount() > 0) {
return generateStatusResponse(RestStatusResponse.PASSWORDCHANGE_BAD_PASSWORD);
} else {
// username is not found
return generateStatusResponse(RestStatusResponse.PASSWORDCHANGE_USER_NOT_FOUND);
}
}
User user = userService.useRecoveryKey(resetPasswordPojo.getUsername(), resetPasswordPojo.getNewPassword(), resetPasswordPojo.getRecoveryKey());
eventPublisher.publishEvent(new OnPasswordChangedEvent(user, request.getLocale(), request.getContextPath()));
String recoveryKey = userService.generateRecoveryKey(resetPasswordPojo.getUsername(), resetPasswordPojo.getNewPassword());
eventPublisher.publishEvent(new OnRecoveryKeyGeneratedEvent(user, recoveryKey));
return generateUserResponse(user);
} catch (IncorrectPasswordException e) {
return generateStatusResponse(RestStatusResponse.PASSWORDCHANGE_WRONG_OLD_PASSWORD);
} catch (UserNotFoundException e) {
return generateStatusResponse(RestStatusResponse.USER_NOT_FOUND);
} catch (KeyStoreIOException e) {
return generateStatusResponse(RestStatusResponse.PASSWORDCHANGE_KEYSTORE_PROBLEM);
}
}
use of won.owner.model.User in project webofneeds by researchstudio-sat.
the class RestUserController method getUserSettings.
@ResponseBody
@RequestMapping(value = "/settings", produces = MediaType.APPLICATION_JSON_VALUE, method = RequestMethod.GET)
public List<UserSettingsPojo> getUserSettings(@RequestParam(name = "uri", required = false) String uri) {
logger.debug("processing request to /settings");
String username = SecurityContextHolder.getContext().getAuthentication().getName();
// cannot use user object from context since hw doesn't know about created in
// this session atom,
// therefore, we have to retrieve the user object from the user repository
User user = userService.getByUsername(username);
List<UserSettingsPojo> userSettings = new ArrayList<UserSettingsPojo>();
if (uri != null) {
URI atomUri = null;
try {
atomUri = new URI(uri);
for (UserAtom userAtom : user.getUserAtoms()) {
if (userAtom.getUri().equals(atomUri)) {
userSettings.add(new UserSettingsPojo(user.getUsername(), user.getEmail(), userAtom.getUri(), userAtom.isMatches(), userAtom.isRequests(), userAtom.isConversations()));
break;
}
}
} catch (URISyntaxException e) {
// TODO error response
logger.warn(uri + " atom uri problem", e);
}
} else {
// No specific uri requested => all userSettings
for (UserAtom userAtom : user.getUserAtoms()) {
if (userAtom.getState() != AtomState.DELETED) {
userSettings.add(new UserSettingsPojo(user.getUsername(), user.getEmail(), userAtom.getUri(), userAtom.isMatches(), userAtom.isRequests(), userAtom.isConversations()));
}
}
}
return userSettings;
}
use of won.owner.model.User in project webofneeds by researchstudio-sat.
the class RestUserController method exportAccount.
@ResponseBody
@RequestMapping(value = "/exportAccount", method = RequestMethod.POST)
public ResponseEntity exportAccount(@RequestParam(name = "keyStorePassword", required = false) String keyStorePassword) {
logger.debug("processing request to /exportAccount");
SecurityContext securityContext = SecurityContextHolder.getContext();
User authUser = ((KeystoreEnabledUserDetails) securityContext.getAuthentication().getPrincipal()).getUser();
User user = userService.getByUsername(authUser.getUsername());
String responseEmail = null;
if (user.isEmailVerified()) {
responseEmail = user.getEmail();
} else {
return generateStatusResponse(RestStatusResponse.EXPORT_NOT_VERIFIED);
}
eventPublisher.publishEvent(new OnExportUserEvent(securityContext.getAuthentication(), keyStorePassword, responseEmail));
return generateStatusResponse(RestStatusResponse.EXPORT_SUCCESS);
}
Aggregations