Search in sources :

Example 31 with User

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();
    }
}
Also used : User(won.owner.model.User) WonMessage(won.protocol.message.WonMessage) WebSocketMessage(org.springframework.web.socket.WebSocketMessage) URI(java.net.URI) UncheckedIOException(java.io.UncheckedIOException) NoSuchAlgorithmException(java.security.NoSuchAlgorithmException) MailException(org.springframework.mail.MailException) IOException(java.io.IOException) TextMessage(org.springframework.web.socket.TextMessage) Transactional(org.springframework.transaction.annotation.Transactional)

Example 32 with User

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);
    }
}
Also used : StringUtils(org.apache.commons.lang.StringUtils) OwnerApplicationService(won.owner.service.impl.OwnerApplicationService) LoggerFactory(org.slf4j.LoggerFactory) SessionRepository(org.springframework.session.SessionRepository) Autowired(org.springframework.beans.factory.annotation.Autowired) UserRepository(won.owner.repository.UserRepository) CloseStatus(org.springframework.web.socket.CloseStatus) LoggingUtils(won.protocol.util.LoggingUtils) TextMessage(org.springframework.web.socket.TextMessage) Duration(java.time.Duration) Map(java.util.Map) URI(java.net.URI) WonMessageEncoder(won.protocol.message.WonMessageEncoder) WonLinkedDataUtils(won.protocol.util.linkeddata.WonLinkedDataUtils) WonMessageType(won.protocol.message.WonMessageType) MethodHandles(java.lang.invoke.MethodHandles) Set(java.util.Set) Collectors(java.util.stream.Collectors) StandardCharsets(java.nio.charset.StandardCharsets) WonRdfUtils(won.protocol.util.WonRdfUtils) UncheckedIOException(java.io.UncheckedIOException) Base64(java.util.Base64) Principal(java.security.Principal) DisposableBean(org.springframework.beans.factory.DisposableBean) NoSuchAlgorithmException(java.security.NoSuchAlgorithmException) ServerSideActionService(won.owner.web.service.ServerSideActionService) Optional(java.util.Optional) MailException(org.springframework.mail.MailException) Authentication(org.springframework.security.core.Authentication) Isolation(org.springframework.transaction.annotation.Isolation) LinkedDataSource(won.protocol.util.linkeddata.LinkedDataSource) UserAtom(won.owner.model.UserAtom) AuthenticationThreadLocal(won.protocol.util.AuthenticationThreadLocal) ConnectionState(won.protocol.model.ConnectionState) MessageDigest(java.security.MessageDigest) WonMessageDecoder(won.protocol.message.WonMessageDecoder) WebSocketSession(org.springframework.web.socket.WebSocketSession) InitializingBean(org.springframework.beans.factory.InitializingBean) WonMessage(won.protocol.message.WonMessage) MessageFormat(java.text.MessageFormat) TextWebSocketHandler(org.springframework.web.socket.handler.TextWebSocketHandler) Propagation(org.springframework.transaction.annotation.Propagation) WonMessageProcessor(won.protocol.message.processor.WonMessageProcessor) ObjectNode(org.codehaus.jackson.node.ObjectNode) WonOwnerPushSender(won.owner.web.WonOwnerPushSender) Order(org.springframework.core.annotation.Order) Logger(org.slf4j.Logger) WebSocketMessage(org.springframework.web.socket.WebSocketMessage) WonOwnerMailSender(won.owner.web.WonOwnerMailSender) Session(org.springframework.session.Session) IOException(java.io.IOException) KeystoreEnabledUserDetails(won.owner.service.impl.KeystoreEnabledUserDetails) User(won.owner.model.User) URIService(won.owner.service.impl.URIService) BatchingConsumer(won.utils.batch.BatchingConsumer) UserAtomService(won.owner.web.service.UserAtomService) ObjectMapper(org.codehaus.jackson.map.ObjectMapper) Transactional(org.springframework.transaction.annotation.Transactional) User(won.owner.model.User) UserAtom(won.owner.model.UserAtom) URI(java.net.URI) TextMessage(org.springframework.web.socket.TextMessage) WebSocketSession(org.springframework.web.socket.WebSocketSession) Transactional(org.springframework.transaction.annotation.Transactional)

Example 33 with User

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);
    }
}
Also used : OnRecoveryKeyGeneratedEvent(won.owner.web.events.OnRecoveryKeyGeneratedEvent) UserNotFoundException(won.owner.service.impl.UserNotFoundException) KeyStoreIOException(won.owner.model.KeyStoreIOException) User(won.owner.model.User) OnPasswordChangedEvent(won.owner.web.events.OnPasswordChangedEvent) IncorrectPasswordException(won.owner.service.impl.IncorrectPasswordException) ResponseBody(org.springframework.web.bind.annotation.ResponseBody) RequestMapping(org.springframework.web.bind.annotation.RequestMapping) Transactional(org.springframework.transaction.annotation.Transactional)

Example 34 with User

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;
}
Also used : User(won.owner.model.User) UserAtom(won.owner.model.UserAtom) URISyntaxException(java.net.URISyntaxException) URI(java.net.URI) UserSettingsPojo(won.owner.pojo.UserSettingsPojo) ResponseBody(org.springframework.web.bind.annotation.ResponseBody) RequestMapping(org.springframework.web.bind.annotation.RequestMapping)

Example 35 with User

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);
}
Also used : OnExportUserEvent(won.owner.web.events.OnExportUserEvent) User(won.owner.model.User) SecurityContext(org.springframework.security.core.context.SecurityContext) KeystoreEnabledUserDetails(won.owner.service.impl.KeystoreEnabledUserDetails) ResponseBody(org.springframework.web.bind.annotation.ResponseBody) RequestMapping(org.springframework.web.bind.annotation.RequestMapping)

Aggregations

User (won.owner.model.User)47 Transactional (org.springframework.transaction.annotation.Transactional)19 RequestMapping (org.springframework.web.bind.annotation.RequestMapping)18 URI (java.net.URI)17 ResponseBody (org.springframework.web.bind.annotation.ResponseBody)15 KeystorePasswordHolder (won.owner.model.KeystorePasswordHolder)9 UserAtom (won.owner.model.UserAtom)8 BCryptPasswordEncoder (org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder)7 PasswordEncoder (org.springframework.security.crypto.password.PasswordEncoder)7 Draft (won.owner.model.Draft)7 KeystoreHolder (won.owner.model.KeystoreHolder)6 URISyntaxException (java.net.URISyntaxException)5 Authentication (org.springframework.security.core.Authentication)5 NoSuchAlgorithmException (java.security.NoSuchAlgorithmException)4 Autowired (org.springframework.beans.factory.annotation.Autowired)4 CreateDraftPojo (won.owner.pojo.CreateDraftPojo)4 IncorrectPasswordException (won.owner.service.impl.IncorrectPasswordException)4 UserNotFoundException (won.owner.service.impl.UserNotFoundException)4 OnRecoveryKeyGeneratedEvent (won.owner.web.events.OnRecoveryKeyGeneratedEvent)4 ExpensiveSecureRandomString (won.protocol.util.ExpensiveSecureRandomString)4