/**
   * POST api/authentication?token=xxx
   *
   * <p>This action is called after signing the nonce on the client-side with the user's
   * certificate. We'll once again use the Authentication class to do the actual work.
   */
  @RequestMapping(
      value = "/api/authentication",
      method = {RequestMethod.POST})
  public AuthenticationPostResponse post(
      @RequestParam(value = "token", required = true) String token) throws RestException {

    // Instantiate the Authentication class
    Authentication auth = new Authentication(Util.getRestPkiClient());

    // Call the completeWithWebPki() method, which finalizes the authentication process. It receives
    // as input
    // only the token that was yielded previously (which we sent to the page and the page sent us
    // back on the URL).
    // The call yields a ValidationResults which denotes whether the authentication was successful
    // or not.
    ValidationResults vr = auth.completeWithWebPki(token);

    AuthenticationPostResponse response = new AuthenticationPostResponse();

    // Check the authentication result
    if (!vr.isValid()) {
      // If the authentication failed, inform the page
      response.setSuccess(false);
      response.setMessage("Authentication failed");
      response.setValidationResults(vr.toString());
      return response;
    }

    // At this point, you have assurance that the certificate is valid according to the
    // SecurityContext passed on the first step (see method get()) and that the user is indeed the
    // certificate's
    // subject. Now, you'd typically query your database for a user that matches one of the
    // certificate's fields, such as cert.getEmailAddress() or cert.getPkiBrazil().getCpf() (the
    // actual field
    // to be used as key depends on your application's business logic) and set the user
    // as authenticated with whatever web security framework your application uses.
    // For demonstration purposes, we'll just return a success and put on the message something
    // to show that we have access to the certificate's fields.

    PKCertificate userCert = auth.getPKCertificate();
    StringBuilder message = new StringBuilder();
    message.append("Welcome, " + userCert.getSubjectName().getCommonName() + "!");
    if (!StringUtils.isEmpty(userCert.getEmailAddress())) {
      message.append(" Your email address is " + userCert.getEmailAddress());
    }
    if (!StringUtils.isEmpty(userCert.getPkiBrazil().getCpf())) {
      message.append(" and your CPF is " + userCert.getPkiBrazil().getCpf());
    }

    // Return success to the page
    response.setSuccess(true);
    response.setMessage(message.toString());
    return response;
  }
  @RequestMapping(value = "/user", method = RequestMethod.PUT)
  @Transactional
  public ResponseEntity<Client> doIt(@RequestBody Client client, Authentication authentication) {

    List<String> errors = DomainValidator.checkForErrors(client);
    if (!errors.isEmpty()) {
      return new ResponseEntity<Client>(new Client(client, errors), HttpStatus.BAD_REQUEST);
    }
    HttpStatus status = null;

    List<GrantedAuthority> authorities = new ArrayList<>();
    authorities.add(new SimpleGrantedAuthority("USER"));

    if (ApplicationSecurity.isRoot(authentication)) {
      if (ApplicationSecurity.isRoot(client.getUsername())) {
        return new ResponseEntity<Client>(
            new Client(client, cannotChangeRootPassword), HttpStatus.BAD_REQUEST);
      }
      status = upsert(client, authorities);

    } else if (StringUtils.equals(client.getUsername(), authentication.getName())) {
      if (!userDetailsManager.userExists(client.getUsername())) {
        return new ResponseEntity<Client>(new Client(client, mustBeRoot), HttpStatus.BAD_REQUEST);
      }
      User user = new User(client.getUsername(), client.getPassword(), authorities);
      userDetailsManager.updateUser(user);
      status = HttpStatus.OK;

    } else {
      return new ResponseEntity<Client>(HttpStatus.FORBIDDEN);
    }

    return new ResponseEntity<Client>(new Client(client), status);
  }
  /**
   * GET api/authentication
   *
   * <p>This action is called once the user clicks the "Sign In" button.
   */
  @RequestMapping(
      value = "/api/authentication",
      method = {RequestMethod.GET})
  public String get() throws RestException {

    // Instantiate the Authentication class
    Authentication auth = new Authentication(Util.getRestPkiClient());

    // Call the Authentication startWithWebPki() method, which initiates the authentication. This
    // yields the token,
    // a 22-character case-sensitive URL-safe string, which we'll send to the page in order to pass
    // on the
    // signWithRestPki method of the Web PKI component.
    String token = auth.startWithWebPki(Util.getSecurityContext());

    // Note: By changing the SecurityContext above you can accept only certificates from a certain
    // PKI,
    // for instance, ICP-Brasil (SecurityContext.pkiBrazil).

    // Return the token to the page
    return token;
  }