Skip to content

Commit

Permalink
Register user / allow to select the group that wishes to register
Browse files Browse the repository at this point in the history
  • Loading branch information
josegar74 committed Jun 12, 2024
1 parent 3a69a56 commit d2e729c
Show file tree
Hide file tree
Showing 11 changed files with 236 additions and 49 deletions.
19 changes: 19 additions & 0 deletions core/src/test/resources/org/fao/geonet/api/Messages.properties
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,10 @@ register_email_admin_message=Dear Admin,\n\
Newly registered user %s has requested %s access for %s.\n\
Yours sincerely,\n\
The %s team.
register_email_group_admin_message=Dear Admin,\n\
Newly registered user %s has requested %s access in group %s for %s.\n\
Yours sincerely,\n\
The %s team.
register_email_subject=%s / Your account as %s
register_email_message=Dear User,\n\
Your registration at %s was successful.\n\
Expand All @@ -77,6 +81,21 @@ register_email_message=Dear User,\n\
\n\
Yours sincerely,\n\
The %s team.
register_email_group_message=Dear User,\n\
Your registration at %s was successful.\n\
Your account is: \n\
* username: %s\n\
* password: %s\n\
* profile: %s\n\
\n\
You've told us that you want to be %s in group %s, you will be contacted soon.\n\
To log in and access your account, please click on the link below.\n\
%s\n\
\n\
Thanks for your registration.\n\
\n\
Yours sincerely,\n\
The %s team.
new_user_rating=%s / New user rating on %s
new_user_rating_text=See record %s
user_feedback_title=%s / User feedback on %s / %s
Expand Down
16 changes: 16 additions & 0 deletions core/src/test/resources/org/fao/geonet/api/Messages_fre.properties
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,10 @@ register_email_admin_message=Cher administrateur,\n\
L'utilisateur %s vient de demander une cr\u00E9ation de compte pour %s.\n\
Salutation,\n\
L'\u00E9quipe %s.
register_email_group_admin_message=Cher administrateur,\n\
L'utilisateur %s vient de demander une cr\u00E9ation de compte pour %s en groupe %s.\n\
Salutation,\n\
L'\u00E9quipe %s.
register_email_subject=%s / Votre compte %s
register_email_message=Cher utilisateur,\n\
Votre compte a \u00E9t\u00E9 cr\u00E9\u00E9 avec succ\u00E9s pour %s.\n\
Expand All @@ -65,6 +69,18 @@ register_email_message=Cher utilisateur,\n\
\n\
Salutations,\n\
L'\u00E9quipe %s.
register_email_group_message=Cher utilisateur,\n\
Votre compte a \u00E9t\u00E9 cr\u00E9\u00E9 avec succ\u00E9s pour %s.\n\
* Nom d'utilisateur : %s\n\
* Mot de passe : %s\n\
* Profil : %s\n\
\n\
Vous avez demand\u00E9 un profil %s en groupe %s, vous serez contact\u00E9 par notre \u00E9quipe prochainement.\n\
Vous pouvez d\u00E9s \u00E0 pr\u00E9sent vous connecter.\n\
%s\n\
\n\
Salutations,\n\
L'\u00E9quipe %s.
new_user_rating=%s / Nouvelle \u00E9valuation faite pour %s
new_user_rating_text=Consulter la fiche %s
user_feedback_title=%s / Nouveau commentaire sur %s / %s
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,12 @@ Click the `Create an account` button and fill out the registration form:
The fields in this form are self-explanatory except for the following:

- **Email**: The user's email address. This is mandatory and will be used as the username.
- **Profile**: By default, self-registered users are given the `Registered User` profile (see previous section). If any other profile is selected:
- **Requested profile**: By default, self-registered users are given the `Registered User` profile (see previous section). If any other profile is selected:
- the user will still be given the `Registered User` profile
- an email will be sent to the Email address nominated in the Feedback section of the 'System Administration' menu, informing them of the request for a more privileged profile
- **Requested group**: By default, self-registered users are not assigned to any group. If a group is selected:
- the user will still not be assigned to any group
- an email will be sent to the Email address nominated in the Feedback section of the 'System Administration' menu, informing them of the requested group.

## What happens when a user self-registers?

Expand Down
151 changes: 107 additions & 44 deletions services/src/main/java/org/fao/geonet/api/users/RegisterApi.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
//=============================================================================
//=== Copyright (C) 2001-2021 Food and Agriculture Organization of the
//=== Copyright (C) 2001-2024 Food and Agriculture Organization of the
//=== United Nations (FAO-UN), United Nations World Food Programme (WFP)
//=== and United Nations Environment Programme (UNEP)
//===
Expand All @@ -26,7 +26,6 @@
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import jeeves.server.context.ServiceContext;
import org.fao.geonet.api.API;
import org.fao.geonet.api.ApiUtils;
import org.fao.geonet.api.tools.i18n.LanguageUtils;
import org.fao.geonet.api.users.model.UserRegisterDto;
Expand All @@ -45,17 +44,14 @@
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import org.springframework.validation.BindingResult;
import org.springframework.validation.ObjectError;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;

import javax.servlet.http.HttpServletRequest;
import java.sql.SQLException;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.ResourceBundle;
import java.util.*;

@EnableWebMvc
@Service
Expand All @@ -72,12 +68,20 @@ public class RegisterApi {
@Autowired(required=false)
SecurityProviderConfiguration securityProviderConfiguration;

@Autowired
GroupRepository groupRepository;

@Autowired
UserGroupRepository userGroupRepository;

@Autowired
SettingManager settingManager;

@io.swagger.v3.oas.annotations.Operation(summary = "Create user account",
description = "User is created with a registered user profile. username field is ignored and the email is used as " +
"username. Password is sent by email. Catalog administrator is also notified.")
@RequestMapping(
@PutMapping(
value = "/actions/register",
method = RequestMethod.PUT,
produces = MediaType.TEXT_PLAIN_VALUE)
@ResponseStatus(value = HttpStatus.CREATED)
@ResponseBody
Expand All @@ -101,19 +105,18 @@ public ResponseEntity<String> registerUser(

ServiceContext context = ApiUtils.createServiceContext(request);

SettingManager sm = context.getBean(SettingManager.class);
boolean selfRegistrationEnabled = sm.getValueAsBool(Settings.SYSTEM_USERSELFREGISTRATION_ENABLE);
boolean selfRegistrationEnabled = settingManager.getValueAsBool(Settings.SYSTEM_USERSELFREGISTRATION_ENABLE);
if (!selfRegistrationEnabled) {
return new ResponseEntity<>(String.format(
messages.getString("self_registration_disabled")
), HttpStatus.PRECONDITION_FAILED);
}

boolean recaptchaEnabled = sm.getValueAsBool(Settings.SYSTEM_USERSELFREGISTRATION_RECAPTCHA_ENABLE);
boolean recaptchaEnabled = settingManager.getValueAsBool(Settings.SYSTEM_USERSELFREGISTRATION_RECAPTCHA_ENABLE);

if (recaptchaEnabled) {
boolean validRecaptcha = RecaptchaChecker.verify(userRegisterDto.getCaptcha(),
sm.getValue(Settings.SYSTEM_USERSELFREGISTRATION_RECAPTCHA_SECRETKEY));
settingManager.getValue(Settings.SYSTEM_USERSELFREGISTRATION_RECAPTCHA_SECRETKEY));
if (!validRecaptcha) {
return new ResponseEntity<>(
messages.getString("recaptcha_not_valid"), HttpStatus.PRECONDITION_FAILED);
Expand Down Expand Up @@ -144,7 +147,7 @@ public ResponseEntity<String> registerUser(
), HttpStatus.PRECONDITION_FAILED);
}

if (userRepository.findByUsernameIgnoreCase(userRegisterDto.getEmail()).size() != 0) {
if (!userRepository.findByUsernameIgnoreCase(userRegisterDto.getEmail()).isEmpty()) {
// username is ignored and the email is used as username in selfregister
return new ResponseEntity<>(String.format(
messages.getString("user_with_that_username_found"),
Expand All @@ -153,16 +156,13 @@ public ResponseEntity<String> registerUser(
}

User user = new User();

// user.setUsername(userRegisterDto.getUsername());
user.setName(userRegisterDto.getName());
user.setSurname(userRegisterDto.getSurname());
user.setOrganisation(userRegisterDto.getOrganisation());
user.setProfile(Profile.findProfileIgnoreCase(userRegisterDto.getProfile()));
user.getAddresses().add(userRegisterDto.getAddress());
user.getEmailAddresses().add(userRegisterDto.getEmail());


String password = User.getRandomPassword();
user.getSecurity().setPassword(
PasswordUtil.encode(context, password)
Expand All @@ -172,48 +172,80 @@ public ResponseEntity<String> registerUser(
user.setProfile(Profile.RegisteredUser);
user = userRepository.save(user);

Group targetGroup = getGroup(context);
Group targetGroup = getGroup();

if (targetGroup != null) {
UserGroup userGroup = new UserGroup().setUser(user).setGroup(targetGroup).setProfile(Profile.RegisteredUser);
context.getBean(UserGroupRepository.class).save(userGroup);
userGroupRepository.save(userGroup);
}


String catalogAdminEmail = sm.getValue(Settings.SYSTEM_FEEDBACK_EMAIL);

String catalogAdminEmail = settingManager.getValue(Settings.SYSTEM_FEEDBACK_EMAIL);
String subject = String.format(
messages.getString("register_email_admin_subject"),
sm.getSiteName(),
settingManager.getSiteName(),
user.getEmail(),
requestedProfile
);
String message = String.format(
messages.getString("register_email_admin_message"),
user.getEmail(),
requestedProfile,
sm.getNodeURL(),
sm.getSiteName()
);
if (!MailUtil.sendMail(catalogAdminEmail, subject, message, null, sm)) {
Group requestedGroup = getRequestedGroup(userRegisterDto.getGroup());
String message;
if (requestedGroup != null) {
message = String.format(
messages.getString("register_email_group_admin_message"),
user.getEmail(),
requestedProfile,
requestedGroup.getLabelTranslations().get(context.getLanguage()),
settingManager.getNodeURL(),
settingManager.getSiteName()
);
} else {
message = String.format(
messages.getString("register_email_admin_message"),
user.getEmail(),
requestedProfile,
settingManager.getNodeURL(),
settingManager.getSiteName()
);

}

if (Boolean.FALSE.equals(MailUtil.sendMail(catalogAdminEmail, subject, message, null, settingManager))) {
return new ResponseEntity<>(String.format(
messages.getString("mail_error")), HttpStatus.PRECONDITION_FAILED);
}

subject = String.format(
messages.getString("register_email_subject"),
sm.getSiteName(),
settingManager.getSiteName(),
user.getProfile()
);
message = String.format(
messages.getString("register_email_message"),
sm.getSiteName(),
user.getUsername(),
password,
Profile.RegisteredUser,
requestedProfile,
sm.getNodeURL(),
sm.getSiteName()
);
if (!MailUtil.sendMail(user.getEmail(), subject, message, null, sm)) {
if (requestedGroup != null) {
message = String.format(
messages.getString("register_email_group_message"),
settingManager.getSiteName(),
user.getUsername(),
password,
Profile.RegisteredUser,
requestedProfile,
requestedGroup.getLabelTranslations().get(context.getLanguage()),
settingManager.getNodeURL(),
settingManager.getSiteName()
);
} else {
message = String.format(
messages.getString("register_email_message"),
settingManager.getSiteName(),
user.getUsername(),
password,
Profile.RegisteredUser,
requestedProfile,
settingManager.getNodeURL(),
settingManager.getSiteName()
);
}

if (Boolean.FALSE.equals(MailUtil.sendMail(user.getEmail(), subject, message, null, settingManager))) {
return new ResponseEntity<>(String.format(
messages.getString("mail_error")), HttpStatus.PRECONDITION_FAILED);
}
Expand All @@ -224,8 +256,39 @@ public ResponseEntity<String> registerUser(
), HttpStatus.CREATED);
}

Group getGroup(ServiceContext context) throws SQLException {
final GroupRepository bean = context.getBean(GroupRepository.class);
return bean.findById(ReservedGroup.guest.getId()).get();
/**
* Returns the group (GUEST) to assign to the registered user.
*
* @return
*/
private Group getGroup() {
Optional<Group> targetGroupOpt = groupRepository.findById(ReservedGroup.guest.getId());

if (targetGroupOpt.isPresent()) {
return targetGroupOpt.get();
}

return null;
}

/**
* Returns the group requested by the registered user.
*
* @param requestedGroup Requested group identifier for the user.
* @return
*/
Group getRequestedGroup(String requestedGroup) {
Group targetGroup = null;

if (StringUtils.hasLength(requestedGroup)) {
Optional<Group> targetGroupOpt = groupRepository.findById(Integer.parseInt(requestedGroup));

// Don't allow reserved groups
if (targetGroupOpt.isPresent() && !targetGroupOpt.get().isReserved()) {
targetGroup = targetGroupOpt.get();
}
}

return targetGroup;
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2001-2016 Food and Agriculture Organization of the
* Copyright (C) 2001-2024 Food and Agriculture Organization of the
* United Nations (FAO-UN), United Nations World Food Programme (WFP)
* and United Nations Environment Programme (UNEP)
*
Expand Down Expand Up @@ -27,7 +27,6 @@
/**
* DTO class for user register information.
*
* @author Jose García
*/
public class UserRegisterDto {
private String profile;
Expand All @@ -39,6 +38,8 @@ public class UserRegisterDto {
private Address address;
private String captcha;

private String group;

public String getProfile() {
return profile;
}
Expand Down Expand Up @@ -103,13 +104,22 @@ public void setCaptcha(String captcha) {
this.captcha = captcha;
}

public String getGroup() {
return group;
}

public void setGroup(String group) {
this.group = group;
}

@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;

UserRegisterDto that = (UserRegisterDto) o;

if (group != null ? !group.equals(that.group) : that.group != null) return false;
if (profile != null ? !profile.equals(that.profile) : that.profile != null) return false;
if (username != null ? !username.equals(that.username) : that.username != null) return false;
if (email != null ? !email.equals(that.email) : that.email != null) return false;
Expand All @@ -123,6 +133,7 @@ public boolean equals(Object o) {
@Override
public int hashCode() {
int result = profile != null ? profile.hashCode() : 0;
result = 31 * result + (group != null ? group.hashCode() : 0);
result = 31 * result + (username != null ? username.hashCode() : 0);
result = 31 * result + (email != null ? email.hashCode() : 0);
result = 31 * result + (name != null ? name.hashCode() : 0);
Expand Down
Loading

0 comments on commit d2e729c

Please sign in to comment.