Allow the . (dot) and @ (at) character in usernames (#637)

Co-authored-by: Uli Koeth <uli@kiot.eu>
This commit is contained in:
Uli 2022-05-05 17:48:45 +02:00 committed by GitHub
parent c6a685d7c0
commit 90d5bc8de7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 16 additions and 8 deletions

View File

@ -21,6 +21,8 @@ public class ValidationUtil {
private static Pattern ALPHANUMERIC_PATTERN = Pattern.compile("[a-zA-Z0-9_]+"); private static Pattern ALPHANUMERIC_PATTERN = Pattern.compile("[a-zA-Z0-9_]+");
private static Pattern USERNAME_PATTERN = Pattern.compile("[a-zA-Z0-9_@\\.]+");
/** /**
* Checks that the argument is not null. * Checks that the argument is not null.
* *
@ -152,6 +154,12 @@ public class ValidationUtil {
} }
} }
public static void validateUsernamepattern(String s, String name) throws ClientException {
if (!USERNAME_PATTERN.matcher(s).matches()) {
throw new ClientException("ValidationError", MessageFormat.format("{0} must have only alphanumeric, underscore characters or @ and .", name));
}
}
public static void validateRegex(String s, String name, String regex) throws ClientException { public static void validateRegex(String s, String name, String regex) throws ClientException {
if (!Pattern.compile(regex).matcher(s).matches()) { if (!Pattern.compile(regex).matcher(s).matches()) {
throw new ClientException("ValidationError", MessageFormat.format("{0} must match {1}", name, regex)); throw new ClientException("ValidationError", MessageFormat.format("{0} must match {1}", name, regex));

View File

@ -313,7 +313,7 @@ public class GroupResource extends BaseResource {
* @return Response * @return Response
*/ */
@DELETE @DELETE
@Path("{groupName: [a-zA-Z0-9_]+}/{username: [a-zA-Z0-9_]+}") @Path("{groupName: [a-zA-Z0-9_]+}/{username: [a-zA-Z0-9_@\\.]+}")
public Response removeMember(@PathParam("groupName") String groupName, public Response removeMember(@PathParam("groupName") String groupName,
@PathParam("username") String username) { @PathParam("username") String username) {
if (!authenticate()) { if (!authenticate()) {

View File

@ -88,7 +88,7 @@ public class UserResource extends BaseResource {
// Validate the input data // Validate the input data
username = ValidationUtil.validateLength(username, "username", 3, 50); username = ValidationUtil.validateLength(username, "username", 3, 50);
ValidationUtil.validateAlphanumeric(username, "username"); ValidationUtil.validateUsernamepattern(username, "username");
password = ValidationUtil.validateLength(password, "password", 8, 50); password = ValidationUtil.validateLength(password, "password", 8, 50);
email = ValidationUtil.validateLength(email, "email", 1, 100); email = ValidationUtil.validateLength(email, "email", 1, 100);
Long storageQuota = ValidationUtil.validateLong(storageQuotaStr, "storage_quota"); Long storageQuota = ValidationUtil.validateLong(storageQuotaStr, "storage_quota");
@ -195,7 +195,7 @@ public class UserResource extends BaseResource {
* @return Response * @return Response
*/ */
@POST @POST
@Path("{username: [a-zA-Z0-9_]+}") @Path("{username: [a-zA-Z0-9_@\\.]+}")
public Response update( public Response update(
@PathParam("username") String username, @PathParam("username") String username,
@FormParam("password") String password, @FormParam("password") String password,
@ -511,7 +511,7 @@ public class UserResource extends BaseResource {
* @return Response * @return Response
*/ */
@DELETE @DELETE
@Path("{username: [a-zA-Z0-9_]+}") @Path("{username: [a-zA-Z0-9_@\\.]+}")
public Response delete(@PathParam("username") String username) { public Response delete(@PathParam("username") String username) {
if (!authenticate()) { if (!authenticate()) {
throw new ForbiddenClientException(); throw new ForbiddenClientException();
@ -591,7 +591,7 @@ public class UserResource extends BaseResource {
* @return Response * @return Response
*/ */
@POST @POST
@Path("{username: [a-zA-Z0-9_]+}/disable_totp") @Path("{username: [a-zA-Z0-9_@\\.]+}/disable_totp")
public Response disableTotpUsername(@PathParam("username") String username) { public Response disableTotpUsername(@PathParam("username") String username) {
if (!authenticate()) { if (!authenticate()) {
throw new ForbiddenClientException(); throw new ForbiddenClientException();
@ -713,7 +713,7 @@ public class UserResource extends BaseResource {
* @return Response * @return Response
*/ */
@GET @GET
@Path("{username: [a-zA-Z0-9_]+}") @Path("{username: [a-zA-Z0-9_@\\.]+}")
@Produces(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON)
public Response view(@PathParam("username") String username) { public Response view(@PathParam("username") String username) {
if (!authenticate()) { if (!authenticate()) {

View File

@ -9,7 +9,7 @@
<label class="col-sm-2 control-label" for="inputUserUsername">{{ 'settings.user.edit.username' | translate }}</label> <label class="col-sm-2 control-label" for="inputUserUsername">{{ 'settings.user.edit.username' | translate }}</label>
<div class="col-sm-7"> <div class="col-sm-7">
<input name="userUsername" type="text" id="inputUserUsername" required ng-disabled="isEdit()" class="form-control" <input name="userUsername" type="text" id="inputUserUsername" required ng-disabled="isEdit()" class="form-control"
ng-pattern="/^[a-zA-Z0-9_]*$/" ng-pattern="/^[a-zA-Z0-9_@\.]*$/"
ng-minlength="3" ng-maxlength="50" ng-attr-placeholder="{{ 'settings.user.edit.username' | translate }}" ng-model="user.username"/> ng-minlength="3" ng-maxlength="50" ng-attr-placeholder="{{ 'settings.user.edit.username' | translate }}" ng-model="user.username"/>
</div> </div>
@ -129,4 +129,4 @@
</div> </div>
</div> </div>
</form> </form>
</div> </div>