@DataBoundConstructor
  public WwpassSecurityRealm(String certFile, String keyFile, String name, boolean allowsSignup) {

    this.disableSignup = !allowsSignup;

    this.name = name;

    if (certFile != null && !certFile.isEmpty() && keyFile != null && !keyFile.isEmpty()) {
      this.certFile = certFile;
      this.keyFile = keyFile;
    } else {
      if (System.getProperty("os.name").startsWith("Windows")) {
        this.certFile = DEFAULT_CERT_FILE_WINDOWS;
        this.keyFile = DEFAULT_KEY_FILE_WINDOWS;
      } else if (System.getProperty("os.name").startsWith("Linux")) {
        this.certFile = DEFAULT_CERT_FILE_LINUX;
        this.keyFile = DEFAULT_KEY_FILE_LINUX;
      } else {
        LOGGER.severe(Messages.WwpassSession_UnsupportedOsError());
        throw new Failure(Messages.WwpassSession_AuthError());
      }
    }

    if (!hasSomeUser()) {
      // if Hudson is newly set up with the security realm and there's no user account created yet,
      // insert a filter that asks the user to create one
      try {
        PluginServletFilter.addFilter(CREATE_FIRST_USER_FILTER);
      } catch (ServletException e) {
        throw new AssertionError(e); // never happen because our Filter.init is no-op
      }
    }
  }
  /** The login process starts from here. */
  public HttpResponse doCommenceLogin(
      StaplerRequest req,
      StaplerResponse rsp,
      @QueryParameter String from,
      @QueryParameter String ticket)
      throws ServletException, IOException {

    // TODO write login method
    String puid = authenticateInWwpass(ticket, certFile, keyFile);

    WwpassIdentity u;
    try {
      u = loadUserByUsername(puid);
    } catch (UsernameNotFoundException e) {
      if (allowsSignup()) {
        req.setAttribute("errorMessage", Messages.WwpassSecurityRealm_NoSuchUserAllowsSignup());
      } else {
        req.setAttribute("errorMessage", Messages.WwpassSecurityRealm_NoSuchUserDisableSignup());
      }
      req.getView(this, "login.jelly").forward(req, rsp);
      throw e;
    }
    if (!u.isAccountNonLocked() || !u.isEnabled()) {
      // throw new LockedException("Account is not activated for " + puid);
      throw new Failure(Messages.WwpassSecurityRealm_AccountNotActivated());
    }

    Authentication a = new WwpassAuthenticationToken(u.getNickname());
    a = this.getSecurityComponents().manager.authenticate(a);
    SecurityContextHolder.getContext().setAuthentication(a);

    return new HttpRedirect(Jenkins.getInstance().getRootUrl());
  }
    public FormValidation doServerCheck(
        @QueryParameter final String server,
        @QueryParameter final String managerDN,
        @QueryParameter final String managerPassword) {

      if (!Jenkins.getInstance().hasPermission(Jenkins.ADMINISTER)) return FormValidation.ok();

      try {
        Hashtable<String, String> props = new Hashtable<String, String>();
        if (managerDN != null && managerDN.trim().length() > 0 && !"undefined".equals(managerDN)) {
          props.put(Context.SECURITY_PRINCIPAL, managerDN);
        }
        if (managerPassword != null
            && managerPassword.trim().length() > 0
            && !"undefined".equals(managerPassword)) {
          props.put(Context.SECURITY_CREDENTIALS, managerPassword);
        }

        props.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
        props.put(Context.PROVIDER_URL, toProviderUrl(server, ""));

        DirContext ctx = new InitialDirContext(props);
        ctx.getAttributes("");
        return FormValidation.ok(); // connected
      } catch (NamingException e) {
        // trouble-shoot
        Matcher m =
            Pattern.compile(
                    "(ldaps?://)?([^:]+)(?:\\:(\\d+))?(\\s+(ldaps?://)?([^:]+)(?:\\:(\\d+))?)*")
                .matcher(server.trim());
        if (!m.matches())
          return FormValidation.error(
              hudson.security.Messages.LDAPSecurityRealm_SyntaxOfServerField());

        try {
          InetAddress adrs = InetAddress.getByName(m.group(2));
          int port = m.group(1) != null ? 636 : 389;
          if (m.group(3) != null) port = Integer.parseInt(m.group(3));
          Socket s = new Socket(adrs, port);
          s.close();
        } catch (UnknownHostException x) {
          return FormValidation.error(
              hudson.security.Messages.LDAPSecurityRealm_UnknownHost(x.getMessage()));
        } catch (IOException x) {
          return FormValidation.error(
              x,
              hudson.security.Messages.LDAPSecurityRealm_UnableToConnect(server, x.getMessage()));
        }

        // otherwise we don't know what caused it, so fall back to the general error report
        // getMessage() alone doesn't offer enough
        return FormValidation.error(
            e, hudson.security.Messages.LDAPSecurityRealm_UnableToConnect(server, e));
      } catch (NumberFormatException x) {
        // The getLdapCtxInstance method throws this if it fails to parse the port number
        return FormValidation.error(hudson.security.Messages.LDAPSecurityRealm_InvalidPortNumber());
      }
    }
  /**
   * @return <code>null</code> if failed. The browser is already redirected to retry by the time
   *     this method returns. a valid {@link User} object if the user creation was successful.
   */
  private User createAccount(StaplerRequest req, StaplerResponse rsp, String formView)
      throws ServletException, IOException {

    SignupInfo si = new SignupInfo(req);

    String puid = authenticateInWwpass(si.ticket, certFile, keyFile);

    try {
      if (loadUserByUsername(puid) != null) {
        si.errorMessages.add(Messages.WwpassSecurityRealm_PuidIsAlreadyTaken());
      }
    } catch (UsernameNotFoundException e) {

    }

    if (si.nickname == null || si.nickname.length() == 0)
      si.errorMessages.add(Messages.WwpassSecurityRealm_NicknameIsRequired());
    else {
      User user = User.get(si.nickname, false);
      if (null != user)
        if (user.getProperty(WwpassIdentity.class) != null)
          si.errorMessages.add(Messages.WwpassSecurityRealm_NicknameIsAlreadyTaken());
    }

    if (si.fullname == null || si.fullname.length() == 0)
      si.errorMessages.add(Messages.WwpassSecurityRealm_FullnameIsRequired());
    else {
      User user = User.get(si.fullname, false);
      if (null != user)
        if (user.getProperty(WwpassIdentity.class) != null)
          si.errorMessages.add(Messages.WwpassSecurityRealm_FullnameIsAlreadyTaken());
    }

    if (si.email == null || !si.email.contains("@"))
      si.errorMessages.add(Messages.WwpassSecurityRealm_InvalidEmailAddress());

    if (!si.errorMessages.isEmpty()) {
      // failed. ask the user to try again.
      req.setAttribute("data", si);
      req.getView(this, formView).forward(req, rsp);
      return null;
    }

    // register the user
    WwpassIdentity id = new WwpassIdentity(puid);
    id.populate(si);

    User user = createAccount(id);
    id.updateProfile(user);

    user.save();
    return user;
  }