diff --git a/iam-common/pom.xml b/iam-common/pom.xml index 67ccb59c9..261b98d4c 100644 --- a/iam-common/pom.xml +++ b/iam-common/pom.xml @@ -6,7 +6,7 @@ it.infn.mw iam-parent - 1.8.1-SNAPSHOT + 1.8.1 iam-common diff --git a/iam-login-service/pom.xml b/iam-login-service/pom.xml index de7b5a5ea..3b370c3d5 100644 --- a/iam-login-service/pom.xml +++ b/iam-login-service/pom.xml @@ -23,7 +23,7 @@ it.infn.mw iam-parent - 1.8.1-SNAPSHOT + 1.8.1 iam-login-service diff --git a/iam-login-service/src/main/java/it/infn/mw/iam/api/common/client/RegisteredClientDTO.java b/iam-login-service/src/main/java/it/infn/mw/iam/api/common/client/RegisteredClientDTO.java index 1462d637b..b71f46e73 100644 --- a/iam-login-service/src/main/java/it/infn/mw/iam/api/common/client/RegisteredClientDTO.java +++ b/iam-login-service/src/main/java/it/infn/mw/iam/api/common/client/RegisteredClientDTO.java @@ -81,7 +81,7 @@ public class RegisteredClientDTO { private String clientSecret; @Size(min = 4, max = 256, - groups = {OnDynamicClientRegistration.class, OnClientCreation.class, OnClientUpdate.class}, + groups = {OnDynamicClientRegistration.class, OnClientCreation.class, OnClientUpdate.class, OnDynamicClientUpdate.class}, message = "Invalid length: must be between 4 and 256 characters") @NotBlank(groups = {OnDynamicClientRegistration.class, OnClientCreation.class}, message = "should not be blank") diff --git a/iam-login-service/src/main/java/it/infn/mw/iam/api/scim/controller/ScimMeController.java b/iam-login-service/src/main/java/it/infn/mw/iam/api/scim/controller/ScimMeController.java index 4cc88eac1..a340f6f15 100644 --- a/iam-login-service/src/main/java/it/infn/mw/iam/api/scim/controller/ScimMeController.java +++ b/iam-login-service/src/main/java/it/infn/mw/iam/api/scim/controller/ScimMeController.java @@ -31,7 +31,6 @@ import java.util.List; import org.mitre.oauth2.service.OAuth2TokenEntityService; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.ApplicationEventPublisher; import org.springframework.context.ApplicationEventPublisherAware; import org.springframework.http.HttpStatus; @@ -69,6 +68,7 @@ import it.infn.mw.iam.core.user.IamAccountService; import it.infn.mw.iam.persistence.model.IamAccount; import it.infn.mw.iam.persistence.repository.IamAccountRepository; +import it.infn.mw.iam.registration.validation.UsernameValidator; @SuppressWarnings("deprecation") @RestController @@ -90,18 +90,18 @@ public class ScimMeController implements ApplicationEventPublisherAware { private final EnumSet enabledUpdaters; - @Autowired public ScimMeController(IamAccountRepository accountRepository, IamAccountService accountService, OAuth2TokenEntityService tokenService, UserConverter userConverter, PasswordEncoder passwordEncoder, OidcIdConverter oidcIdConverter, SamlIdConverter samlIdConverter, SshKeyConverter sshKeyConverter, - X509CertificateConverter x509CertificateConverter, IamProperties properties) { + X509CertificateConverter x509CertificateConverter, IamProperties properties, + UsernameValidator usernameValidator) { this.iamAccountRepository = accountRepository; this.userConverter = userConverter; this.updatersFactory = new DefaultAccountUpdaterFactory(passwordEncoder, accountRepository, accountService, tokenService, oidcIdConverter, samlIdConverter, sshKeyConverter, - x509CertificateConverter); + x509CertificateConverter, usernameValidator); enabledUpdaters = EnumSet.noneOf(UpdaterType.class); diff --git a/iam-login-service/src/main/java/it/infn/mw/iam/api/scim/provisioning/ScimUserProvisioning.java b/iam-login-service/src/main/java/it/infn/mw/iam/api/scim/provisioning/ScimUserProvisioning.java index 420ac6c31..8e1d7fdf4 100644 --- a/iam-login-service/src/main/java/it/infn/mw/iam/api/scim/provisioning/ScimUserProvisioning.java +++ b/iam-login-service/src/main/java/it/infn/mw/iam/api/scim/provisioning/ScimUserProvisioning.java @@ -37,7 +37,6 @@ import java.util.List; import org.mitre.oauth2.service.OAuth2TokenEntityService; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.ApplicationEventPublisher; import org.springframework.context.ApplicationEventPublisherAware; import org.springframework.data.domain.Page; @@ -68,6 +67,7 @@ import it.infn.mw.iam.core.user.exception.UserAlreadyExistsException; import it.infn.mw.iam.persistence.model.IamAccount; import it.infn.mw.iam.persistence.repository.IamAccountRepository; +import it.infn.mw.iam.registration.validation.UsernameValidator; @Service public class ScimUserProvisioning @@ -87,18 +87,19 @@ public class ScimUserProvisioning private ApplicationEventPublisher eventPublisher; - @Autowired - public ScimUserProvisioning(IamAccountService accountService, OAuth2TokenEntityService tokenService, - IamAccountRepository accountRepository, PasswordEncoder passwordEncoder, - UserConverter userConverter, OidcIdConverter oidcIdConverter, SamlIdConverter samlIdConverter, - SshKeyConverter sshKeyConverter, X509CertificateConverter x509CertificateConverter) { + public ScimUserProvisioning(IamAccountService accountService, + OAuth2TokenEntityService tokenService, IamAccountRepository accountRepository, + PasswordEncoder passwordEncoder, UserConverter userConverter, OidcIdConverter oidcIdConverter, + SamlIdConverter samlIdConverter, SshKeyConverter sshKeyConverter, + X509CertificateConverter x509CertificateConverter, + UsernameValidator usernameValidator) { this.accountService = accountService; this.accountRepository = accountRepository; this.userConverter = userConverter; this.updatersFactory = new DefaultAccountUpdaterFactory(passwordEncoder, accountRepository, accountService, tokenService, oidcIdConverter, samlIdConverter, sshKeyConverter, - x509CertificateConverter); + x509CertificateConverter, usernameValidator); } public void setApplicationEventPublisher(ApplicationEventPublisher publisher) { diff --git a/iam-login-service/src/main/java/it/infn/mw/iam/api/scim/updater/builders/AccountBuilderSupport.java b/iam-login-service/src/main/java/it/infn/mw/iam/api/scim/updater/builders/AccountBuilderSupport.java index 2479e1c52..9d80aec9e 100644 --- a/iam-login-service/src/main/java/it/infn/mw/iam/api/scim/updater/builders/AccountBuilderSupport.java +++ b/iam-login-service/src/main/java/it/infn/mw/iam/api/scim/updater/builders/AccountBuilderSupport.java @@ -21,6 +21,7 @@ import it.infn.mw.iam.core.user.IamAccountService; import it.infn.mw.iam.persistence.model.IamAccount; import it.infn.mw.iam.persistence.repository.IamAccountRepository; +import it.infn.mw.iam.registration.validation.UsernameValidator; public abstract class AccountBuilderSupport { @@ -29,28 +30,21 @@ public abstract class AccountBuilderSupport { protected final PasswordEncoder encoder; protected final IamAccount account; protected final OAuth2TokenEntityService tokenService; + protected final UsernameValidator usernameValidator; public AccountBuilderSupport(IamAccountRepository repo, IamAccountService accountService, - OAuth2TokenEntityService tokenService, PasswordEncoder encoder, IamAccount account) { + OAuth2TokenEntityService tokenService, PasswordEncoder encoder, UsernameValidator usernameValidator, IamAccount account) { this.repo = repo; this.encoder = encoder; this.accountService = accountService; this.tokenService = tokenService; + this.usernameValidator = usernameValidator; this.account = account; } - public AccountBuilderSupport(IamAccountRepository repo, IamAccount account) { - this(repo, null, null, null, account); - } - - public AccountBuilderSupport(IamAccountRepository repo, IamAccountService accountService, - PasswordEncoder encoder, IamAccount account) { - this(repo, accountService, null, encoder, account); - } - public AccountBuilderSupport(IamAccountRepository repo, IamAccountService accountService, IamAccount account) { - this(repo, accountService, null, null, account); + this(repo, accountService, null, null, new UsernameValidator(), account); } } diff --git a/iam-login-service/src/main/java/it/infn/mw/iam/api/scim/updater/builders/AccountUpdaters.java b/iam-login-service/src/main/java/it/infn/mw/iam/api/scim/updater/builders/AccountUpdaters.java index fa0ffc787..4f47e1406 100644 --- a/iam-login-service/src/main/java/it/infn/mw/iam/api/scim/updater/builders/AccountUpdaters.java +++ b/iam-login-service/src/main/java/it/infn/mw/iam/api/scim/updater/builders/AccountUpdaters.java @@ -21,6 +21,7 @@ import it.infn.mw.iam.core.user.IamAccountService; import it.infn.mw.iam.persistence.model.IamAccount; import it.infn.mw.iam.persistence.repository.IamAccountRepository; +import it.infn.mw.iam.registration.validation.UsernameValidator; public class AccountUpdaters { @@ -29,8 +30,9 @@ private AccountUpdaters() { public static Adders adders(IamAccountRepository repo, IamAccountService accountService, PasswordEncoder encoder, - IamAccount account, OAuth2TokenEntityService tokenService) { - return new Adders(repo, accountService, encoder, account, tokenService); + IamAccount account, OAuth2TokenEntityService tokenService, + UsernameValidator usernameValidator) { + return new Adders(repo, accountService, encoder, account, tokenService, usernameValidator); } public static Removers removers(IamAccountRepository repo, IamAccountService accountService, @@ -39,10 +41,9 @@ public static Removers removers(IamAccountRepository repo, IamAccountService acc } public static Replacers replacers(IamAccountRepository repo, IamAccountService accountService, - PasswordEncoder encoder, - IamAccount account, OAuth2TokenEntityService tokenService) { - return new Replacers(repo, accountService, encoder, account, tokenService); + PasswordEncoder encoder, IamAccount account, OAuth2TokenEntityService tokenService, + UsernameValidator usernameValidator) { + return new Replacers(repo, accountService, encoder, account, tokenService, usernameValidator); } - } diff --git a/iam-login-service/src/main/java/it/infn/mw/iam/api/scim/updater/builders/Adders.java b/iam-login-service/src/main/java/it/infn/mw/iam/api/scim/updater/builders/Adders.java index 08b7ec1dc..8250a056f 100644 --- a/iam-login-service/src/main/java/it/infn/mw/iam/api/scim/updater/builders/Adders.java +++ b/iam-login-service/src/main/java/it/infn/mw/iam/api/scim/updater/builders/Adders.java @@ -49,6 +49,7 @@ import it.infn.mw.iam.persistence.model.IamSshKey; import it.infn.mw.iam.persistence.model.IamX509Certificate; import it.infn.mw.iam.persistence.repository.IamAccountRepository; +import it.infn.mw.iam.registration.validation.UsernameValidator; public class Adders extends Replacers { @@ -66,8 +67,9 @@ public class Adders extends Replacers { final Consumer> linkSshKeys; public Adders(IamAccountRepository repo, IamAccountService accountService, - PasswordEncoder encoder, IamAccount account, OAuth2TokenEntityService tokenService) { - super(repo, accountService, encoder, account, tokenService); + PasswordEncoder encoder, IamAccount account, OAuth2TokenEntityService tokenService, + UsernameValidator usernameValidator) { + super(repo, accountService, encoder, account, tokenService, usernameValidator); findByOidcId = id -> repo.findByOidcId(id.getIssuer(), id.getSubject()); findBySamlId = repo::findBySamlId; diff --git a/iam-login-service/src/main/java/it/infn/mw/iam/api/scim/updater/builders/Replacers.java b/iam-login-service/src/main/java/it/infn/mw/iam/api/scim/updater/builders/Replacers.java index dbb310191..7340ec897 100644 --- a/iam-login-service/src/main/java/it/infn/mw/iam/api/scim/updater/builders/Replacers.java +++ b/iam-login-service/src/main/java/it/infn/mw/iam/api/scim/updater/builders/Replacers.java @@ -46,6 +46,7 @@ import it.infn.mw.iam.persistence.model.IamAccount; import it.infn.mw.iam.persistence.model.IamUserInfo; import it.infn.mw.iam.persistence.repository.IamAccountRepository; +import it.infn.mw.iam.registration.validation.UsernameValidator; public class Replacers extends AccountBuilderSupport { @@ -59,9 +60,10 @@ public class Replacers extends AccountBuilderSupport { final AccountFinder findByUsername; public Replacers(IamAccountRepository repo, IamAccountService accountService, - PasswordEncoder encoder, IamAccount account, OAuth2TokenEntityService tokenService) { + PasswordEncoder encoder, IamAccount account, OAuth2TokenEntityService tokenService, + UsernameValidator usernameValidator) { - super(repo, accountService, tokenService, encoder, account); + super(repo, accountService, tokenService, encoder, usernameValidator, account); findByEmail = repo::findByEmail; findByUsername = repo::findByUsername; encodedPasswordSetter = t -> account.setPassword(encoder.encode(t)); @@ -90,7 +92,9 @@ private Predicate buildUsernameAddChecks() { Predicate usernameNotOwned = e -> !account.getUsername().equals(e); - return usernameNotBound.and(usernameNotOwned); + Predicate usernameNotUnix = e -> usernameValidator.isValid(e, null); + + return usernameNotBound.and(usernameNotOwned).and(usernameNotUnix); } public AccountUpdater givenName(String givenName) { diff --git a/iam-login-service/src/main/java/it/infn/mw/iam/api/scim/updater/factory/DefaultAccountUpdaterFactory.java b/iam-login-service/src/main/java/it/infn/mw/iam/api/scim/updater/factory/DefaultAccountUpdaterFactory.java index b213242be..d3533f044 100644 --- a/iam-login-service/src/main/java/it/infn/mw/iam/api/scim/updater/factory/DefaultAccountUpdaterFactory.java +++ b/iam-login-service/src/main/java/it/infn/mw/iam/api/scim/updater/factory/DefaultAccountUpdaterFactory.java @@ -56,6 +56,7 @@ import it.infn.mw.iam.persistence.model.IamSshKey; import it.infn.mw.iam.persistence.model.IamX509Certificate; import it.infn.mw.iam.persistence.repository.IamAccountRepository; +import it.infn.mw.iam.registration.validation.UsernameValidator; public class DefaultAccountUpdaterFactory implements AccountUpdaterFactory { @@ -65,6 +66,8 @@ public class DefaultAccountUpdaterFactory implements AccountUpdaterFactory sshKeyConverter(ScimUser user) { @@ -123,7 +128,7 @@ private static void addUpdater(List updaters, Predicate v private void prepareAdders(List updaters, ScimUser user, IamAccount account) { - Adders add = AccountUpdaters.adders(repo, accountService, encoder, account, tokenService); + Adders add = AccountUpdaters.adders(repo, accountService, encoder, account, tokenService, usernameValidator); if (user.hasName()) { @@ -191,7 +196,8 @@ private void prepareRemovers(List updaters, ScimUser user, IamAc private void prepareReplacers(List updaters, ScimUser user, IamAccount account) { - Replacers replace = AccountUpdaters.replacers(repo, accountService, encoder, account, tokenService); + Replacers replace = AccountUpdaters.replacers(repo, accountService, encoder, account, + tokenService, usernameValidator); if (user.hasName()) { addUpdater(updaters, Objects::nonNull, user.getName()::getGivenName, replace::givenName); diff --git a/iam-login-service/src/main/java/it/infn/mw/iam/config/IamConfig.java b/iam-login-service/src/main/java/it/infn/mw/iam/config/IamConfig.java index 3dc23f7f5..bf63a4aad 100644 --- a/iam-login-service/src/main/java/it/infn/mw/iam/config/IamConfig.java +++ b/iam-login-service/src/main/java/it/infn/mw/iam/config/IamConfig.java @@ -87,6 +87,7 @@ import it.infn.mw.iam.notification.service.resolver.NotifyGmsAndAdminsStrategy; import it.infn.mw.iam.persistence.repository.IamAccountRepository; import it.infn.mw.iam.persistence.repository.IamAupRepository; +import it.infn.mw.iam.registration.validation.UsernameValidator; import it.infn.mw.iam.service.aup.AUPSignatureCheckService; @SuppressWarnings("deprecation") @@ -234,7 +235,7 @@ IntrospectionResultAssembler defaultIntrospectionResultAssembler( } @Bean - public PasswordEncoder passwordEncoder() { + PasswordEncoder passwordEncoder() { return new BCryptPasswordEncoder(); } @@ -263,4 +264,9 @@ ServletRegistrationBean h2Console() { return new ServletRegistrationBean<>(h2Servlet, "/h2-console/*"); } + @Bean + UsernameValidator usernameRegExpValidator() { + return new UsernameValidator(); + } + } diff --git a/iam-login-service/src/main/java/it/infn/mw/iam/registration/RegistrationRequestDto.java b/iam-login-service/src/main/java/it/infn/mw/iam/registration/RegistrationRequestDto.java index d58456384..489ea32f3 100644 --- a/iam-login-service/src/main/java/it/infn/mw/iam/registration/RegistrationRequestDto.java +++ b/iam-login-service/src/main/java/it/infn/mw/iam/registration/RegistrationRequestDto.java @@ -18,28 +18,24 @@ import java.util.Date; import java.util.List; +import javax.validation.constraints.Size; + import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonProperty; import it.infn.mw.iam.api.common.LabelDTO; - -import javax.validation.constraints.Pattern; -import javax.validation.constraints.Size; +import it.infn.mw.iam.registration.validation.UsernameRegExp; @JsonInclude(JsonInclude.Include.NON_EMPTY) public class RegistrationRequestDto { - // Regular expression from https://unix.stackexchange.com/a/435120 - public static final String USERNAME_REGEXP = "^[a-z_]([a-z0-9_-]{0,31}|[a-z0-9_-]{0,30}\\$)$"; - private String uuid; private Date creationTime; private String status; private Date lastUpdateTime; @Size(max = 32, message = "username cannot be longer than 32 chars") - @Pattern(regexp = USERNAME_REGEXP, - message = "invalid username (the provided username is not a valid UNIX username)") + @UsernameRegExp private String username; private String password; private String givenname; diff --git a/iam-login-service/src/main/java/it/infn/mw/iam/registration/validation/UsernameRegExp.java b/iam-login-service/src/main/java/it/infn/mw/iam/registration/validation/UsernameRegExp.java new file mode 100644 index 000000000..b1842cbaf --- /dev/null +++ b/iam-login-service/src/main/java/it/infn/mw/iam/registration/validation/UsernameRegExp.java @@ -0,0 +1,38 @@ +/** + * Copyright (c) Istituto Nazionale di Fisica Nucleare (INFN). 2016-2021 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package it.infn.mw.iam.registration.validation; + +import static java.lang.annotation.ElementType.FIELD; +import static java.lang.annotation.RetentionPolicy.RUNTIME; + +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + +import javax.validation.Constraint; +import javax.validation.Payload; + +@Retention(RUNTIME) +@Target({FIELD}) +@Constraint(validatedBy = UsernameValidator.class) +public @interface UsernameRegExp { + + String message() default "invalid username (the provided username is not a valid UNIX username)"; + + Class[] groups() default {}; + + Class[] payload() default {}; + +} \ No newline at end of file diff --git a/iam-login-service/src/main/java/it/infn/mw/iam/registration/validation/UsernameValidator.java b/iam-login-service/src/main/java/it/infn/mw/iam/registration/validation/UsernameValidator.java new file mode 100644 index 000000000..ad1ac7b2d --- /dev/null +++ b/iam-login-service/src/main/java/it/infn/mw/iam/registration/validation/UsernameValidator.java @@ -0,0 +1,46 @@ +/** + * Copyright (c) Istituto Nazionale di Fisica Nucleare (INFN). 2016-2021 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package it.infn.mw.iam.registration.validation; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import javax.validation.ConstraintValidator; +import javax.validation.ConstraintValidatorContext; + +import org.springframework.context.annotation.Scope; +import org.springframework.stereotype.Component; + +@Component +@Scope("prototype") +public class UsernameValidator implements ConstraintValidator { + + // Regular expression from https://unix.stackexchange.com/a/435120 + public static final String DEFAULT_REG_EXP = "^[a-z_]([a-z0-9_@.-]{0,31}|[a-z0-9_@.-]{0,30}\\$)$"; + + Pattern pattern; + + public UsernameValidator() { + this.pattern = Pattern.compile(DEFAULT_REG_EXP); + } + + @Override + public boolean isValid(String value, ConstraintValidatorContext context) { + Matcher matcher = pattern.matcher(value); + return matcher.matches(); + } + +} diff --git a/iam-login-service/src/main/webapp/resources/iam/apps/dashboard-app/components/user/myclients/myclients.component.html b/iam-login-service/src/main/webapp/resources/iam/apps/dashboard-app/components/user/myclients/myclients.component.html index 7e904e999..7bb427ae7 100644 --- a/iam-login-service/src/main/webapp/resources/iam/apps/dashboard-app/components/user/myclients/myclients.component.html +++ b/iam-login-service/src/main/webapp/resources/iam/apps/dashboard-app/components/user/myclients/myclients.component.html @@ -16,58 +16,71 @@ -->
-

-    My clients -

+

+    My clients +

-
-
-
-
-
-
- - -
-
-
-

- No clients found. -

+
+
+
+
+
+
+ + +
+
+
+

No clients found.

-

- Showing clients - {{$ctrl.clients.startIndex}}-{{$ctrl.clients.startIndex+$ctrl.clients.itemsPerPage-1}} - of {{$ctrl.clients.totalResults}} -

+

+ Showing clients + {{$ctrl.clients.startIndex}}-{{$ctrl.clients.startIndex+$ctrl.clients.itemsPerPage-1}} + of {{$ctrl.clients.totalResults}}

-
-
- + {{client.client_name}} -
{{client.client_id}}
-
-
- -
-
-
-
    -
-
-
+
{{client.client_id}}
+
+
+ + +
+
+
+
    +
+
+
-
-
-
-
+
+
+ +
\ No newline at end of file diff --git a/iam-login-service/src/test/java/it/infn/mw/iam/test/registration/RegistrationUsernameTests.java b/iam-login-service/src/test/java/it/infn/mw/iam/test/registration/RegistrationUsernameTests.java index fd974409f..9eabe8f85 100644 --- a/iam-login-service/src/test/java/it/infn/mw/iam/test/registration/RegistrationUsernameTests.java +++ b/iam-login-service/src/test/java/it/infn/mw/iam/test/registration/RegistrationUsernameTests.java @@ -38,62 +38,67 @@ @RunWith(SpringRunner.class) @IamMockMvcIntegrationTest public class RegistrationUsernameTests extends TestSupport { - @Autowired - private ObjectMapper objectMapper; - @Autowired - private MockOAuth2Filter oauth2Filter; - - @Autowired - private MockMvc mvc; - - @Before - public void setup() { - oauth2Filter.cleanupSecurityContext(); - } - - @After - public void teardown() { - oauth2Filter.cleanupSecurityContext(); - } - - private RegistrationRequestDto createRegistrationRequest(String username) { - - String email = username + "@example.org"; - RegistrationRequestDto request = new RegistrationRequestDto(); - request.setGivenname("Test"); - request.setFamilyname("User"); - request.setEmail(email); - request.setUsername(username); - request.setNotes("Some short notes..."); - request.setPassword("password"); - - return request; + @Autowired + private ObjectMapper objectMapper; + + @Autowired + private MockOAuth2Filter oauth2Filter; + + @Autowired + private MockMvc mvc; + + @Before + public void setup() { + oauth2Filter.cleanupSecurityContext(); + } + + @After + public void teardown() { + oauth2Filter.cleanupSecurityContext(); + } + + private RegistrationRequestDto createRegistrationRequest(String username) { + + String email = username + "@example.org"; + RegistrationRequestDto request = new RegistrationRequestDto(); + request.setGivenname("Test"); + request.setFamilyname("User"); + request.setEmail(email); + request.setUsername(username); + request.setNotes("Some short notes..."); + request.setPassword("password"); + + return request; + } + + @Test + public void validUsernames() throws Exception { + final String[] validUsernames = {"bob", "b", "test$", "root", "test1234", "test_", "_test", + "username@example.com", "username@domain"}; + + for (String u : validUsernames) { + RegistrationRequestDto r = createRegistrationRequest(u); + mvc + .perform(post("/registration/create").contentType(MediaType.APPLICATION_JSON) + .content(objectMapper.writeValueAsString(r))) + .andExpect(status().isOk()); } - @Test - public void validUsernames() throws Exception { - final String[] validUsernames = {"bob", "b", "test$", "root", "test1234", "test_", "_test"}; - - for (String u : validUsernames) { - RegistrationRequestDto r = createRegistrationRequest(u); - mvc.perform(post("/registration/create").contentType(MediaType.APPLICATION_JSON) - .content(objectMapper.writeValueAsString(r))).andExpect(status().isOk()); - } + } - } - - @Test - public void nonUnixUsernames() throws Exception { - final String[] nonUnixUsernames = {"£$%^&*(", ".,", "-test", "1test", "test$$", "username@example.com", "username@domain", - "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"}; + @Test + public void invalidUsernames() throws Exception { + final String[] invalidUsernames = {"£$%^&*(", ".,", "-test", "1test", "test$$", "@domain", + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"}; - for (String u : nonUnixUsernames) { - RegistrationRequestDto r = createRegistrationRequest(u); - mvc.perform(post("/registration/create").contentType(MediaType.APPLICATION_JSON) - .content(objectMapper.writeValueAsString(r))).andExpect(status().isBadRequest()); - } + for (String u : invalidUsernames) { + RegistrationRequestDto r = createRegistrationRequest(u); + mvc + .perform(post("/registration/create").contentType(MediaType.APPLICATION_JSON) + .content(objectMapper.writeValueAsString(r))) + .andExpect(status().isBadRequest()); } - + } } diff --git a/iam-login-service/src/test/java/it/infn/mw/iam/test/scim/updater/AccountUpdatersTests.java b/iam-login-service/src/test/java/it/infn/mw/iam/test/scim/updater/AccountUpdatersTests.java index 51f01537d..54592d26e 100644 --- a/iam-login-service/src/test/java/it/infn/mw/iam/test/scim/updater/AccountUpdatersTests.java +++ b/iam-login-service/src/test/java/it/infn/mw/iam/test/scim/updater/AccountUpdatersTests.java @@ -53,6 +53,7 @@ import it.infn.mw.iam.persistence.model.IamSshKey; import it.infn.mw.iam.persistence.model.IamUserInfo; import it.infn.mw.iam.persistence.repository.IamAccountRepository; +import it.infn.mw.iam.registration.validation.UsernameValidator; import it.infn.mw.iam.test.ext_authn.x509.X509TestSupport; import it.infn.mw.iam.test.util.annotation.IamNoMvcTest; @@ -103,6 +104,9 @@ public class AccountUpdatersTests extends X509TestSupport { @Autowired private PasswordEncoder encoder; + @Autowired + private UsernameValidator usernameValidator; + private IamAccount account; private IamAccount other; @@ -120,7 +124,8 @@ private IamAccount newAccount(String username) { } private Adders accountAdders() { - return AccountUpdaters.adders(accountRepo, accountService, encoder, account, tokenService); + return AccountUpdaters.adders(accountRepo, accountService, encoder, account, tokenService, + usernameValidator); } private Removers accountRemovers() { @@ -128,7 +133,8 @@ private Removers accountRemovers() { } private Replacers accountReplacers() { - return AccountUpdaters.replacers(accountRepo, accountService, encoder, account, tokenService); + return AccountUpdaters.replacers(accountRepo, accountService, encoder, account, tokenService, + usernameValidator); } @Before diff --git a/iam-login-service/src/test/java/it/infn/mw/iam/test/scim/updater/UsernameUpdaterTests.java b/iam-login-service/src/test/java/it/infn/mw/iam/test/scim/updater/UsernameUpdaterTests.java index 23d8fbae3..3842d1c20 100644 --- a/iam-login-service/src/test/java/it/infn/mw/iam/test/scim/updater/UsernameUpdaterTests.java +++ b/iam-login-service/src/test/java/it/infn/mw/iam/test/scim/updater/UsernameUpdaterTests.java @@ -42,6 +42,7 @@ import it.infn.mw.iam.api.tokens.model.RefreshToken; import it.infn.mw.iam.persistence.model.IamAccount; import it.infn.mw.iam.persistence.model.IamUserInfo; +import it.infn.mw.iam.registration.validation.UsernameValidator; import it.infn.mw.iam.test.api.tokens.MultiValueMapBuilder; import it.infn.mw.iam.test.api.tokens.TestTokensUtils; import it.infn.mw.iam.test.util.WithMockOAuthUser; @@ -63,6 +64,9 @@ public class UsernameUpdaterTests extends TestTokensUtils { @Autowired private MockOAuth2Filter mockOAuth2Filter; + @Autowired + private UsernameValidator usernameValidator; + @Before public void setup() { clearAllTokens(); @@ -91,7 +95,7 @@ private IamAccount newAccount(String username) { private Replacers accountReplacers() { return AccountUpdaters.replacers(accountRepository, accountService, encoder, account, - tokenService); + tokenService, usernameValidator); } @Test diff --git a/iam-login-service/src/test/java/it/infn/mw/iam/test/scim/updater/factory/DefaultAccountUpdaterFactoryTests.java b/iam-login-service/src/test/java/it/infn/mw/iam/test/scim/updater/factory/DefaultAccountUpdaterFactoryTests.java index 046267610..e0816ca9f 100644 --- a/iam-login-service/src/test/java/it/infn/mw/iam/test/scim/updater/factory/DefaultAccountUpdaterFactoryTests.java +++ b/iam-login-service/src/test/java/it/infn/mw/iam/test/scim/updater/factory/DefaultAccountUpdaterFactoryTests.java @@ -83,6 +83,7 @@ import it.infn.mw.iam.persistence.model.IamSshKey; import it.infn.mw.iam.persistence.model.IamUserInfo; import it.infn.mw.iam.persistence.repository.IamAccountRepository; +import it.infn.mw.iam.registration.validation.UsernameValidator; import it.infn.mw.iam.test.util.RestAssuredJacksonUtils; @RunWith(MockitoJUnitRunner.class) @@ -124,11 +125,13 @@ private IamAccount newAccount(String username) { DefaultAccountUpdaterFactory factory; + UsernameValidator usernameValidator = new UsernameValidator(); + @Before public void init() { factory = new DefaultAccountUpdaterFactory(encoder, repo, accountService, tokenService, - oidcConverter, samlConverter, sshKeyConverter, x509Converter); + oidcConverter, samlConverter, sshKeyConverter, x509Converter, usernameValidator); } @Test diff --git a/iam-login-service/src/test/java/it/infn/mw/iam/test/scim/user/ScimUserProvisioningPatchTests.java b/iam-login-service/src/test/java/it/infn/mw/iam/test/scim/user/ScimUserProvisioningPatchTests.java index aa6364d02..54e39d5a9 100644 --- a/iam-login-service/src/test/java/it/infn/mw/iam/test/scim/user/ScimUserProvisioningPatchTests.java +++ b/iam-login-service/src/test/java/it/infn/mw/iam/test/scim/user/ScimUserProvisioningPatchTests.java @@ -115,19 +115,16 @@ public void testPatchUserInfo() throws Exception { scimUtils.patchUser(lennon.getId(), add, lennon_updates); - ScimUser updatedUser = scimUtils.getUser(lennon.getId()); - assertThat(updatedUser.getId(), equalTo(lennon.getId())); - assertThat(updatedUser.getUserName(), equalTo(lennon_updates.getUserName())); - assertThat(updatedUser.getDisplayName(), equalTo(lennon_updates.getUserName())); - assertThat(updatedUser.getName().getGivenName(), - equalTo(lennon_updates.getName().getGivenName())); - assertThat(updatedUser.getName().getMiddleName(), - equalTo(lennon_updates.getName().getMiddleName())); - assertThat(updatedUser.getName().getFamilyName(), - equalTo(lennon_updates.getName().getFamilyName())); - assertThat(updatedUser.getActive(), equalTo(lennon_updates.getActive())); - assertThat(updatedUser.getEmails(), hasSize(equalTo(1))); - assertThat(updatedUser.getEmails().get(0).getValue(), + ScimUser u = scimUtils.getUser(lennon.getId()); + assertThat(u.getId(), equalTo(lennon.getId())); + assertThat(u.getUserName(), equalTo(lennon_updates.getUserName())); + assertThat(u.getDisplayName(), equalTo(lennon_updates.getUserName())); + assertThat(u.getName().getGivenName(), equalTo(lennon_updates.getName().getGivenName())); + assertThat(u.getName().getMiddleName(), equalTo(lennon_updates.getName().getMiddleName())); + assertThat(u.getName().getFamilyName(), equalTo(lennon_updates.getName().getFamilyName())); + assertThat(u.getActive(), equalTo(lennon_updates.getActive())); + assertThat(u.getEmails(), hasSize(equalTo(1))); + assertThat(u.getEmails().get(0).getValue(), equalTo(lennon_updates.getEmails().get(0).getValue())); } diff --git a/iam-persistence/pom.xml b/iam-persistence/pom.xml index b5134d9ed..e6349a251 100644 --- a/iam-persistence/pom.xml +++ b/iam-persistence/pom.xml @@ -23,7 +23,7 @@ it.infn.mw iam-parent - 1.8.1-SNAPSHOT + 1.8.1 iam-persistence jar diff --git a/iam-persistence/src/main/resources/db/migration/h2/V91__update_client_name.sql b/iam-persistence/src/main/resources/db/migration/h2/V91__update_client_name.sql new file mode 100644 index 000000000..652a992c3 --- /dev/null +++ b/iam-persistence/src/main/resources/db/migration/h2/V91__update_client_name.sql @@ -0,0 +1,3 @@ +UPDATE client_details + set client_name = 'Change me please!' + where client_name = ''; \ No newline at end of file diff --git a/iam-persistence/src/main/resources/db/migration/mysql/V91__update_client_name.sql b/iam-persistence/src/main/resources/db/migration/mysql/V91__update_client_name.sql new file mode 100644 index 000000000..652a992c3 --- /dev/null +++ b/iam-persistence/src/main/resources/db/migration/mysql/V91__update_client_name.sql @@ -0,0 +1,3 @@ +UPDATE client_details + set client_name = 'Change me please!' + where client_name = ''; \ No newline at end of file diff --git a/iam-test-client/pom.xml b/iam-test-client/pom.xml index ff3ab40cb..2976e7b4c 100644 --- a/iam-test-client/pom.xml +++ b/iam-test-client/pom.xml @@ -7,7 +7,7 @@ it.infn.mw iam-parent - 1.8.1-SNAPSHOT + 1.8.1 iam-test-client diff --git a/iam-voms-aa/pom.xml b/iam-voms-aa/pom.xml index 23f98eb21..388bc1bde 100644 --- a/iam-voms-aa/pom.xml +++ b/iam-voms-aa/pom.xml @@ -24,7 +24,7 @@ it.infn.mw iam-parent - 1.8.1-SNAPSHOT + 1.8.1 iam-voms-aa diff --git a/pom.xml b/pom.xml index cb3926a18..ad29ddc00 100644 --- a/pom.xml +++ b/pom.xml @@ -15,7 +15,7 @@ it.infn.mw iam-parent - 1.8.1-SNAPSHOT + 1.8.1 pom INDIGO Identity and Access Manager (IAM) - Parent POM