class AnonymousUserGetAPITokenByOneTimeTokenService {

    @UseCaseUserClicksLinkToGetNewAPIToken(@Step(number = 2, next = { 3,
            4 }, name = "Validation and update", description = "When its a valid one time token a new api token is generated and persisted hashed to user. The token itself is returned. When not valid an emtpy string is the result ..."))
    public String createNewAPITokenForUserByOneTimeToken(String oneTimeToken) {
        assertion.isValidOneTimeToken(oneTimeToken);

        Optional<User> found = sechubUserRepository.findByOneTimeToken(oneTimeToken);
        if (!found.isPresent()) {
            securityLogService.log(SecurityLogType.POTENTIAL_INTRUSION,
                    "Did not found a user having one time token :{}. Maybe an attack, so will just return info string.",
                    logSanitizer.sanitize(oneTimeToken, 50));
            return ANSWER_WHEN_TOKEN_CANNOT_BE_CHANGED;
        }

        User user = found.get();
        /* check not outdated onetime token */
        if (user.isOneTimeTokenOutDated(oneTimeOutDatedMillis)) {
            securityLogService.log(SecurityLogType.POTENTIAL_USERDATA_LEAK,
                    "Did found a user having one time token :{}, but token is outdated! Maybe an attack (or user just waited too long...). Will just return info string.",
                    logSanitizer.sanitize(oneTimeToken, 50));
            return ANSWER_WHEN_TOKEN_CANNOT_BE_CHANGED;
        }

        user.oneTimeToken = null;
        user.oneTimeTokenDate = null;
        String rawToken = apiTokenGenerator.generateNewAPIToken();
        user.hashedApiToken = passwordEncoder.encode(rawToken);

        sechubUserRepository.save(user);

        LOG.info("Updated API token for user {}", user.getName());

        sendUserAPITokenChanged(user);

        /* we return the raw token to user - but do NOT save it but hashed variant */
        return rawToken;
    }

}