/**
   * Ensure that an activation email is sent out to the user
   *
   * @throws IOException on read error of email
   * @throws MessagingException on read error of email
   */
  @Test
  public void sendActivationEmail() throws IOException, MessagingException {
    // make a new user
    UserClient user = userClientService.addActivationKey(makeNewRandomUserClient(null));

    setEmailMailServerUser(user.getEmail());

    // send the activation email
    String activationUrl = "http://whatever/" + user.getActivationKey();
    mailService.sendActivationEmail(user, activationUrl, null);

    // make sure the message was received
    MimeMessage[] messages = getEmailsFromServer();

    int current = messages.length - 1 == -1 ? 0 : messages.length - 1;

    assertThat(
        "user's login should be present",
        messages[current].getContent().toString().indexOf(user.getLogin()),
        is(not(-1)));

    assertThat(
        "title of email comes from template",
        messages[current].getHeader("Subject", ":"),
        is("New User Account Confirmation"));

    assertThat(
        "activation url is present",
        messages[current].getContent().toString().indexOf(activationUrl),
        is(not(-1)));
  }
  /** Ensure we can send password change confirmation emails */
  @Test
  public void changePasswordConfirmation() {
    String email = "*****@*****.**";
    setEmailMailServerUser(email);
    int countOfMessages = getEmailsFromServer().length;
    mailService.sendPasswordChangeConfirmationEmail(null, null);
    assertThat("email shouldn't send", getEmailsFromServer().length, is(countOfMessages));

    UserClient userClient = new UserClient();
    userClient.setEmail(email);
    mailService.sendPasswordChangeConfirmationEmail(userClient, null);
    assertThat("everything ok, send", getEmailsFromServer().length, is(countOfMessages + 1));
  }
  /** Ensure we can send invalid account password reset emails */
  @Test
  public void invalidAccountPasswordReset() {
    String email = "*****@*****.**";
    setEmailMailServerUser(email);
    int countOfMessages = getEmailsFromServer().length;
    mailService.sendInvalidAccountPasswordResetEmail(null, null);
    assertThat("no email shouldn't send", getEmailsFromServer().length, is(countOfMessages));

    UserClient userClient = new UserClient();
    userClient.setEmail(email);
    mailService.sendInvalidAccountPasswordResetEmail(userClient, null);
    assertThat("everything ok, send", getEmailsFromServer().length, is(countOfMessages + 1));
  }
  /** Ensure we can send email verification emails */
  @Test
  public void emailVerification() {
    String email = "*****@*****.**";
    setEmailMailServerUser(email);
    int countOfMessages = getEmailsFromServer().length;
    mailService.sendValidationEmail(
        null, "http://aUrl", "http://aTrackingUrl/" + SIGNATURE_VARIABLE_NAME);
    assertThat("email shouldn't send", getEmailsFromServer().length, is(countOfMessages));

    UserClient userClient = new UserClient();
    userClient.setEmail(email);
    mailService.sendValidationEmail(userClient, "http://aUrl", null);
    assertThat("everything ok, send", getEmailsFromServer().length, is(countOfMessages + 1));
  }
  /** Try to send activation email in various 'bad' scenarios */
  @Test
  public void badActivation() {
    UserClient userClient = new UserClient();

    int countOfMessages = getEmailsFromServer().length;

    mailService.sendActivationEmail(null, null, null);
    assertThat(
        "no client shouldn't change messages", getEmailsFromServer().length, is(countOfMessages));

    mailService.sendActivationEmail(userClient, "http://aUrl", null);
    assertThat("no email shouldn't send", getEmailsFromServer().length, is(countOfMessages));

    userClient.setEmail("*****@*****.**");
    mailService.sendActivationEmail(userClient, "http://aUrl", null);
    assertThat("everything ok, send", getEmailsFromServer().length, is(countOfMessages + 1));
  }
  /**
   * Ensure that a password reset email is sent out to the user
   *
   * @throws IOException on read error of email
   * @throws MessagingException on read error of email
   */
  @Test
  public void sendPasswordResetEmail() throws IOException, MessagingException {
    // make a new user
    UserClient user = makeNewRandomUserClient(null);

    setEmailMailServerUser(user.getEmail());

    // make sure the message was received
    MimeMessage[] messages = getEmailsFromServer();

    int before = messages.length - 1 == -1 ? 0 : messages.length - 1;

    // send the reset email
    String resetUrl = "http://whatever/";
    mailService.sendPasswordResetEmail(user, resetUrl, null);

    // make sure the message was received
    messages = getEmailsFromServer();

    int current = messages.length - 1 == -1 ? 0 : messages.length - 1;

    assertThat("a mail was sent", before + 1, is(current));

    assertThat(
        "user's first name should be present",
        messages[current]
            .getContent()
            .toString()
            .indexOf(StringUtils.capitalize(user.getFirstName())),
        is(not(-1)));

    assertThat(
        "title of email comes from template",
        messages[current].getHeader("Subject", ":"),
        is("Password Reset"));

    assertThat(
        "reset url is present",
        messages[current].getContent().toString().indexOf(resetUrl),
        is(not(-1)));
  }
 @Override
 public UserClientResource toResource(UserClient entity) {
   UserClientResource ret = new UserClientResource();
   ret.add(linkTo(methodOn(UserClientsResource.class).get(entity.getId())).withSelfRel());
   ret.add(
       linkTo(
               methodOn(UserClientUserClientRolesResource.class)
                   .getUserClientUserClientRoles(entity.getId(), null, null))
           .withRel("userClientRoles"));
   ret.add(UserClientUserClientTeamRoleResourceAssembler.createPossibleTeamsLink(entity));
   ret.add(
       UserClientUserClientTeamRoleResourceAssembler.createGetUserClientUserClientTeamRolesLink(
           entity));
   ret.add(
       linkTo(methodOn(UserClientPasswordResource.class).set(entity.getId(), null))
           .withRel("changePassword"));
   ret.add(
       linkTo(methodOn(UserClientsResource.class).activate(entity.getId())).withRel("activate"));
   ret.add(
       linkTo(methodOn(UserClientsResource.class).resetPassword(entity.getId()))
           .withRel("resetPassword"));
   ret.add(
       linkTo(methodOn(CasesResource.class).userClientReferenceData(entity.getId()))
           .withRel("createCase"));
   ret.setEntity(entity);
   return ret;
 }
 public static Link updateUserClientLink(UserClient user) {
   Link verifyPasswordLink =
       linkTo(
               methodOn(UserClientsResource.class)
                   .updateUserClientEmail(user.getId(), null, null, null, null))
           .withRel("userClientEmail");
   UriTemplate verifyPasswordUriTemplate =
       new UriTemplate(verifyPasswordLink.getHref())
           .with(
               new TemplateVariables(
                   new TemplateVariable("password", TemplateVariable.VariableType.REQUEST_PARAM)));
   return new Link(verifyPasswordUriTemplate, verifyPasswordLink.getRel());
 }
  @Override
  public UserClientResource toResource(UserClient user) {
    if (user == null) {
      return null;
    }
    Set<String> perms = new HashSet<>();
    for (GrantedAuthority grantedAuthority : user.getAuthorities()) {
      // strip off the client and team specifics on the authorities
      Matcher matcher = specializedPermissions.matcher(grantedAuthority.getAuthority());
      if (matcher.matches()) {
        perms.add(matcher.replaceAll("$1"));
      } else {
        perms.add(grantedAuthority.getAuthority());
      }
    }

    if (user.isSuperUser()) {
      // give the super user all team permissions (not necessary but nice for the UI)
      user.setTeamRoles(superUserTeamRoleGenerator.allPermissionsOnAllTeams(user.getClient()));
    }

    // add the teams to which this user has access
    Set<TeamResource> teams = new HashSet<>();
    for (UserClientUserClientTeamRole userClientUserClientTeamRole : user.getTeamRoles()) {
      teams.add(roleTeamResourceResourceAssembler.toResource(userClientUserClientTeamRole));
    }

    boolean interruptFlow = false;

    if (user.getNotNowExpirationTime() != null) {
      LocalDateTime dateTime = LocalDateTime.now(DateTimeZone.UTC);
      interruptFlow = dateTime.isBefore(user.getNotNowExpirationTime());
    }

    UserClientResource ret =
        new UserClientResource(
            user.getId(),
            user.getVersion(),
            user.getLogin(),
            user.getFirstName(),
            user.getLastName(),
            user.getEmail(),
            user.isActive(),
            user.isAccountNonExpired(),
            user.isAccountNonLocked(),
            user.isCredentialsNonExpired(),
            user.isEmailValidated(),
            user.isSecretQuestionCreated(),
            clientResourceAssembler.toResource(user.getClient()),
            new ArrayList<>(perms),
            user.isImpersonated(),
            user.getNotNowExpirationTime(),
            user.getPasswordExpireationDateTime(),
            user.getPasswordSavedDateTime(),
            interruptFlow);

    ret.setSecurityQuestionsNotRequiredForReset(user.isSecurityQuestionsNotRequiredForReset());

    ret.add(linkTo(methodOn(UserClientsResource.class).authenticated()).withRel("authenticated"));

    if (!CollectionUtils.isEmpty(teams)) {
      ret.setTeams(teams);
    }

    if (!user.isImpersonated()) {
      // non-impersonation users only
      ret.add(linkTo(methodOn(UserClientsResource.class).getById(user.getId())).withSelfRel());
      ret.add(updateUserClientLink(user));
      ret.add(createVerifyPasswordLink(user));

      Link link =
          linkTo(
                  methodOn(UserClientSecretQuestionResponsesResource.class)
                      .secretQuestionResponses(user.getId(), null, null, null))
              .withRel("secretQuestionResponses");
      ret.add(new Link(createUriTemplate("password", link), link.getRel()));

      Link updateUserClientSecretQuestion =
          linkTo(methodOn(UserClientsResource.class).updateUserClient(user.getId(), null))
              .withRel("updateUserClientSecretQuestionFlag");
      ret.add(
          new Link(
              createUriTemplate("secretQuestionsCreated", updateUserClientSecretQuestion),
              updateUserClientSecretQuestion.getRel()));

      ret.add(
          linkTo(
                  methodOn(UserClientSecretQuestionResponsesResource.class)
                      .secretQuestionAsteriskResponse(user.getId(), null, null))
              .withRel("secretQuestionAsteriskResponses"));
      ret.add(
          linkTo(methodOn(UserClientsResource.class).sendValidationEmail(user.getId()))
              .withRel("sendValidationEmail"));
      ret.add(
          linkTo(methodOn(UserClientsPasswordResource.class).changePassword(null, null, null))
              .withRel("changePassword"));
      ret.add(linkTo(methodOn(UserClientsResource.class).notNow(user.getId())).withRel("notNow"));
    } else {
      // impersonation users
      ret.add(
          new Link(
              UriComponentsBuilder.fromHttpUrl(
                      linkTo(methodOn(UserClientsResource.class).getById(1l))
                          .withSelfRel()
                          .getHref())
                  .replacePath(adminEntryPoint)
                  .build(false)
                  .toUriString(),
              "adminApp"));
    }

    return ret;
  }