public IdentityMgtEventListener() {

    module = IdentityMgtConfig.getInstance().getIdentityDataStore();
    String adminUserName =
        IdentityMgtServiceComponent.getRealmService()
            .getBootstrapRealmConfiguration()
            .getAdminUserName();
    try {
      IdentityMgtConfig config = IdentityMgtConfig.getInstance();

      // Get the policy registry with the loaded policies.
      policyRegistry = config.getPolicyRegistry();

      if (config.isListenerEnable()) {

        UserStoreManager userStoreMng =
            IdentityMgtServiceComponent.getRealmService().getBootstrapRealm().getUserStoreManager();
        if (!userStoreMng.isReadOnly()) {

          userStoreMng.setUserClaimValue(
              adminUserName, UserIdentityDataStore.ACCOUNT_LOCK, Boolean.toString(false), null);
        }
      }
    } catch (UserStoreException e) {
      log.error("Error while init identity listener", e);
    }
  }
  public void doRoleStuff() throws Exception {
    UserStoreManager admin = realm.getUserStoreManager();

    admin.addRole("role2", null, null);
    admin.addRole("role3", null, null);
    admin.addRole("role4", null, null);

    admin.updateRoleListOfUser("saman", null, new String[] {"role2"});
    admin.updateRoleListOfUser("saman", new String[] {"role2"}, new String[] {"role4", "role3"});

    String[] rolesOfSaman = admin.getRoleListOfUser("saman");
    assertEquals(3, rolesOfSaman.length);

    // negative
    admin.updateUserListOfRole("role2", new String[] {"saman"}, null);
    admin.updateUserListOfRole("role3", null, new String[] {"amara", "sunil"});

    // negative
    try {
      // wrong roles
      admin.updateRoleListOfUser("saman", new String[] {"x"}, new String[] {"y"});
      TestCase.assertTrue(false);
    } catch (Exception e) {
      // exptected error in negative testing

    }
    // wrong users - must pass because we don't know the external users.
    admin.updateUserListOfRole("role2", null, new String[] {"d"});
  }
  public boolean isAddUserEnabled() throws Exception {

    UserRealm userRealm = IdentityTenantUtil.getRealm(null, null);
    if (userRealm != null) {
      UserStoreManager userStoreManager = userRealm.getUserStoreManager();
      if (userStoreManager != null) {
        return !userStoreManager.isReadOnly();
      }
    }

    return false;
  }
  @Override
  public boolean doPostUpdateCredential(
      String userName, Object credential, UserStoreManager userStoreManager)
      throws UserStoreException {

    IdentityMgtConfig config = IdentityMgtConfig.getInstance();

    UserIdentityClaimsDO userIdentityDTO = module.load(userName, userStoreManager);

    if (userIdentityDTO == null) {
      userIdentityDTO = new UserIdentityClaimsDO(userName);
    }

    // Do not timestamp if OTP enabled.
    boolean userOTPEnabled = userIdentityDTO.getOneTimeLogin();

    if (config.isAuthPolicyExpirePasswordCheck()
        && !userOTPEnabled
        && (!userStoreManager.isReadOnly())) {

      Calendar currentTime = Calendar.getInstance();
      userIdentityDTO.setPasswordTimeStamp(Calendar.getInstance().getTimeInMillis());

      try {
        // Store the new timestamp after change password
        module.store(userIdentityDTO, userStoreManager);

      } catch (IdentityException e) {
        throw new UserStoreException(e.getMessage());
      }
    }

    return true;
  }
  public String getGroupingIdentifiers(String loginResponse) {

    JSONObject obj;
    String username = null;
    Boolean isSuperTenant;
    int tenantId = MultitenantConstants.SUPER_TENANT_ID;
    String tenantDomain = MultitenantConstants.SUPER_TENANT_DOMAIN_NAME;
    String claim = "http://wso2.org/claims/organization";
    String organization = null;
    try {
      obj = new JSONObject(loginResponse);
      username = (String) obj.get("user");
      isSuperTenant = (Boolean) obj.get("isSuperTenant");

      RealmService realmService = ServiceReferenceHolder.getInstance().getRealmService();

      // if the user is not in the super tenant domain then find the domain name and tenant id.
      if (!isSuperTenant) {
        tenantDomain = MultitenantUtils.getTenantDomain(username);
        tenantId =
            ServiceReferenceHolder.getInstance()
                .getRealmService()
                .getTenantManager()
                .getTenantId(tenantDomain);
      }

      UserRealm realm = (UserRealm) realmService.getTenantUserRealm(tenantId);
      UserStoreManager manager = realm.getUserStoreManager();
      organization =
          manager.getUserClaimValue(MultitenantUtils.getTenantAwareUsername(username), claim, null);
      if (organization != null) {
        organization = tenantDomain + "/" + organization.trim();
      }
    } catch (JSONException e) {
      log.error("Exception occured while trying to get group Identifier from login response");
    } catch (org.wso2.carbon.user.api.UserStoreException e) {
      log.error("Error while checking user existence for " + username);
    }

    return organization;
  }
  /** Deleting user from the identity database. What are the registry keys ? */
  @Override
  public boolean doPostDeleteUser(String userName, UserStoreManager userStoreManager)
      throws UserStoreException {

    IdentityMgtConfig config = IdentityMgtConfig.getInstance();
    if (!config.isListenerEnable()) {
      return true;
    }
    // remove from the identity store
    try {
      IdentityMgtConfig.getInstance().getIdentityDataStore().remove(userName, userStoreManager);
    } catch (IdentityException e) {
      throw new UserStoreException("Error while doPostDeleteUser", e);
    }
    // deleting registry meta-data
    UserRegistry registry = null;
    try {
      registry =
          IdentityMgtServiceComponent.getRegistryService()
              .getConfigSystemRegistry(userStoreManager.getTenantId());
      String identityKeyMgtPath =
          IdentityMgtConstants.IDENTITY_MANAGEMENT_KEYS
              + RegistryConstants.PATH_SEPARATOR
              + userStoreManager.getTenantId()
              + RegistryConstants.PATH_SEPARATOR
              + userName;

      if (registry.resourceExists(identityKeyMgtPath)) {
        registry.delete(identityKeyMgtPath);
      }
    } catch (RegistryException e) {
      log.error(
          "Error while deleting recovery data for user : "******" in tenant : "
              + userStoreManager.getTenantId(),
          e);
    }
    return true;
  }
  /**
   * This service method will return back all available password validation regular expressions
   * against the corresponding domain names.
   *
   * @return
   * @throws IdentityException
   */
  public PasswordRegExDTO[] getPasswordRegularExpressions() throws IdentityException {
    UserRealm realm = null;
    realm = IdentityTenantUtil.getRealm(null, null);
    List<PasswordRegExDTO> passwordRegExList = new ArrayList<PasswordRegExDTO>();
    PasswordRegExDTO passwordRegEx;

    try {

      UserStoreManager manager = realm.getUserStoreManager();
      String domainName;
      String regEx;

      while (manager != null) {
        domainName =
            manager
                .getRealmConfiguration()
                .getUserStoreProperty(UserCoreConstants.RealmConfig.PROPERTY_DOMAIN_NAME);
        regEx =
            manager
                .getRealmConfiguration()
                .getUserStoreProperty(UserCoreConstants.RealmConfig.PROPERTY_JS_REG_EX);
        if (regEx != null && regEx.length() > 0) {
          passwordRegEx = new PasswordRegExDTO();
          passwordRegEx.setDomainName(domainName);
          passwordRegEx.setRegEx(regEx);
          passwordRegExList.add(passwordRegEx);
        }
        manager = manager.getSecondaryUserStoreManager();
      }

    } catch (UserStoreException e) {
      log.error(e);
      throw new IdentityException(
          "Error occured while loading password validation regular expressions.");
    }

    return passwordRegExList.toArray(new PasswordRegExDTO[passwordRegExList.size()]);
  }
 private void doAddUser(
     int i,
     UserStoreManager admin,
     String[] identityRoleNames,
     String userName,
     Permission permission)
     throws IdentityException, UserStoreException {
   try {
     if (!admin.isExistingRole(identityRoleNames[i], false)) {
       permission = new Permission("/permission/admin/login", UserMgtConstants.EXECUTE_ACTION);
       admin.addRole(
           identityRoleNames[i], new String[] {userName}, new Permission[] {permission}, false);
     } else {
       // if role already exists, just add user to role
       admin.updateUserListOfRole(identityRoleNames[i], new String[] {}, new String[] {userName});
     }
   } catch (org.wso2.carbon.user.api.UserStoreException e) {
     // If something goes wrong here - then remove the already added user.
     admin.deleteUser(userName);
     throw new IdentityException(
         "Error occurred while adding user : "******". " + e.getMessage(), e);
   }
 }
  /**
   * This method checks if the user account exist or is locked. If the account is locked, the
   * authentication process will be terminated after this method returning false.
   */
  @Override
  public boolean doPreAuthenticate(
      String userName, Object credential, UserStoreManager userStoreManager)
      throws UserStoreException {

    if (log.isDebugEnabled()) {
      log.debug("Pre authenticator is called in IdentityMgtEventListener");
    }

    IdentityMgtConfig config = IdentityMgtConfig.getInstance();

    if (!config.isEnableAuthPolicy()) {
      return true;
    }

    if (config.isAuthPolicyAccountExistCheck() && !userStoreManager.isExistingUser(userName)) {
      log.warn("User name does not exist in system : " + userName);
      throw new UserStoreException(UserCoreConstants.ErrorCode.USER_DOES_NOT_EXIST);
    }

    UserIdentityClaimsDO userIdentityDTO = module.load(userName, userStoreManager);

    // if the account is locked, should not be able to log in
    if (userIdentityDTO != null && userIdentityDTO.isAccountLocked()) {

      // If unlock time is specified then unlock the account.
      if ((userIdentityDTO.getUnlockTime() != 0)
          && (System.currentTimeMillis() >= userIdentityDTO.getUnlockTime())) {

        userIdentityDTO.setAccountLock(false);
        userIdentityDTO.setUnlockTime(0);

        try {
          module.store(userIdentityDTO, userStoreManager);
        } catch (IdentityException e) {
          throw new UserStoreException("Error while saving user", e);
        }
      } else {

        log.warn(
            "User account is locked for user : "******". cannot login until the account is unlocked ");
        throw new UserStoreException(UserCoreConstants.ErrorCode.USER_IS_LOCKED);
      }
    }

    return true;
  }
  public void doAuthorizationStuff() throws Exception {
    AuthorizationManager authMan = realm.getAuthorizationManager();
    UserStoreManager usWriter = realm.getUserStoreManager();

    usWriter.addRole("rolex", new String[] {"saman", "amara"}, null);
    usWriter.addRole("roley", null, null);
    authMan.authorizeRole("rolex", "wall", "write");
    authMan.authorizeRole("roley", "table", "write");
    authMan.authorizeUser("sunil", "wall", "read");

    assertTrue(authMan.isUserAuthorized("saman", "wall", "write"));
    assertTrue(authMan.isUserAuthorized("sunil", "wall", "read"));
    assertTrue(authMan.isRoleAuthorized("roley", "table", "write"));
    assertFalse(authMan.isUserAuthorized("saman", "wall", "read"));
    assertFalse(authMan.isUserAuthorized("sunil", "wall", "write"));

    authMan.clearUserAuthorization("sunil", "wall", "read");
    authMan.clearRoleAuthorization("roley", "table", "write");
    authMan.clearResourceAuthorizations("wall");

    assertFalse(authMan.isUserAuthorized("saman", "wall", "write"));
    assertFalse(authMan.isUserAuthorized("sunil", "wall", "read"));
    assertFalse(authMan.isRoleAuthorized("roley", "table", "write"));
  }
  @Override
  protected void processAuthenticationResponse(
      HttpServletRequest request, HttpServletResponse response, AuthenticationContext context)
      throws AuthenticationFailedException {

    try {

      Map<String, String> authenticatorProperties = context.getAuthenticatorProperties();

      String clientId = authenticatorProperties.get(OIDCAuthenticatorConstants.CLIENT_ID);
      String clientSecret = authenticatorProperties.get(OIDCAuthenticatorConstants.CLIENT_SECRET);
      String tokenEndPoint = getTokenEndpoint(authenticatorProperties);

      if (tokenEndPoint == null) {
        tokenEndPoint = authenticatorProperties.get(OIDCAuthenticatorConstants.OAUTH2_TOKEN_URL);
      }

      String callbackUrl = getCallbackUrl(authenticatorProperties);

      if (StringUtils.isBlank(callbackUrl)) {
        callbackUrl = IdentityUtil.getServerURL(FrameworkConstants.COMMONAUTH, true, true);
      }

      @SuppressWarnings({"unchecked"})
      Map<String, String> paramValueMap =
          (Map<String, String>) context.getProperty("oidc:param.map");

      if (paramValueMap != null && paramValueMap.containsKey("redirect_uri")) {
        callbackUrl = paramValueMap.get("redirect_uri");
      }

      OAuthAuthzResponse authzResponse = OAuthAuthzResponse.oauthCodeAuthzResponse(request);
      String code = authzResponse.getCode();

      OAuthClientRequest accessRequest =
          getaccessRequest(tokenEndPoint, clientId, code, clientSecret, callbackUrl);

      // Create OAuth client that uses custom http client under the hood
      OAuthClient oAuthClient = new OAuthClient(new URLConnectionClient());
      OAuthClientResponse oAuthResponse = getOauthResponse(oAuthClient, accessRequest);

      // TODO : return access token and id token to framework
      String accessToken = oAuthResponse.getParam(OIDCAuthenticatorConstants.ACCESS_TOKEN);

      if (StringUtils.isBlank(accessToken)) {
        throw new AuthenticationFailedException("Access token is empty or null");
      }

      String idToken = oAuthResponse.getParam(OIDCAuthenticatorConstants.ID_TOKEN);

      if (StringUtils.isBlank(idToken) && requiredIDToken(authenticatorProperties)) {
        throw new AuthenticationFailedException("Id token is required and is missing");
      }

      context.setProperty(OIDCAuthenticatorConstants.ACCESS_TOKEN, accessToken);

      AuthenticatedUser authenticatedUserObj;
      Map<ClaimMapping, String> claims = new HashMap<>();
      Map<String, Object> jsonObject = new HashMap<>();

      if (StringUtils.isNotBlank(idToken)) {

        context.setProperty(OIDCAuthenticatorConstants.ID_TOKEN, idToken);

        String base64Body = idToken.split("\\.")[1];
        byte[] decoded = Base64.decodeBase64(base64Body.getBytes());
        String json = new String(decoded);

        jsonObject = JSONUtils.parseJSON(json);

        if (jsonObject == null) {

          if (log.isDebugEnabled()) {
            log.debug("Decoded json object is null");
          }

          throw new AuthenticationFailedException("Decoded json object is null");
        }

        if (log.isDebugEnabled()
            && IdentityUtil.isTokenLoggable(IdentityConstants.IdentityTokens.USER_ID_TOKEN)) {
          log.debug("Retrieved the User Information:" + jsonObject);
        }

        String authenticatedUser = null;
        String isSubjectInClaimsProp =
            context
                .getAuthenticatorProperties()
                .get(IdentityApplicationConstants.Authenticator.SAML2SSO.IS_USER_ID_IN_CLAIMS);

        if (StringUtils.equalsIgnoreCase("true", isSubjectInClaimsProp)) {

          authenticatedUser = getSubjectFromUserIDClaimURI(context);

          if (authenticatedUser == null && log.isDebugEnabled()) {
            log.debug(
                "Subject claim could not be found amongst subject attributes. "
                    + "Defaulting to the sub attribute in IDToken.");
          }
        }

        if (authenticatedUser == null) {

          authenticatedUser = getAuthenticateUser(context, jsonObject, oAuthResponse);

          if (authenticatedUser == null) {
            throw new AuthenticationFailedException("Cannot find federated User Identifier");
          }
        }

        String attributeSeparator = null;

        try {

          String tenantDomain = context.getTenantDomain();

          if (StringUtils.isBlank(tenantDomain)) {
            tenantDomain = MultitenantConstants.SUPER_TENANT_DOMAIN_NAME;
          }

          int tenantId =
              OpenIDConnectAuthenticatorServiceComponent.getRealmService()
                  .getTenantManager()
                  .getTenantId(tenantDomain);
          UserRealm userRealm =
              OpenIDConnectAuthenticatorServiceComponent.getRealmService()
                  .getTenantUserRealm(tenantId);

          if (userRealm != null) {
            UserStoreManager userStore = (UserStoreManager) userRealm.getUserStoreManager();
            attributeSeparator =
                userStore
                    .getRealmConfiguration()
                    .getUserStoreProperty(IdentityCoreConstants.MULTI_ATTRIBUTE_SEPARATOR);
            if (log.isDebugEnabled()) {
              log.debug(
                  "For the claim mapping: "
                      + attributeSeparator
                      + " is used as the attributeSeparator in tenant: "
                      + tenantDomain);
            }
          }

        } catch (UserStoreException e) {
          throw new AuthenticationFailedException(
              "Error while retrieving multi attribute " + "separator", e);
        }

        for (Map.Entry<String, Object> entry : jsonObject.entrySet()) {
          buildClaimMappings(claims, entry, attributeSeparator);
        }

        authenticatedUserObj =
            AuthenticatedUser.createFederateAuthenticatedUserFromSubjectIdentifier(
                authenticatedUser);
      } else {

        if (log.isDebugEnabled()) {
          log.debug("The IdToken is null");
        }

        authenticatedUserObj =
            AuthenticatedUser.createFederateAuthenticatedUserFromSubjectIdentifier(
                getAuthenticateUser(context, jsonObject, oAuthResponse));
      }

      claims.putAll(getSubjectAttributes(oAuthResponse, authenticatorProperties));
      authenticatedUserObj.setUserAttributes(claims);

      context.setSubject(authenticatedUserObj);

    } catch (OAuthProblemException e) {
      throw new AuthenticationFailedException("Authentication process failed", e);
    }
  }
  public void doAuthorizationStuff() throws Exception {
    AuthorizationManager authMan = realm.getAuthorizationManager();
    UserStoreManager usWriter = realm.getUserStoreManager();

    usWriter.addRole("rolex", new String[] {"saman", "amara"}, null);
    usWriter.addRole("roley", null, null);
    authMan.authorizeRole("rolex", "wall", "write");
    authMan.authorizeRole("roley", "table", "write");

    try {
      authMan.authorizeRole(null, "wall", "write");
      fail("Exception at authorizing a role with Null role");
    } catch (Exception e) {
      // exptected error in negative testing
      if (log.isDebugEnabled()) {
        log.debug("Expected error, hence ignored", e);
      }
    }
    try {
      authMan.authorizeRole("rollee", null, "write");
      fail("Exception at authorizing a role with Null resourceID");
    } catch (Exception e) {
      // exptected error in negative testing
    }
    try {
      authMan.authorizeRole("rollee", "wall", null);
      fail("Exception at authorizing a role with Null action");
    } catch (Exception e) {
      // exptected error in negative testing
      if (log.isDebugEnabled()) {
        log.debug("Expected error, hence ignored", e);
      }
    }
    try {
      authMan.authorizeRole("rolleex", "wall", "run");
      fail("Exception at authorizing a role with Invalid action");
    } catch (Exception e) {
      // exptected error in negative testing
      if (log.isDebugEnabled()) {
        log.debug("Expected error, hence ignored", e);
      }
    }

    // ***authorize user
    authMan.authorizeUser("sunil", "wall", "read");
    try {
      authMan.authorizeUser(null, "wall", "read");
      fail("Exception at authorizing a user with Null name");
    } catch (Exception e) {
      // exptected error in negative testing
      if (log.isDebugEnabled()) {
        log.debug("Expected error, hence ignored", e);
      }
    }
    try {
      authMan.authorizeUser("isuru", null, "read");
      fail("Exception at authorizing a user with Null resourceID");
    } catch (Exception e) {
      // exptected error in negative testing
      if (log.isDebugEnabled()) {
        log.debug("Expected error, hence ignored", e);
      }
    }
    try {
      authMan.authorizeUser("isuru", "wall", null);
      fail("Exception at authorizing a user with Null action");
    } catch (Exception e) {
      // exptected error in negative testing
      if (log.isDebugEnabled()) {
        log.debug("Expected error, hence ignored", e);
      }
    }
    try {
      authMan.authorizeUser("isuru", "wall", "run");
      fail("Exception at authorizing a user with Invalid action");
    } catch (Exception e) {
      // exptected error in negative testing
      if (log.isDebugEnabled()) {
        log.debug("Expected error, hence ignored", e);
      }
    }

    assertTrue(authMan.isUserAuthorized("saman", "wall", "write"));
    assertTrue(authMan.isUserAuthorized("sunil", "wall", "read"));
    assertTrue(authMan.isRoleAuthorized("primary/roley", "table", "write"));
    assertFalse(authMan.isRoleAuthorized("roley", "chair", "write"));
    assertFalse(authMan.isUserAuthorized("saman", "wall", "read"));
    assertFalse(authMan.isUserAuthorized("sunil", "wall", "write"));
    assertFalse(authMan.isUserAuthorized("isuru", "wall", "write"));
    try {
      boolean b = authMan.isUserAuthorized("isuru", "wall", "run");
      fail("Exception at check authorization of a user with Invalid action");
    } catch (Exception e) {
      // exptected error in negative testing
      if (log.isDebugEnabled()) {
        log.debug("Expected error, hence ignored", e);
      }
    }

    String[] AllowedRolesForResource = authMan.getAllowedRolesForResource("wall", "write");
    assertEquals(1, AllowedRolesForResource.length);
    // assertEquals(2,authMan.getAllowedUsersForResource("wall", "write").length);
    // String[] AllowedUsersForResource = authMan.getAllowedUsersForResource("wall", "read");
    // assertEquals(1, AllowedUsersForResource.length);

    authMan.clearUserAuthorization("sunil", "wall", "read");
    try {
      authMan.clearUserAuthorization("isuru", "wall", "run");
      fail("Exception at clear user authorization");
    } catch (Exception e) {
      if (log.isDebugEnabled()) {
        log.debug("Expected error, hence ignored", e);
      }
    }
    try {
      authMan.clearUserAuthorization(null, "wall", "run");
      fail("Exception at clear user authorization");
    } catch (Exception e) {
      if (log.isDebugEnabled()) {
        log.debug("Expected error, hence ignored", e);
      }
    }
    try {
      authMan.clearUserAuthorization("isuru", null, "run");
      fail("Exception at clear user authorization");
    } catch (Exception e) {
      if (log.isDebugEnabled()) {
        log.debug("Expected error, hence ignored", e);
      }
    }
    try {
      authMan.clearUserAuthorization("isuru", "wall", null);
      fail("Exception at clear user authorization");
    } catch (Exception e) {
      if (log.isDebugEnabled()) {
        log.debug("Expected error, hence ignored", e);
      }
    }

    authMan.clearRoleAuthorization("roley", "table", "write");
    try {
      authMan.clearRoleAuthorization(null, "table", "write");
      fail("Exception at clear role authorization");
    } catch (Exception e) {
      if (log.isDebugEnabled()) {
        log.debug("Expected error, hence ignored", e);
      }
    }
    try {
      authMan.clearRoleAuthorization("roleee", null, "write");
      fail("Exception at clear role authorization");
    } catch (Exception e) {
      if (log.isDebugEnabled()) {
        log.debug("Expected error, hence ignored", e);
      }
    }
    try {
      authMan.clearRoleAuthorization("roleee", "table", null);
      fail("Exception at clear role authorization");
    } catch (Exception e) {
      if (log.isDebugEnabled()) {
        log.debug("Expected error, hence ignored", e);
      }
    }

    authMan.clearResourceAuthorizations("wall");
    try {
      authMan.clearResourceAuthorizations(null);
      fail("Exception at clear Resource Authorizations");
    } catch (Exception e) {
      if (log.isDebugEnabled()) {
        log.debug("Expected error, hence ignored", e);
      }
    }

    assertFalse(authMan.isUserAuthorized("saman", "wall", "write"));
    assertFalse(authMan.isUserAuthorized("sunil", "wall", "read"));
    assertFalse(authMan.isRoleAuthorized("roley", "table", "write"));
  }
  public void doClaimStuff() throws Exception {
    UserStoreManager usWriter = realm.getUserStoreManager();
    String[] allClaims = {
      ClaimTestUtil.CLAIM_URI1, ClaimTestUtil.CLAIM_URI2, ClaimTestUtil.CLAIM_URI3
    };

    // add DEFAULT
    usWriter.setUserClaimValue("dimuthu", ClaimTestUtil.CLAIM_URI1, "claim1default", null);
    try {
      usWriter.setUserClaimValue(null, ClaimTestUtil.CLAIM_URI1, "claim1default", null);
      fail("Exception at set claim values to null users");
    } catch (Exception e) {
      // expected exception
      if (log.isDebugEnabled()) {
        log.debug("Expected error, hence ignored", e);
      }
    }
    try {
      usWriter.setUserClaimValue("isuru", null, "claim1default", null);
      fail("Exception at set claim values to null claimURI");
    } catch (Exception e) {
      // expected exception
      if (log.isDebugEnabled()) {
        log.debug("Expected error, hence ignored", e);
      }
    }
    try {
      usWriter.setUserClaimValue("isuru", ClaimTestUtil.CLAIM_URI1, null, null);
      fail("Exception at set claim values to null claimValue");
    } catch (Exception e) {
      // expected exception
      if (log.isDebugEnabled()) {
        log.debug("Expected error, hence ignored", e);
      }
    }

    String value = usWriter.getUserClaimValue("dimuthu", ClaimTestUtil.CLAIM_URI1, null);
    assertEquals("claim1default", value);
    // Non existing user
    String value1 = usWriter.getUserClaimValue("isuru", ClaimTestUtil.CLAIM_URI1, null);
    assertEquals(null, value1);
    // update default
    usWriter.setUserClaimValue("dimuthu", ClaimTestUtil.CLAIM_URI1, "dimzi lee", null);
    value = usWriter.getUserClaimValue("dimuthu", ClaimTestUtil.CLAIM_URI1, null);
    assertEquals("dimzi lee", value);

    // multiple additions
    Map<String, String> map = new HashMap<String, String>();
    map.put(ClaimTestUtil.CLAIM_URI1, "lee");
    map.put(ClaimTestUtil.CLAIM_URI3, "muthu");

    usWriter.setUserClaimValue("dimuthu", ClaimTestUtil.CLAIM_URI2, "claim2default", null);
    assertEquals(
        "dimzi lee", usWriter.getUserClaimValue("dimuthu", ClaimTestUtil.CLAIM_URI1, null));
    assertEquals(
        "claim2default", usWriter.getUserClaimValue("dimuthu", ClaimTestUtil.CLAIM_URI2, null));
    assertNull(usWriter.getUserClaimValue("dimuthu", ClaimTestUtil.CLAIM_URI3, null));

    usWriter.setUserClaimValues("dimuthu", map, ClaimTestUtil.HOME_PROFILE_NAME);
    assertEquals(
        "lee",
        usWriter.getUserClaimValue(
            "dimuthu", ClaimTestUtil.CLAIM_URI1, ClaimTestUtil.HOME_PROFILE_NAME));
    assertNull(
        usWriter.getUserClaimValue(
            "dimuthu", ClaimTestUtil.CLAIM_URI2, ClaimTestUtil.HOME_PROFILE_NAME));
    assertEquals(
        "muthu",
        usWriter.getUserClaimValue(
            "dimuthu", ClaimTestUtil.CLAIM_URI3, ClaimTestUtil.HOME_PROFILE_NAME));

    usWriter.setUserClaimValue(
        "dimuthu",
        UserCoreConstants.PROFILE_CONFIGURATION,
        ClaimTestUtil.HOME_PROFILE_NAME,
        ClaimTestUtil.HOME_PROFILE_NAME);
    Map<String, String> obtained =
        usWriter.getUserClaimValues("dimuthu", allClaims, ClaimTestUtil.HOME_PROFILE_NAME);
    // assertNull(obtained.get(ClaimTestUtil.CLAIM_URI1)); // hidden
    // assertEquals("claim2default", obtained.get(ClaimTestUtil.CLAIM_URI2)); // overridden
    assertEquals("muthu", obtained.get(ClaimTestUtil.CLAIM_URI3)); // normal

    // UPDATE
    map.put(ClaimTestUtil.CLAIM_URI3, "muthulee");
    usWriter.setUserClaimValues("dimuthu", map, ClaimTestUtil.HOME_PROFILE_NAME);
    value =
        usWriter.getUserClaimValue(
            "dimuthu", ClaimTestUtil.CLAIM_URI3, ClaimTestUtil.HOME_PROFILE_NAME);
    assertEquals("muthulee", value);

    // DELETE
    usWriter.deleteUserClaimValue("dimuthu", ClaimTestUtil.CLAIM_URI1, null);
    value = usWriter.getUserClaimValue("dimuthu", ClaimTestUtil.CLAIM_URI1, null);
    assertNull(value);
    try {
      usWriter.deleteUserClaimValue("dimuthu", null, null);
      fail("Exception at null Claim URI");
    } catch (Exception e) {
      // expected exception
      if (log.isDebugEnabled()) {
        log.debug("Expected error, hence ignored", e);
      }
    }
    try {
      usWriter.deleteUserClaimValue(null, ClaimTestUtil.CLAIM_URI1, null);
      fail("Exception at giving null user name to delete user claim values");
    } catch (Exception e) {
      // expected exception
      if (log.isDebugEnabled()) {
        log.debug("Expected error, hence ignored", e);
      }
    }

    usWriter.deleteUserClaimValues("dimuthu", allClaims, ClaimTestUtil.HOME_PROFILE_NAME);
    obtained = usWriter.getUserClaimValues("dimuthu", allClaims, ClaimTestUtil.HOME_PROFILE_NAME);
    assertNull(obtained.get(ClaimTestUtil.CLAIM_URI2)); // overridden
    assertNull(obtained.get(ClaimTestUtil.CLAIM_URI3));

    // UserStoreManager admin = realm.getUserStoreManager();
    // admin.deleteUser("dimuthu");
  }
  /**
   * This method locks the created accounts based on the account policies or based on the account
   * confirmation method being used. Two account confirmation methods are used : Temporary Password
   * and Verification Code. In the case of temporary password is used the temporary password will be
   * emailed to the user. In the case of verification code, the code will be emailed to the user.
   * The security questions filter ad doPreAddUser will be persisted in this method.
   */
  @Override
  public boolean doPostAddUser(
      String userName,
      Object credential,
      String[] roleList,
      Map<String, String> claims,
      String profile,
      UserStoreManager userStoreManager)
      throws UserStoreException {
    if (log.isDebugEnabled()) {
      log.debug("Post add user is called in IdentityMgtEventListener");
    }
    IdentityMgtConfig config = IdentityMgtConfig.getInstance();
    if (!config.isListenerEnable()) {
      return true;
    }
    // reading the value from the thread local
    UserIdentityClaimsDO userIdentityClaimsDO =
        (UserIdentityClaimsDO) threadLocalProperties.get().get(USER_IDENTITY_DO);

    if (config.isEnableUserAccountVerification()) {

      // empty password account creation
      if (threadLocalProperties.get().containsKey(EMPTY_PASSWORD_USED)) {
        // store identity data
        userIdentityClaimsDO.setAccountLock(false).setPasswordTimeStamp(System.currentTimeMillis());
        try {
          module.store(userIdentityClaimsDO, userStoreManager);
        } catch (IdentityException e) {
          throw new UserStoreException("Error while doPostAddUser", e);
        }
        // store identity metadata
        UserRecoveryDataDO metadataDO = new UserRecoveryDataDO();
        metadataDO
            .setUserName(userName)
            .setTenantId(userStoreManager.getTenantId())
            .setCode((String) credential);
        //				try {
        //	                UserIdentityManagementUtil.storeUserIdentityMetadata(metadataDO);
        //                } catch (IdentityException e) {
        //                	throw new UserStoreException("Error while doPreAddUser", e);
        //                }

        // set recovery data
        RecoveryProcessor processor = new RecoveryProcessor();
        VerificationBean verificationBean = new VerificationBean();

        try {
          verificationBean =
              processor.updateConfirmationCode(1, userName, userStoreManager.getTenantId());
        } catch (IdentityException e) {
          // TODO Auto-generated catch block
          e.printStackTrace();
        }

        // preparing a bean to send the email
        UserIdentityMgtBean bean = new UserIdentityMgtBean();
        bean.setUserId(userName)
            .setConfirmationCode(verificationBean.getKey())
            .setRecoveryType(IdentityMgtConstants.Notification.TEMPORARY_PASSWORD)
            .setEmail(claims.get(config.getAccountRecoveryClaim()));

        UserRecoveryDTO recoveryDto = new UserRecoveryDTO(userName);
        recoveryDto.setNotification(IdentityMgtConstants.Notification.ASK_PASSWORD);
        recoveryDto.setNotificationType("EMAIL");
        recoveryDto.setTenantId(userStoreManager.getTenantId());
        recoveryDto.setConfirmationCode(verificationBean.getKey());

        NotificationDataDTO notificationDto = null;

        try {
          notificationDto = processor.recoverWithNotification(recoveryDto);
        } catch (IdentityException e) {
          if (log.isDebugEnabled()) {
            log.debug(e.getMessage());
          }
          throw new UserStoreException("Error while sending notification. " + e.getMessage());
        }

        if (notificationDto != null && notificationDto.isNotificationSent()) {
          return true;
        } else {
          return false;
        }

        // sending email
        //				UserIdentityManagementUtil.notifyViaEmail(bean);

      } else {
        // none-empty passwords. lock account and persist
        /*				This scenario needs to be validated.
        * 				userIdentityClaimsDO.setAccountLock(true)
        			                    .setPasswordTimeStamp(System.currentTimeMillis());
        			try {
        				UserIdentityManagementUtil.storeUserIdentityClaims(userIdentityClaimsDO, userStoreManager);
        			} catch (IdentityException e) {
        				throw new UserStoreException("Error while doPostAddUser", e);
        			}
        			String confirmationCode = UserIdentityManagementUtil.generateRandomConfirmationCode();
        			// store identity metadata
        			UserRecoveryDataDO metadataDO = new UserRecoveryDataDO();
        			metadataDO.setUserName(userName).setTenantId(userStoreManager.getTenantId())
        			          .setCode(confirmationCode);
        			try {
                        UserIdentityManagementUtil.storeUserIdentityMetadata(metadataDO);
                       } catch (IdentityException e) {
                       	throw new UserStoreException("Error while doPostAddUser", e);
                       }
        			// sending a mail with the confirmation code
        			UserIdentityMgtBean bean = new UserIdentityMgtBean();
        			bean.setUserId(userName)
        			    .setRecoveryType(IdentityMgtConstants.Notification.ACCOUNT_CONFORM)
        			    .setConfirmationCode(confirmationCode);
        			UserIdentityManagementUtil.notifyViaEmail(bean);
        			return true; */
      }
    }
    // No account recoveries are defined, no email will be sent.
    if (config.isAuthPolicyAccountLockOnCreation()) {
      // accounts are locked. Admin should unlock
      userIdentityClaimsDO.setAccountLock(true);
      userIdentityClaimsDO.setPasswordTimeStamp(System.currentTimeMillis());
      try {
        config.getIdentityDataStore().store(userIdentityClaimsDO, userStoreManager);
      } catch (IdentityException e) {
        throw new UserStoreException("Error while doPostAddUser", e);
      }
    }
    return true;
  }
  /**
   * This method locks the accounts after a configured number of authentication failure attempts.
   * And unlocks accounts based on successful authentications.
   */
  @Override
  public boolean doPostAuthenticate(
      String userName, boolean authenticated, UserStoreManager userStoreManager)
      throws UserStoreException {

    if (log.isDebugEnabled()) {
      log.debug("Post authenticator is called in IdentityMgtEventListener");
    }

    IdentityMgtConfig config = IdentityMgtConfig.getInstance();

    if (!config.isEnableAuthPolicy()) {
      return authenticated;
    }

    UserIdentityClaimsDO userIdentityDTO = module.load(userName, userStoreManager);
    if (userIdentityDTO == null) {
      userIdentityDTO = new UserIdentityClaimsDO(userName);
    }

    boolean userOTPEnabled = userIdentityDTO.getOneTimeLogin();

    // One time password check
    if (authenticated
        && config.isAuthPolicyOneTimePasswordCheck()
        && (!userStoreManager.isReadOnly())) {

      // reset password of the user and notify user of the new password
      if (userOTPEnabled) {

        String password = UserIdentityManagementUtil.generateTemporaryPassword().toString();
        userStoreManager.updateCredentialByAdmin(userName, password);

        // Get email user claim value
        String email =
            userStoreManager.getUserClaimValue(
                userName, UserCoreConstants.ClaimTypeURIs.EMAIL_ADDRESS, null);

        if (email == null) {
          throw new UserStoreException("No user email provided for user " + userName);
        }

        List<NotificationSendingModule> notificationModules =
            config.getNotificationSendingModules();

        if (notificationModules != null) {

          NotificationDataDTO notificationData = new NotificationDataDTO();

          NotificationData emailNotificationData = new NotificationData();
          String emailTemplate = null;
          int tenantId = userStoreManager.getTenantId();
          String firstName = null;
          try {
            firstName =
                Utils.getClaimFromUserStoreManager(
                    userName, tenantId, "http://wso2.org/claims/givenname");
          } catch (IdentityException e2) {
            throw new UserStoreException("Could not load user given name");
          }
          emailNotificationData.setTagData("first-name", firstName);
          emailNotificationData.setTagData("user-name", userName);
          emailNotificationData.setTagData("otp-password", password);

          emailNotificationData.setSendTo(email);

          Config emailConfig = null;
          ConfigBuilder configBuilder = ConfigBuilder.getInstance();
          try {
            emailConfig =
                configBuilder.loadConfiguration(ConfigType.EMAIL, StorageType.REGISTRY, tenantId);
          } catch (Exception e1) {
            throw new UserStoreException("Could not load the email template configuration");
          }

          emailTemplate = emailConfig.getProperty("otp");

          Notification emailNotification = null;
          try {
            emailNotification =
                NotificationBuilder.createNotification(
                    "EMAIL", emailTemplate, emailNotificationData);
          } catch (Exception e) {
            throw new UserStoreException("Could not create the email notification");
          }
          NotificationSender sender = new NotificationSender();

          for (NotificationSendingModule notificationSendingModule : notificationModules) {

            if (IdentityMgtConfig.getInstance().isNotificationInternallyManaged()) {
              notificationSendingModule.setNotificationData(notificationData);
              notificationSendingModule.setNotification(emailNotification);
              sender.sendNotification(notificationSendingModule);
              notificationData.setNotificationSent(true);
            }
          }

        } else {
          throw new UserStoreException("No notification modules configured");
        }
      }
    }

    // Password expire check. Not for OTP enabled users.
    if (authenticated
        && config.isAuthPolicyExpirePasswordCheck()
        && !userOTPEnabled
        && (!userStoreManager.isReadOnly())) {
      // TODO - password expire impl
      // Refactor adduser and change password api to stamp the time
      // Check user's expire time in the claim
      // if expired redirect to change password
      // else pass through
      /*
      long timestamp = userIdentityDTO.getPasswordTimeStamp();
      // Only allow behavior to users with this claim. Intent bypass for admin?
      if (timestamp > 0) {
      	Calendar passwordExpireTime = Calendar.getInstance();
      	passwordExpireTime.setTimeInMillis(timestamp);

      	int expireDuration = config.getAuthPolicyPasswordExpireTime();
      	if (expireDuration > 0) {

      		passwordExpireTime.add(Calendar.DATE, expireDuration);

      		Calendar currentTime = Calendar.getInstance();

      		if (currentTime.compareTo(passwordExpireTime) > 0) {
      			// password expired
      			// set flag to redirect
      			log.error("Password is expired ...........");
      			// throw new UserStoreException("Password is expired");
      		}

      	}
      }
      */
    }

    if (!authenticated && config.isAuthPolicyAccountLockOnFailure()) {
      userIdentityDTO.setFailAttempts();
      // reading the max allowed #of failure attempts

      if (userIdentityDTO.getFailAttempts() >= config.getAuthPolicyMaxLoginAttempts()) {
        if (log.isDebugEnabled()) {
          log.debug(
              "User, "
                  + userName
                  + " has exceed the max failed login attempts. "
                  + "User account would be locked");
        }
        userIdentityDTO.setAccountLock(true);
        // lock time from the config
        int lockTime = IdentityMgtConfig.getInstance().getAuthPolicyLockingTime();
        if (lockTime != 0) {
          userIdentityDTO.setUnlockTime(System.currentTimeMillis() + (lockTime * 60 * 1000));
        }
      }

      try {
        module.store(userIdentityDTO, userStoreManager);
      } catch (IdentityException e) {
        throw new UserStoreException("Error while doPostAuthenticate", e);
      }

    } else {
      // if the account was locked due to account verification process,
      // the unlock the account and reset the number of failedAttempts
      if (userIdentityDTO.isAccountLocked() || userIdentityDTO.getFailAttempts() > 0) {
        userIdentityDTO.setAccountLock(false);
        userIdentityDTO.setFailAttempts(0);
        userIdentityDTO.setUnlockTime(0);
        try {
          module.store(userIdentityDTO, userStoreManager);
        } catch (IdentityException e) {
          throw new UserStoreException("Error while doPostAuthenticate", e);
        }
      }
    }

    return true;
  }
  private void addUser(
      String userName,
      String password,
      Map<String, String> claimList,
      String profileName,
      UserRealm realm)
      throws IdentityException {
    UserStoreManager admin = null;
    Permission permission = null;
    try {
      // get config from tenant registry
      TenantRegistrationConfig tenantConfig =
          getTenantSignUpConfig(realm.getUserStoreManager().getTenantId());
      // set tenant config specific sign up domain
      if (tenantConfig != null && !"".equals(tenantConfig.getSignUpDomain())) {
        int index = userName.indexOf(UserCoreConstants.DOMAIN_SEPARATOR);
        if (index > 0) {
          userName =
              tenantConfig.getSignUpDomain().toUpperCase()
                  + UserCoreConstants.DOMAIN_SEPARATOR
                  + userName.substring(index + 1);
        } else {
          userName =
              tenantConfig.getSignUpDomain().toUpperCase()
                  + UserCoreConstants.DOMAIN_SEPARATOR
                  + userName;
        }
      }

      // add user to the relevant user store

      admin = realm.getUserStoreManager();
      if (!isUserNameWithAllowedDomainName(userName, realm)) {
        throw new IdentityException("Domain does not permit self registration");
      }
      // add user
      admin.addUser(userName, password, null, claimList, profileName);

      // after adding the user, assign specif roles
      List<String> roleNamesArr = getRoleName(userName, tenantConfig);
      if (claimList.get(SelfRegistrationConstants.SIGN_UP_ROLE_CLAIM_URI) != null) {
        // check is a user role is specified as a claim by the client, if so add it to the roles
        // list
        if (tenantConfig != null) {
          roleNamesArr.add(
              tenantConfig.getSignUpDomain().toUpperCase()
                  + UserCoreConstants.DOMAIN_SEPARATOR
                  + claimList.get(SelfRegistrationConstants.SIGN_UP_ROLE_CLAIM_URI));
        } else {
          roleNamesArr.add(
              UserCoreConstants.INTERNAL_DOMAIN
                  + UserCoreConstants.DOMAIN_SEPARATOR
                  + claimList.get(SelfRegistrationConstants.SIGN_UP_ROLE_CLAIM_URI));
        }
      }
      String[] identityRoleNames = roleNamesArr.toArray(new String[roleNamesArr.size()]);

      for (int i = 0; i < identityRoleNames.length; i++) {
        // if this is the first time a user signs up, needs to create role
        doAddUser(i, admin, identityRoleNames, userName, permission);
      }

    } catch (UserStoreException e) {
      throw new IdentityException(
          "Error occurred while adding user : "******". " + e.getMessage(), e);
    }
  }
  public void doUserRoleStuff() throws Exception {
    UserStoreManager admin = realm.getUserStoreManager();

    InputStream inStream =
        this.getClass()
            .getClassLoader()
            .getResource(JDBCRealmTest.JDBC_TEST_USERMGT_XML)
            .openStream();
    RealmConfigXMLProcessor realmConfigProcessor = new RealmConfigXMLProcessor();
    RealmConfiguration realmConfig = realmConfigProcessor.buildRealmConfiguration(inStream);

    admin.addRole("role2", null, null);
    admin.addRole("role3", null, null);
    admin.addRole("role4", null, null);
    assertEquals(6, admin.getRoleNames().length); // admin,everyone,role1,role2,role3,role4

    // Test delete role method
    assertTrue(admin.isExistingRole("role3"));
    admin.deleteRole("role3");
    admin.deleteRole("role4");
    assertFalse(admin.isExistingRole("role3"));
    admin.addRole("role3", null, null);
    admin.addRole("role4", null, null);

    // add users
    admin.addUser("saman", "pass1", null, null, null, false);
    admin.addUser("amara", "pass2", null, null, null, false);
    admin.addUser("sunil", "pass3", null, null, null, false);

    // update the ROLE list of USERS
    admin.updateRoleListOfUser("saman", null, new String[] {"role2"});
    admin.updateRoleListOfUser("saman", new String[] {"role2"}, new String[] {"role4", "role3"});
    try {
      admin.updateRoleListOfUser(null, null, new String[] {"role2"});
      fail("Exceptions at missing user name");
    } catch (Exception ex) {
      // expected user
      if (log.isDebugEnabled()) {
        log.debug("Expected error, hence ignored", ex);
      }
    }

    // Renaming Role
    admin.updateRoleName("role4", "role5");

    String[] rolesOfSaman = admin.getRoleListOfUser("saman");
    assertEquals(3, rolesOfSaman.length);

    String[] rolesOfisuru = admin.getRoleListOfUser("isuru");
    assertEquals(0, rolesOfisuru.length);

    admin.updateUserListOfRole("role2", new String[] {"saman"}, null);
    admin.updateUserListOfRole("role3", null, new String[] {"amara", "sunil"});

    String[] userOfRole5 = admin.getUserListOfRole("role5");
    assertEquals(1, userOfRole5.length);

    String[] userOfRole4 = admin.getUserListOfRole("role4");
    assertEquals(0, userOfRole4.length);

    try {
      admin.updateUserListOfRole("rolexx", null, new String[] {"amara", "sunil"});
      TestCase.assertTrue(false);
    } catch (Exception e) {
      // exptected error in negative testing
      if (log.isDebugEnabled()) {
        log.debug("Expected error, hence ignored", e);
      }
    }
    try {
      admin.updateUserListOfRole("role2", null, new String[] {"d"});
      TestCase.assertTrue(false);
    } catch (Exception e) {
      // exptected error in negative testing
      if (log.isDebugEnabled()) {
        log.debug("Expected error, hence ignored", e);
      }
    }

    try {
      admin.updateRoleListOfUser("saman", new String[] {"x"}, new String[] {"y"});
      TestCase.assertTrue(false);
    } catch (Exception e) {
      // exptected error in negative testing
      if (log.isDebugEnabled()) {
        log.debug("Expected error, hence ignored", e);
      }
    }

    try {
      admin.updateUserListOfRole(
          realmConfig.getAdminRoleName(), null, new String[] {realmConfig.getAdminUserName()});
      TestCase.assertTrue(false);
    } catch (Exception e) {
      // exptected error in negative testing
      if (log.isDebugEnabled()) {
        log.debug("Expected error, hence ignored", e);
      }
    }

    try {
      admin.updateRoleListOfUser(
          realmConfig.getAdminUserName(), new String[] {realmConfig.getAdminRoleName()}, null);
      TestCase.assertTrue(false);
    } catch (Exception e) {
      // exptected error in negative testing
      if (log.isDebugEnabled()) {
        log.debug("Expected error, hence ignored", e);
      }
    }

    try {
      admin.updateUserListOfRole(realmConfig.getEveryOneRoleName(), new String[] {"saman"}, null);
      TestCase.assertTrue(false);
    } catch (Exception e) {
      // exptected error in negative testing
      if (log.isDebugEnabled()) {
        log.debug("Expected error, hence ignored", e);
      }
    }

    try {
      admin.updateRoleListOfUser("sunil", new String[] {realmConfig.getEveryOneRoleName()}, null);
      TestCase.assertTrue(false);
    } catch (Exception e) {
      // exptected error in negative testing
      if (log.isDebugEnabled()) {
        log.debug("Expected error, hence ignored", e);
      }
    }

    try {
      admin.updateRoleName("role2", "role5");
      TestCase.assertTrue(false);
    } catch (Exception e) {
      // exptected error in negative testing
      if (log.isDebugEnabled()) {
        log.debug("Expected error, hence ignored", e);
      }
    }
  }
  /**
   * Returns an array of claims of the authorized user. This is for the OpenIDConnect user-end-point
   * implementation.
   *
   * <p>TODO : 1. Should return the userinfo response instead. TODO : 2. Should create another
   * service API for userinfo endpoint
   *
   * @param accessTokenIdentifier
   * @return
   * @throws IdentityException
   */
  public Claim[] getUserClaims(String accessTokenIdentifier) {

    OAuth2TokenValidationRequestDTO reqDTO = new OAuth2TokenValidationRequestDTO();
    OAuth2TokenValidationRequestDTO.OAuth2AccessToken accessToken = reqDTO.new OAuth2AccessToken();
    accessToken.setTokenType("bearer");
    accessToken.setIdentifier(accessTokenIdentifier);
    reqDTO.setAccessToken(accessToken);
    OAuth2TokenValidationResponseDTO respDTO = new OAuth2TokenValidationService().validate(reqDTO);

    String username = respDTO.getAuthorizedUser();
    if (username == null) { // invalid token
      log.debug(respDTO.getErrorMsg());
      return new Claim[0];
    }
    String[] scope = respDTO.getScope();
    boolean isOICScope = false;
    for (String curScope : scope) {
      if ("openid".equals(curScope)) {
        isOICScope = true;
      }
    }
    if (!isOICScope) {
      log.error("AccessToken does not have the openid scope");
      return new Claim[0];
    }

    // TODO : this code is ugly
    String profileName = "default"; // TODO : configurable
    String tenantDomain = MultitenantUtils.getTenantDomain(username);
    String tenatUser = MultitenantUtils.getTenantAwareUsername(username);

    List<Claim> claimsList = new ArrayList<Claim>();

    // MUST claim
    // http://openid.net/specs/openid-connect-basic-1_0-22.html#id_res
    Claim subClaim = new Claim();
    subClaim.setClaimUri("sub");
    subClaim.setValue(username);
    claimsList.add(subClaim);

    try {
      UserStoreManager userStore =
          IdentityTenantUtil.getRealm(tenantDomain, tenatUser).getUserStoreManager();
      // externel configured claims
      String[] claims = OAuthServerConfiguration.getInstance().getSupportedClaims();
      if (claims != null) {
        Map<String, String> extClaimsMap =
            userStore.getUserClaimValues(username, claims, profileName);
        for (Map.Entry<String, String> entry : extClaimsMap.entrySet()) {
          Claim curClaim = new Claim();
          curClaim.setClaimUri(entry.getKey());
          curClaim.setValue(entry.getValue());
          claimsList.add(curClaim);
        }
      }
      // default claims
      String[] defaultClaims = new String[3];
      defaultClaims[0] = "http://wso2.org/claims/emailaddress";
      defaultClaims[1] = "http://wso2.org/claims/givenname";
      defaultClaims[2] = "http://wso2.org/claims/lastname";
      String emailAddress = null;
      String firstName = null;
      String lastName = null;
      Map<String, String> defClaimsMap =
          userStore.getUserClaimValues(username, defaultClaims, profileName);
      if (defClaimsMap.get(defaultClaims[0]) != null) {
        emailAddress = defClaimsMap.get(defaultClaims[0]);
        Claim email = new Claim();
        email.setClaimUri("email");
        email.setValue(emailAddress);
        claimsList.add(email);
        Claim prefName = new Claim();
        prefName.setClaimUri("preferred_username");
        prefName.setValue(emailAddress.split("@")[0]);
        claimsList.add(prefName);
      }
      if (defClaimsMap.get(defaultClaims[1]) != null) {
        firstName = defClaimsMap.get(defaultClaims[1]);
        Claim givenName = new Claim();
        givenName.setClaimUri("given_name");
        givenName.setValue(firstName);
        claimsList.add(givenName);
      }
      if (defClaimsMap.get(defaultClaims[2]) != null) {
        lastName = defClaimsMap.get(defaultClaims[2]);
        Claim familyName = new Claim();
        familyName.setClaimUri("family_name");
        familyName.setValue(lastName);
        claimsList.add(familyName);
      }
      if (firstName != null && lastName != null) {
        Claim name = new Claim();
        name.setClaimUri("name");
        name.setValue(firstName + " " + lastName);
        claimsList.add(name);
      }

    } catch (Exception e) {
      log.error("Error while reading user claims ", e);
    }

    Claim[] allClaims = new Claim[claimsList.size()];
    for (int i = 0; i < claimsList.size(); i++) {
      allClaims[i] = claimsList.get(i);
    }
    return allClaims;
  }
  public void doUserStuff() throws Exception {

    UserStoreManager admin = realm.getUserStoreManager();

    Map<String, String> userProps = new HashMap<String, String>();
    userProps.put(ClaimTestUtil.CLAIM_URI1, "1claim1Value");
    userProps.put(ClaimTestUtil.CLAIM_URI2, "2claim2Value");

    Permission[] permisions = new Permission[2];
    permisions[0] = new Permission("high security", "read");
    permisions[1] = new Permission("low security", "write");

    // add USER
    admin.addUser("dimuthu", "credential", null, null, null, false);
    try {
      admin.addUser(null, null, null, null, null, false);
      TestCase.assertTrue(false);
    } catch (Exception ex) {
      // expected error
      if (log.isDebugEnabled()) {
        log.debug("Expected error, hence ignored", ex);
      }
    }
    try {
      admin.addUser("dimuthu", null, null, null, null, false);
      TestCase.assertTrue(false);
    } catch (Exception ex) {
      // expected error
      if (log.isDebugEnabled()) {
        log.debug("Expected error, hence ignored", ex);
      }
    }
    try {
      admin.addUser(null, "credential", null, null, null, false);
      TestCase.assertTrue(false);
    } catch (Exception ex) {
      // expected error
      if (log.isDebugEnabled()) {
        log.debug("Expected error, hence ignored", ex);
      }
    }
    try {
      admin.addUser(" ", "credential", null, null, null, false);
      TestCase.assertTrue(false);
    } catch (Exception ex) {
      // expected error
      if (log.isDebugEnabled()) {
        log.debug("Expected error, hence ignored", ex);
      }
    }
    try {
      admin.addUser("dimuthu", "credential", null, null, null, false);
      fail("Exception at adding the same user again");
    } catch (Exception ex) {
      // expected error
      if (log.isDebugEnabled()) {
        log.debug("Expected error, hence ignored", ex);
      }
    }

    // add ROLE
    admin.addRole("role1", new String[] {"dimuthu"}, permisions); // dimuthu added to the role
    try {
      admin.addRole(null, null, null);
      fail("Exception at defining a roll with No information");
    } catch (Exception ex) {
      // expected error
      if (log.isDebugEnabled()) {
        log.debug("Expected error, hence ignored", ex);
      }
    }
    try {
      admin.addRole(null, new String[] {"dimuthu"}, permisions);
      fail("Exception at adding user to a non specified role");
    } catch (Exception ex) {
      // expected error
      if (log.isDebugEnabled()) {
        log.debug("Expected error, hence ignored", ex);
      }
    }
    try {
      admin.addRole("role1", new String[] {"isuru"}, permisions);
      fail("Exception at adding a non existing user to the role");
    } catch (Exception ex) {
      // expected error
      if (log.isDebugEnabled()) {
        log.debug("Expected error, hence ignored", ex);
      }
    }

    // add USER to a ROLE
    admin.addUser("vajira", "credential", new String[] {"role1"}, userProps, null, false);
    try {
      admin.addUser("Bence", "credential", new String[] {"rolexxx"}, userProps, null, false);
      fail("Exception at adding user to a Non-existing role");
    } catch (Exception ex) {
      // expected user
      if (log.isDebugEnabled()) {
        log.debug("Expected error, hence ignored", ex);
      }
    }
    try {
      admin.addUser(null, "credential", new String[] {"role1"}, userProps, null, false);
      fail("Exception at adding user to a role with no user name");
    } catch (Exception ex) {
      // expected user
      if (log.isDebugEnabled()) {
        log.debug("Expected error, hence ignored", ex);
      }
    }
    try {
      admin.addUser("vajira", "credential", new String[] {"role1"}, userProps, null, false);
      fail("Exception at adding same user to the same roll");
    } catch (Exception ex) {
      // expected user
      if (log.isDebugEnabled()) {
        log.debug("Expected error, hence ignored", ex);
      }
    }

    // Authenticate USER
    assertTrue(admin.authenticate("dimuthu", "credential"));
    assertFalse(admin.authenticate(null, "credential"));
    assertFalse(admin.authenticate("dimuthu", null));

    // update by ADMIN
    admin.updateCredentialByAdmin("dimuthu", "topsecret");
    assertTrue(admin.authenticate("dimuthu", "topsecret"));

    // isExistingUser
    assertTrue(admin.isExistingUser("dimuthu"));
    assertFalse(admin.isExistingUser("muhaha"));

    // update by USER
    admin.updateCredential("dimuthu", "password", "topsecret");
    // assertTrue(admin.authenticate("dimuthu", "password")); //TO DO
    assertFalse(admin.authenticate("dimuthu", "credential"));
    try {
      admin.updateCredential("dimuthu", "password", "xxx");
      TestCase.assertTrue(false);
    } catch (Exception ex) {
      // expected exception
      if (log.isDebugEnabled()) {
        log.debug("Expected error, hence ignored", ex);
      }
    }

    String[] names = admin.listUsers("*", 100);
    assertEquals(3, names.length);

    String[] names1 = admin.listUsers("*", 0);
    assertEquals(0, names1.length);

    String[] names2 = admin.listUsers("*", 2);
    assertEquals(2, names2.length);

    String[] names3 = admin.listUsers("di?uthu", 100);
    assertEquals(1, names3.length);

    String[] names4 = admin.listUsers("is?ru", 100);
    assertEquals(0, names4.length);

    String[] roleNames = admin.getRoleNames();
    assertEquals(3, roleNames.length);

    // delete
    admin.deleteUser("vajira");
    assertFalse(admin.isExistingUser("vajira"));
    assertFalse(admin.authenticate("vajira", "credential"));

    // delete ROLE
    admin.addUser("vajira", "credential", new String[] {"role1"}, userProps, null, false);
    assertTrue(admin.isExistingUser("vajira"));
    admin.deleteRole("role1");

    // add role
    admin.addRole("role1", new String[] {"dimuthu"}, permisions);
  }
  /**
   * This method used to confirm the self registered user account and unlock it.
   *
   * @param username
   * @param code
   * @param captcha
   * @param tenantDomain
   * @return
   * @throws IdentityMgtServiceException
   */
  public VerificationBean confirmUserSelfRegistration(
      String username, String code, CaptchaInfoBean captcha, String tenantDomain)
      throws IdentityMgtServiceException {

    VerificationBean bean = new VerificationBean();

    if (log.isDebugEnabled()) {
      log.debug("User registration verification request received with username :"******" Error while validating captcha for user : "******"Trying to confirm users in unauthorized tenant space";
        log.error(msg);
      }
      if (tenantDomain == null || tenantDomain.isEmpty()) {
        tenantDomain = loggedInTenant;
      }
    }

    UserDTO userDTO = null;
    try {
      userDTO = Utils.processUserId(username + "@" + tenantDomain);

    } catch (IdentityException e) {
      bean =
          handleError(
              VerificationBean.ERROR_CODE_INVALID_USER
                  + " Error verifying user account for user : "******"Error retrieving the user store manager for the tenant : " + tenantDomain, e);
        return bean;
      }

      try {
        bean = processor.verifyConfirmationCode(1, username, code);
        if (bean.isVerified()) {
          UserIdentityManagementUtil.unlockUserAccount(username, userStoreManager);
          bean.setVerified(true);

        } else {
          bean.setVerified(false);
          bean.setKey("");
          log.error("User verification failed against the given confirmation code");
        }
      } catch (IdentityException e) {
        bean = handleError("Error while validating confirmation code for user : " + username, e);
        return bean;
      }
    } finally {
      if (IdentityMgtConfig.getInstance().isSaasEnabled()) {
        PrivilegedCarbonContext.endTenantFlow();
      }
    }
    return bean;
  }
  /**
   * This method is used to register an user in the system. The account will be locked if the
   * Authentication.Policy.Account.Lock.On.Creation is set to true. Else user will be able to login
   * after registration.
   *
   * @param userName
   * @param password
   * @param claims
   * @param profileName
   * @param tenantDomain
   * @return
   * @throws IdentityMgtServiceException
   */
  public VerificationBean registerUser(
      String userName,
      String password,
      UserIdentityClaimDTO[] claims,
      String profileName,
      String tenantDomain)
      throws IdentityMgtServiceException {

    VerificationBean vBean = new VerificationBean();

    org.wso2.carbon.user.core.UserStoreManager userStoreManager = null;
    Permission permission = null;

    if (!IdentityMgtConfig.getInstance().isSaasEnabled()) {
      String loggedInTenant =
          PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantDomain();
      if (tenantDomain != null && !tenantDomain.isEmpty() && !loggedInTenant.equals(tenantDomain)) {
        String msg = "Trying to create users in unauthorized tenant space";
        log.error(msg);
        throw new IdentityMgtServiceException(msg);
      }
      if (tenantDomain == null || tenantDomain.isEmpty()) {
        tenantDomain = loggedInTenant;
      }
    }

    RealmService realmService = IdentityMgtServiceComponent.getRealmService();
    int tenantId;

    try {

      tenantId = Utils.getTenantId(tenantDomain);
      if (realmService.getTenantUserRealm(tenantId) != null) {
        userStoreManager =
            (org.wso2.carbon.user.core.UserStoreManager)
                realmService.getTenantUserRealm(tenantId).getUserStoreManager();
      }

    } catch (Exception e) {
      vBean =
          handleError(
              VerificationBean.ERROR_CODE_UNEXPECTED
                  + " Error retrieving the user store manager for the tenant",
              e);
      return vBean;
    }

    try {

      if (userStoreManager == null) {
        vBean = new VerificationBean();
        vBean.setVerified(false);
        vBean.setError(
            VerificationBean.ERROR_CODE_UNEXPECTED
                + " Error retrieving the user store manager for the tenant");
        return vBean;
      }

      Map<String, String> claimsMap = new HashMap<String, String>();
      for (UserIdentityClaimDTO userIdentityClaimDTO : claims) {
        claimsMap.put(userIdentityClaimDTO.getClaimUri(), userIdentityClaimDTO.getClaimValue());
      }

      userStoreManager.addUser(userName, password, null, claimsMap, profileName);

      String identityRoleName =
          UserCoreConstants.INTERNAL_DOMAIN
              + CarbonConstants.DOMAIN_SEPARATOR
              + IdentityConstants.IDENTITY_DEFAULT_ROLE;

      if (!userStoreManager.isExistingRole(identityRoleName, false)) {
        permission = new Permission("/permission/admin/login", UserMgtConstants.EXECUTE_ACTION);
        userStoreManager.addRole(
            identityRoleName, new String[] {userName}, new Permission[] {permission}, false);
      } else {
        userStoreManager.updateUserListOfRole(
            identityRoleName, new String[] {}, new String[] {userName});
      }

      IdentityEventListener identityEventListener =
          IdentityUtil.readEventListenerProperty(
              UserOperationEventListener.class.getName(), IdentityMgtEventListener.class.getName());

      boolean isListenerEnable = true;

      if (identityEventListener != null) {
        if (StringUtils.isNotBlank(identityEventListener.getEnable())) {
          isListenerEnable = Boolean.parseBoolean(identityEventListener.getEnable());
        }
      }

      IdentityMgtConfig config = IdentityMgtConfig.getInstance();

      if (isListenerEnable && config.isAuthPolicyAccountLockOnCreation()) {
        UserDTO userDTO = new UserDTO(userName);
        userDTO.setTenantId(tenantId);

        UserRecoveryDTO dto = new UserRecoveryDTO(userDTO);
        dto.setNotification(IdentityMgtConstants.Notification.ACCOUNT_CONFORM);
        dto.setNotificationType("EMAIL");

        RecoveryProcessor processor = IdentityMgtServiceComponent.getRecoveryProcessor();
        vBean = processor.updateConfirmationCode(1, userName, tenantId);

        dto.setConfirmationCode(vBean.getKey());
        NotificationDataDTO notificationDto = processor.notifyWithEmail(dto);
        vBean.setVerified(notificationDto.isNotificationSent());

        //				Send email data only if not internally managed.
        if (!(IdentityMgtConfig.getInstance().isNotificationInternallyManaged())) {
          vBean.setNotificationData(notificationDto);
        }

      } else {
        vBean.setVerified(true);
      }
    } catch (UserStoreException | IdentityException e) {
      UserIdentityManagementUtil.getCustomErrorMessages(e, userName);
      // Rollback if user exists
      try {
        if (userStoreManager.isExistingUser(userName)) {
          userStoreManager.deleteUser(userName);
        }
      } catch (org.wso2.carbon.user.core.UserStoreException e1) {
        UserIdentityManagementUtil.getCustomErrorMessages(e1, userName);
      }

      return vBean;
    }

    return vBean;
  }