use of org.wso2.carbon.identity.mgt.mail.Notification in project identity-governance by wso2-extensions.
the class UserSelfRegistrationManager method registerUser.
public NotificationResponseBean registerUser(User user, String password, Claim[] claims, Property[] properties) throws IdentityRecoveryException {
publishEvent(user, claims, properties, IdentityEventConstants.Event.PRE_SELF_SIGNUP_REGISTER);
String consent = getPropertyValue(properties, IdentityRecoveryConstants.Consent.CONSENT);
String tenantDomain = user.getTenantDomain();
if (StringUtils.isEmpty(tenantDomain)) {
tenantDomain = MultitenantConstants.SUPER_TENANT_DOMAIN_NAME;
}
// Callback URL validation
String callbackURL = null;
try {
callbackURL = Utils.getCallbackURLFromRegistration(properties);
if (StringUtils.isNotBlank(callbackURL) && !Utils.validateCallbackURL(callbackURL, tenantDomain, IdentityRecoveryConstants.ConnectorConfig.SELF_REGISTRATION_CALLBACK_REGEX)) {
throw Utils.handleServerException(IdentityRecoveryConstants.ErrorMessages.ERROR_CODE_CALLBACK_URL_NOT_VALID, callbackURL);
}
} catch (MalformedURLException | UnsupportedEncodingException | IdentityEventException e) {
throw Utils.handleServerException(IdentityRecoveryConstants.ErrorMessages.ERROR_CODE_CALLBACK_URL_NOT_VALID, callbackURL);
}
if (StringUtils.isBlank(user.getTenantDomain())) {
user.setTenantDomain(MultitenantConstants.SUPER_TENANT_DOMAIN_NAME);
log.info("registerUser :Tenant domain is not in the request. set to default for user : " + user.getUserName());
}
if (StringUtils.isBlank(user.getUserStoreDomain())) {
user.setUserStoreDomain(IdentityUtil.getPrimaryDomainName());
log.info("registerUser :User store domain is not in the request. set to default for user : " + user.getUserName());
}
boolean enable = Boolean.parseBoolean(Utils.getSignUpConfigs(IdentityRecoveryConstants.ConnectorConfig.ENABLE_SELF_SIGNUP, user.getTenantDomain()));
if (!enable) {
throw Utils.handleClientException(IdentityRecoveryConstants.ErrorMessages.ERROR_CODE_DISABLE_SELF_SIGN_UP, user.getUserName());
}
NotificationResponseBean notificationResponseBean;
try {
RealmService realmService = IdentityRecoveryServiceDataHolder.getInstance().getRealmService();
UserStoreManager userStoreManager;
try {
userStoreManager = realmService.getTenantUserRealm(IdentityTenantUtil.getTenantId(user.getTenantDomain())).getUserStoreManager();
} catch (UserStoreException e) {
throw Utils.handleServerException(IdentityRecoveryConstants.ErrorMessages.ERROR_CODE_UNEXPECTED, user.getUserName(), e);
}
PrivilegedCarbonContext.startTenantFlow();
PrivilegedCarbonContext carbonContext = PrivilegedCarbonContext.getThreadLocalCarbonContext();
carbonContext.setTenantId(IdentityTenantUtil.getTenantId(user.getTenantDomain()));
carbonContext.setTenantDomain(user.getTenantDomain());
Map<String, String> claimsMap = new HashMap<>();
for (Claim claim : claims) {
claimsMap.put(claim.getClaimUri(), claim.getValue());
}
// Set arbitrary properties to use in UserSelfRegistrationHandler
Utils.setArbitraryProperties(properties);
validateAndFilterFromReceipt(consent, claimsMap);
// User preferred notification channel.
String preferredChannel;
try {
// TODO It is required to add this role before tenant creation. And also, this role should not not be able remove.
if (!userStoreManager.isExistingRole(IdentityRecoveryConstants.SELF_SIGNUP_ROLE)) {
Permission permission = new Permission("/permission/admin/login", IdentityRecoveryConstants.EXECUTE_ACTION);
userStoreManager.addRole(IdentityRecoveryConstants.SELF_SIGNUP_ROLE, null, new Permission[] { permission });
}
String[] userRoles = new String[] { IdentityRecoveryConstants.SELF_SIGNUP_ROLE };
try {
NotificationChannelManager notificationChannelManager = Utils.getNotificationChannelManager();
preferredChannel = notificationChannelManager.resolveCommunicationChannel(user.getUserName(), user.getTenantDomain(), user.getUserStoreDomain(), claimsMap);
} catch (NotificationChannelManagerException e) {
throw mapNotificationChannelManagerException(e, user);
}
// resolved channel is not empty.
if (StringUtils.isEmpty(claimsMap.get(IdentityRecoveryConstants.PREFERRED_CHANNEL_CLAIM)) && StringUtils.isNotEmpty(preferredChannel)) {
claimsMap.put(IdentityRecoveryConstants.PREFERRED_CHANNEL_CLAIM, preferredChannel);
}
userStoreManager.addUser(IdentityUtil.addDomainToName(user.getUserName(), user.getUserStoreDomain()), password, userRoles, claimsMap, null);
} catch (UserStoreException e) {
Throwable cause = e;
while (cause != null) {
if (cause instanceof PolicyViolationException) {
throw IdentityException.error(IdentityRecoveryClientException.class, IdentityRecoveryConstants.ErrorMessages.ERROR_CODE_POLICY_VIOLATION.getCode(), cause.getMessage(), e);
}
cause = cause.getCause();
}
Utils.checkPasswordPatternViolation(e, user);
return handleClientException(user, e);
}
addUserConsent(consent, tenantDomain);
// Build the notification response.
notificationResponseBean = buildNotificationResponseBean(user, preferredChannel, claimsMap);
} finally {
Utils.clearArbitraryProperties();
PrivilegedCarbonContext.endTenantFlow();
}
publishEvent(user, claims, properties, IdentityEventConstants.Event.POST_SELF_SIGNUP_REGISTER);
return notificationResponseBean;
}
use of org.wso2.carbon.identity.mgt.mail.Notification in project identity-governance by wso2-extensions.
the class UserSelfRegistrationManager method introspectSelfRegistrationCode.
/**
* Introspects self registration confirmation code details without invalidating it.
* Does not triggering notification events or update user claims.
*
* @param skipExpiredCodeValidation Skip confirmation code validation against expiration.
* @param code Confirmation code.
* @return UserRecoveryData Data associated with the provided code, including related user and scenarios.
* @throws IdentityRecoveryException Error validating the confirmation code
*/
private UserRecoveryData introspectSelfRegistrationCode(String code, boolean skipExpiredCodeValidation) throws IdentityRecoveryException {
UserRecoveryDataStore userRecoveryDataStore = JDBCRecoveryDataStore.getInstance();
// If the code is validated, the load method will return data. Otherwise method will throw exceptions.
UserRecoveryData recoveryData;
if (!skipExpiredCodeValidation) {
recoveryData = userRecoveryDataStore.load(code);
} else {
recoveryData = userRecoveryDataStore.load(code, skipExpiredCodeValidation);
}
User user = recoveryData.getUser();
// Validate context tenant domain name with user tenant domain.
validateContextTenantDomainWithUserTenantDomain(user);
return recoveryData;
}
use of org.wso2.carbon.identity.mgt.mail.Notification in project identity-governance by wso2-extensions.
the class UserSelfRegistrationManager method isPreferredChannelVerified.
/**
* Checks whether the notification channel is already verified for the user.
*
* @param username Username
* @param notificationChannel Notification channel
* @param claimsMap Properties related to the event
* @return True if the channel is already verified
* @throws IdentityRecoveryClientException Error while getting the notification channel
*/
private boolean isPreferredChannelVerified(String username, String notificationChannel, Map<String, String> claimsMap) throws IdentityRecoveryClientException {
boolean isEnableAccountLockForVerifiedPreferredChannelEnabled = Boolean.parseBoolean(IdentityUtil.getProperty(IdentityRecoveryConstants.ConnectorConfig.ENABLE_ACCOUNT_LOCK_FOR_VERIFIED_PREFERRED_CHANNEL));
if (!isEnableAccountLockForVerifiedPreferredChannelEnabled) {
NotificationChannels channel = getNotificationChannel(username, notificationChannel);
// Get the matching claim uri for the channel.
String verifiedClaimUri = channel.getVerifiedClaimUrl();
// Get the verified status for given channel.
String verifiedStatus = claimsMap.get(verifiedClaimUri);
return StringUtils.isNotEmpty(verifiedStatus) && Boolean.parseBoolean(verifiedStatus);
}
return false;
}
use of org.wso2.carbon.identity.mgt.mail.Notification in project identity-governance by wso2-extensions.
the class UserSelfRegistrationManager method buildLiteNotificationResponseBean.
/**
* Build the notification response bean.
*
* @param user User
* @param preferredChannel User preferred channel
* @param claimsMap Claim map of the user
* @return NotificationResponseBean object
* @throws IdentityRecoveryException Error while building the response.
*/
private NotificationResponseBean buildLiteNotificationResponseBean(User user, String preferredChannel, Map<String, String> claimsMap) throws IdentityRecoveryException {
boolean isAccountLockOnCreation = Boolean.parseBoolean(Utils.getSignUpConfigs(IdentityRecoveryConstants.ConnectorConfig.LITE_ACCOUNT_LOCK_ON_CREATION, user.getTenantDomain()));
boolean isNotificationInternallyManage = Boolean.parseBoolean(Utils.getSignUpConfigs(IdentityRecoveryConstants.ConnectorConfig.LITE_SIGN_UP_NOTIFICATION_INTERNALLY_MANAGE, user.getTenantDomain()));
// Check whether the preferred channel is already verified. In this case no need to send confirmation
// mails.
boolean preferredChannelVerified = isPreferredChannelVerified(user.getUserName(), preferredChannel, claimsMap);
NotificationResponseBean notificationResponseBean = new NotificationResponseBean(user);
// since, the notification channel is already verified.
if (preferredChannelVerified) {
notificationResponseBean.setCode(IdentityRecoveryConstants.SuccessEvents.SUCCESS_STATUS_CODE_SUCCESSFUL_USER_CREATION_WITH_VERIFIED_CHANNEL.getCode());
notificationResponseBean.setMessage(IdentityRecoveryConstants.SuccessEvents.SUCCESS_STATUS_CODE_SUCCESSFUL_USER_CREATION_WITH_VERIFIED_CHANNEL.getMessage());
} else if (isNotificationInternallyManage && isAccountLockOnCreation) {
// When the channel is not verified, notifications are internally managed and account is locked
// on creating, API should ask the user to verify the user account and and notification channel.
notificationResponseBean.setCode(IdentityRecoveryConstants.SuccessEvents.SUCCESS_STATUS_CODE_SUCCESSFUL_USER_CREATION_INTERNAL_VERIFICATION.getCode());
notificationResponseBean.setMessage(IdentityRecoveryConstants.SuccessEvents.SUCCESS_STATUS_CODE_SUCCESSFUL_USER_CREATION_INTERNAL_VERIFICATION.getMessage());
notificationResponseBean.setNotificationChannel(preferredChannel);
} else if (!isAccountLockOnCreation) {
// When the preferred channel is not verified and account is not locked on user creation, response needs to
// convey that no verification is needed.
// In this scenario notification managed mechanism will not effect.
notificationResponseBean.setCode(IdentityRecoveryConstants.SuccessEvents.SUCCESS_STATUS_CODE_SUCCESSFUL_USER_CREATION_UNLOCKED_WITH_NO_VERIFICATION.getCode());
notificationResponseBean.setMessage(IdentityRecoveryConstants.SuccessEvents.SUCCESS_STATUS_CODE_SUCCESSFUL_USER_CREATION_UNLOCKED_WITH_NO_VERIFICATION.getMessage());
} else {
// When the notification is externally managed and the account is locked on user creation.
UserRecoveryDataStore userRecoveryDataStore = JDBCRecoveryDataStore.getInstance();
userRecoveryDataStore.invalidate(user);
String secretKey = UUIDGenerator.generateUUID();
UserRecoveryData recoveryDataDO = new UserRecoveryData(user, secretKey, RecoveryScenarios.LITE_SIGN_UP, RecoverySteps.CONFIRM_LITE_SIGN_UP);
recoveryDataDO.setRemainingSetIds(NotificationChannels.EXTERNAL_CHANNEL.getChannelType());
userRecoveryDataStore.store(recoveryDataDO);
notificationResponseBean.setCode(IdentityRecoveryConstants.SuccessEvents.SUCCESS_STATUS_CODE_SUCCESSFUL_USER_CREATION_EXTERNAL_VERIFICATION.getCode());
notificationResponseBean.setMessage(IdentityRecoveryConstants.SuccessEvents.SUCCESS_STATUS_CODE_SUCCESSFUL_USER_CREATION_EXTERNAL_VERIFICATION.getMessage());
notificationResponseBean.setRecoveryId(secretKey);
notificationResponseBean.setNotificationChannel(NotificationChannels.EXTERNAL_CHANNEL.getChannelType());
// Populate the key variable in response bean to maintain backward compatibility.
notificationResponseBean.setKey(secretKey);
}
return notificationResponseBean;
}
use of org.wso2.carbon.identity.mgt.mail.Notification in project identity-governance by wso2-extensions.
the class UserSelfRegistrationManager method registerLiteUser.
public NotificationResponseBean registerLiteUser(User user, Claim[] claims, Property[] properties) throws IdentityRecoveryException {
String consent = getPropertyValue(properties, IdentityRecoveryConstants.Consent.CONSENT);
String tenantDomain = user.getTenantDomain();
if (StringUtils.isEmpty(tenantDomain)) {
tenantDomain = MultitenantConstants.SUPER_TENANT_DOMAIN_NAME;
}
// Callback URL validation
String callbackURL = null;
try {
callbackURL = Utils.getCallbackURLFromRegistration(properties);
if (StringUtils.isNotBlank(callbackURL) && !Utils.validateCallbackURL(callbackURL, tenantDomain, IdentityRecoveryConstants.ConnectorConfig.SELF_REGISTRATION_CALLBACK_REGEX)) {
throw Utils.handleServerException(IdentityRecoveryConstants.ErrorMessages.ERROR_CODE_CALLBACK_URL_NOT_VALID, callbackURL);
}
} catch (MalformedURLException | UnsupportedEncodingException | IdentityEventException e) {
throw Utils.handleServerException(IdentityRecoveryConstants.ErrorMessages.ERROR_CODE_CALLBACK_URL_NOT_VALID, callbackURL);
}
if (StringUtils.isBlank(user.getTenantDomain())) {
user.setTenantDomain(MultitenantConstants.SUPER_TENANT_DOMAIN_NAME);
log.info("registerUser :Tenant domain is not in the request. set to default for user : " + user.getUserName());
}
if (StringUtils.isBlank(user.getUserStoreDomain())) {
user.setUserStoreDomain(IdentityUtil.getPrimaryDomainName());
log.info("registerUser :User store domain is not in the request. set to default for user : " + user.getUserName());
}
boolean enable = Boolean.parseBoolean(Utils.getSignUpConfigs(IdentityRecoveryConstants.ConnectorConfig.ENABLE_LITE_SIGN_UP, user.getTenantDomain()));
if (!enable) {
throw Utils.handleClientException(IdentityRecoveryConstants.ErrorMessages.ERROR_CODE_DISABLE_LITE_SIGN_UP, user.getUserName());
}
NotificationResponseBean notificationResponseBean;
try {
RealmService realmService = IdentityRecoveryServiceDataHolder.getInstance().getRealmService();
UserStoreManager userStoreManager;
try {
userStoreManager = realmService.getTenantUserRealm(IdentityTenantUtil.getTenantId(user.getTenantDomain())).getUserStoreManager();
} catch (UserStoreException e) {
throw Utils.handleServerException(IdentityRecoveryConstants.ErrorMessages.ERROR_CODE_UNEXPECTED, user.getUserName(), e);
}
PrivilegedCarbonContext.startTenantFlow();
PrivilegedCarbonContext carbonContext = PrivilegedCarbonContext.getThreadLocalCarbonContext();
carbonContext.setTenantId(IdentityTenantUtil.getTenantId(user.getTenantDomain()));
carbonContext.setTenantDomain(user.getTenantDomain());
Map<String, String> claimsMap = new HashMap<>();
for (Claim claim : claims) {
claimsMap.put(claim.getClaimUri(), claim.getValue());
}
// Set lite user sign up claim to indicate the profile
claimsMap.put(IdentityRecoveryConstants.LITE_USER_CLAIM, Boolean.TRUE.toString());
// Set arbitrary properties to use in UserSelfRegistrationHandler
Utils.setArbitraryProperties(properties);
validateAndFilterFromReceipt(consent, claimsMap);
// User preferred notification channel.
String preferredChannel;
try {
String[] userRoles = new String[] {};
try {
NotificationChannelManager notificationChannelManager = Utils.getNotificationChannelManager();
preferredChannel = notificationChannelManager.resolveCommunicationChannel(user.getUserName(), user.getTenantDomain(), user.getUserStoreDomain(), claimsMap);
} catch (NotificationChannelManagerException e) {
throw mapNotificationChannelManagerException(e, user);
}
// resolved channel is not empty.
if (StringUtils.isEmpty(claimsMap.get(IdentityRecoveryConstants.PREFERRED_CHANNEL_CLAIM)) && StringUtils.isNotEmpty(preferredChannel)) {
claimsMap.put(IdentityRecoveryConstants.PREFERRED_CHANNEL_CLAIM, preferredChannel);
}
userStoreManager.addUser(IdentityUtil.addDomainToName(user.getUserName(), user.getUserStoreDomain()), Utils.generateRandomPassword(12), userRoles, claimsMap, null);
} catch (UserStoreException e) {
Throwable cause = e;
while (cause != null) {
if (cause instanceof PolicyViolationException) {
throw IdentityException.error(IdentityRecoveryClientException.class, IdentityRecoveryConstants.ErrorMessages.ERROR_CODE_POLICY_VIOLATION.getCode(), cause.getMessage(), e);
}
cause = cause.getCause();
}
return handleClientException(user, e);
}
addUserConsent(consent, tenantDomain);
// Build the notification response for lite user.
notificationResponseBean = buildLiteNotificationResponseBean(user, preferredChannel, claimsMap);
} finally {
Utils.clearArbitraryProperties();
PrivilegedCarbonContext.endTenantFlow();
}
return notificationResponseBean;
}
Aggregations