Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
4 changes: 4 additions & 0 deletions iam-common/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,10 @@
<artifactId>iam-persistence</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>com.nimbusds</groupId>
<artifactId>nimbus-jose-jwt</artifactId>
</dependency>
</dependencies>

<build>
Expand Down
35 changes: 20 additions & 15 deletions iam-login-service/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,6 @@
<test-clock.version>1.0.2</test-clock.version>
<eclipselink.version>2.7.9</eclipselink.version>
<javax.persistence.version>2.2.1</javax.persistence.version>
<nimbus-jose-jwt.version>9.37.4</nimbus-jose-jwt.version>
</properties>

<dependencies>
Expand Down Expand Up @@ -201,11 +200,10 @@
<artifactId>javax.persistence</artifactId>
<version>${javax.persistence.version}</version>
</dependency>

<dependency>
<groupId>com.nimbusds</groupId>
<artifactId>nimbus-jose-jwt</artifactId>
<version>${nimbus-jose-jwt.version}</version>
</dependency>

<!-- OAuth 2 dependencies -->
Expand Down Expand Up @@ -238,6 +236,18 @@
<artifactId>jstl</artifactId>
</dependency>

<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>javax.servlet.jsp-api</artifactId>
<version>2.3.3</version>
<scope>provided</scope>
</dependency>

<dependency>
<groupId>org.freemarker</groupId>
<artifactId>freemarker</artifactId>
</dependency>

<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-taglibs</artifactId>
Expand Down Expand Up @@ -273,21 +283,17 @@
<scope>runtime</scope>
</dependency>

<!-- Mitre -->
<!-- Guava -->
<dependency>
<groupId>org.mitre</groupId>
<artifactId>openid-connect-server</artifactId>
<exclusions>
<exclusion>
<groupId>org.eclipse.persistence</groupId>
<artifactId>org.eclipse.persistence.core</artifactId>
</exclusion>
</exclusions>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>33.5.0-jre</version>
</dependency>

<!-- Apache -->
<dependency>
<groupId>org.mitre</groupId>
<artifactId>openid-connect-client</artifactId>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
</dependency>

<!-- VOMS -->
Expand All @@ -297,7 +303,6 @@
</dependency>

<!-- Bouncy Castle -->

<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcpkix-jdk18on</artifactId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,20 +15,6 @@
*/
package it.infn.mw.iam;

import org.mitre.discovery.web.DiscoveryEndpoint;
import org.mitre.oauth2.service.impl.DefaultOAuth2ProviderTokenService;
import org.mitre.oauth2.web.CorsFilter;
import org.mitre.oauth2.web.DeviceEndpoint;
import org.mitre.oauth2.web.IntrospectionEndpoint;
import org.mitre.oauth2.web.OAuthConfirmationController;
import org.mitre.oauth2.web.RevocationEndpoint;
import org.mitre.openid.connect.token.ConnectTokenEnhancer;
import org.mitre.openid.connect.token.TofuUserApprovalHandler;
import org.mitre.openid.connect.view.UserInfoView;
import org.mitre.openid.connect.web.DynamicClientRegistrationEndpoint;
import org.mitre.openid.connect.web.JWKSetPublishingEndpoint;
import org.mitre.openid.connect.web.RootController;
import org.mitre.openid.connect.web.UserInfoEndpoint;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.SpringBootApplication;
Expand All @@ -37,7 +23,6 @@
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.FilterType;
import org.springframework.context.support.PropertySourcesPlaceholderConfigurer;
import org.springframework.core.io.ClassPathResource;
import org.springframework.transaction.annotation.EnableTransactionManagement;
Expand All @@ -60,42 +45,13 @@
"it.infn.mw.iam.audit",
"it.infn.mw.iam.actuator",
"it.infn.mw.iam.rcauth",
"it.infn.mw.iam.service.aup",
"org.mitre.oauth2.web",
"org.mitre.oauth2.view",
"org.mitre.openid.connect.web",
"org.mitre.openid.connect.view",
"org.mitre.discovery.web",
"org.mitre.discovery.view"},
excludeFilters = {
@ComponentScan.Filter(type=FilterType.ASSIGNABLE_TYPE,
value=UserInfoEndpoint.class),
@ComponentScan.Filter(type=FilterType.ASSIGNABLE_TYPE,
value=RootController.class),
@ComponentScan.Filter(type=FilterType.ASSIGNABLE_TYPE,
value=DiscoveryEndpoint.class),
@ComponentScan.Filter(type=FilterType.ASSIGNABLE_TYPE,
value=JWKSetPublishingEndpoint.class),
@ComponentScan.Filter(type=FilterType.ASSIGNABLE_TYPE,
value=DynamicClientRegistrationEndpoint.class),
@ComponentScan.Filter(type=FilterType.ASSIGNABLE_TYPE,
value=CorsFilter.class),
@ComponentScan.Filter(type=FilterType.ASSIGNABLE_TYPE,
value=OAuthConfirmationController.class),
@ComponentScan.Filter(type=FilterType.ASSIGNABLE_TYPE,
value=DeviceEndpoint.class),
@ComponentScan.Filter(type=FilterType.ASSIGNABLE_TYPE,
value=TofuUserApprovalHandler.class),
@ComponentScan.Filter(type=FilterType.ASSIGNABLE_TYPE,
value=IntrospectionEndpoint.class),
@ComponentScan.Filter(type=FilterType.ASSIGNABLE_TYPE,
value=RevocationEndpoint.class),
@ComponentScan.Filter(type=FilterType.ASSIGNABLE_TYPE,
value=UserInfoView.class),
@ComponentScan.Filter(type=FilterType.ASSIGNABLE_TYPE,
value=ConnectTokenEnhancer.class),
@ComponentScan.Filter(type=FilterType.ASSIGNABLE_TYPE,
value=DefaultOAuth2ProviderTokenService.class)
"it.infn.mw.iam.service.aup"
// "org.mitre.oauth2.web",
// "org.mitre.oauth2.view",
// "org.mitre.openid.connect.web",
// "org.mitre.openid.connect.view",
// "org.mitre.discovery.web",
// "org.mitre.discovery.view"
})
@EnableCaching
@EnableAutoConfiguration(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import static java.lang.String.format;
import static org.springframework.http.HttpStatus.NO_CONTENT;

import java.util.ArrayList;
import java.util.List;

import org.springframework.http.HttpStatus;
Expand All @@ -34,7 +35,7 @@
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestController;

import com.google.common.collect.Lists;
//import com.google.common.collect.Lists;

import it.infn.mw.iam.api.common.AttributeDTO;
import it.infn.mw.iam.api.common.AttributeDTOConverter;
Expand Down Expand Up @@ -74,7 +75,7 @@ public List<AttributeDTO> getAttributes(@PathVariable String id) {
IamAccount account =
accountService.findByUuid(id).orElseThrow(() -> NoSuchAccountError.forUuid(id));

List<AttributeDTO> results = Lists.newArrayList();
List<AttributeDTO> results = new ArrayList<>();
account.getAttributes().forEach(a -> results.add(converter.dtoFromEntity(a)));

return results;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
*/
package it.infn.mw.iam.api.account.authority;

import static com.google.common.base.Preconditions.checkNotNull;
import static java.util.Objects.requireNonNull;

import java.util.Set;
import java.util.stream.Collectors;
Expand Down Expand Up @@ -52,15 +52,15 @@ public void setApplicationEventPublisher(ApplicationEventPublisher publisher) {
}

protected IamAuthority findAuthorityFromString(String authority) {
checkNotNull(authority, "authority must not be null");
requireNonNull(authority, "authority must not be null");

return authRepo.findByAuthority(authority).orElseThrow(
() -> new InvalidAuthorityError(String.format("Invalid authority: '%s'", authority)));
}

@Override
public void addAuthorityToAccount(IamAccount account, String authority) {
checkNotNull(account, ACCOUNT_NOT_NULL_MSG);
requireNonNull(account, ACCOUNT_NOT_NULL_MSG);

IamAuthority iamAuthority = findAuthorityFromString(authority);

Expand All @@ -81,7 +81,7 @@ public void addAuthorityToAccount(IamAccount account, String authority) {

@Override
public void removeAuthorityFromAccount(IamAccount account, String authority) {
checkNotNull(account, ACCOUNT_NOT_NULL_MSG);
requireNonNull(account, ACCOUNT_NOT_NULL_MSG);
IamAuthority iamAuthority = findAuthorityFromString(authority);
account.getAuthorities().remove(iamAuthority);
accountRepo.save(account);
Expand All @@ -94,7 +94,7 @@ public void removeAuthorityFromAccount(IamAccount account, String authority) {

@Override
public Set<String> getAccountAuthorities(IamAccount account) {
checkNotNull(account, ACCOUNT_NOT_NULL_MSG);
requireNonNull(account, ACCOUNT_NOT_NULL_MSG);

return account.getAuthorities()
.stream()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,8 @@
import java.util.List;
import java.util.stream.Collectors;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.google.common.collect.Lists;

import it.infn.mw.iam.api.account.authority.AccountAuthorityService;
import it.infn.mw.iam.api.account.group_manager.error.InvalidManagedGroupError;
import it.infn.mw.iam.api.account.group_manager.model.AccountManagedGroupsDTO;
Expand All @@ -40,13 +37,11 @@
public class DefaultAccountGroupManagerService implements AccountGroupManagerService {

public static final String ROLE_GM_TEMPLATE = "ROLE_GM:%s";

final IamAccountRepository accountRepo;
final IamGroupRepository groupRepo;
final AccountAuthorityService authorityService;


@Autowired
public DefaultAccountGroupManagerService(IamAccountRepository accountRepo,
IamGroupRepository groupRepo, AccountAuthorityService authorityService) {
this.accountRepo = accountRepo;
Expand Down Expand Up @@ -94,10 +89,10 @@ public AccountManagedGroupsDTO getManagedGroupInfoForAccount(IamAccount account)

result.managedGroups(iamGroupsToDTO(managedGroups));

List<IamGroup> unmanagedGroups = null;
List<IamGroup> unmanagedGroups = new ArrayList<>();

if (managedGroups.isEmpty()) {
unmanagedGroups = Lists.newArrayList(groupRepo.findAll());
unmanagedGroups.addAll(groupRepo.findAll());
} else {
unmanagedGroups = groupRepo
.findByUuidNotIn(managedGroups.stream().map(IamGroup::getUuid).collect(Collectors.toSet()));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import static java.lang.String.format;
import static org.springframework.http.HttpStatus.NO_CONTENT;

import java.util.ArrayList;
import java.util.List;
import java.util.function.Supplier;

Expand All @@ -36,8 +37,6 @@
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestController;

import com.google.common.collect.Lists;

import it.infn.mw.iam.api.common.ErrorDTO;
import it.infn.mw.iam.api.common.LabelDTO;
import it.infn.mw.iam.api.common.LabelDTOConverter;
Expand Down Expand Up @@ -77,7 +76,7 @@ public List<LabelDTO> getLabels(@PathVariable String id) {

IamAccount account = service.findByUuid(id).orElseThrow(noSuchAccountError(id));

List<LabelDTO> results = Lists.newArrayList();
List<LabelDTO> results = new ArrayList<>();

account.getLabels().forEach(l -> results.add(converter.dtoFromEntity(l)));

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,10 @@

import java.util.Optional;

import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.context.ApplicationEventPublisherAware;
import org.springframework.context.annotation.Profile;
import org.springframework.stereotype.Service;

import dev.samstevens.totp.code.CodeVerifier;
Expand All @@ -38,10 +40,12 @@
import it.infn.mw.iam.util.mfa.IamTotpMfaInvalidArgumentError;

@Service
@Profile("mfa")
public class DefaultIamTotpMfaService implements IamTotpMfaService, ApplicationEventPublisherAware {

public static final int RECOVERY_CODE_QUANTITY = 6;
private static final String MFA_SECRET_NOT_FOUND_MESSAGE = "No multi-factor secret is attached to this account";
private static final String MFA_SECRET_NOT_FOUND_MESSAGE =
"No multi-factor secret is attached to this account";

private final IamAccountService iamAccountService;
private final IamTotpMfaRepository totpMfaRepository;
Expand All @@ -51,9 +55,10 @@ public class DefaultIamTotpMfaService implements IamTotpMfaService, ApplicationE
private ApplicationEventPublisher eventPublisher;

public DefaultIamTotpMfaService(IamAccountService iamAccountService,
IamTotpMfaRepository totpMfaRepository, SecretGenerator secretGenerator,
CodeVerifier codeVerifier, ApplicationEventPublisher eventPublisher,
IamTotpMfaProperties iamTotpMfaProperties) {
IamTotpMfaRepository totpMfaRepository,
@Qualifier("secretGenerator") SecretGenerator secretGenerator,
@Qualifier("codeVerifier") CodeVerifier codeVerifier,
ApplicationEventPublisher eventPublisher, IamTotpMfaProperties iamTotpMfaProperties) {
this.iamAccountService = iamAccountService;
this.totpMfaRepository = totpMfaRepository;
this.secretGenerator = secretGenerator;
Expand All @@ -80,9 +85,9 @@ public void setApplicationEventPublisher(ApplicationEventPublisher applicationEv
}

/**
* Generates and attaches a TOTP MFA secret to a user account
* This is pre-emptive to actually enabling TOTP MFA on the account - the secret is written for
* server-side TOTP verification during the user's enabling of MFA on their account
* Generates and attaches a TOTP MFA secret to a user account This is pre-emptive to actually
* enabling TOTP MFA on the account - the secret is written for server-side TOTP verification
* during the user's enabling of MFA on their account
*
* @param account the account to add the secret to
* @return the new TOTP secret
Expand Down Expand Up @@ -176,8 +181,8 @@ public boolean verifyTotp(IamAccount account, String totp) throws IamTotpMfaInva
}

IamTotpMfa totpMfa = totpMfaOptional.get();
String mfaSecret = IamTotpMfaEncryptionAndDecryptionUtil.decryptSecret(
totpMfa.getSecret(), iamTotpMfaProperties.getPasswordToEncryptOrDecrypt());
String mfaSecret = IamTotpMfaEncryptionAndDecryptionUtil.decryptSecret(totpMfa.getSecret(),
iamTotpMfaProperties.getPasswordToEncryptOrDecrypt());

// Verify provided TOTP
if (codeVerifier.isValidCode(mfaSecret, totp)) {
Expand Down
Loading
Loading