Skip to content

Commit

Permalink
Merge branch 'provisioning/patch'
Browse files Browse the repository at this point in the history
* provisioning/patch:
  Removed JaCoCo maven plugin
  Added JaCoCo maven plugin
  Fixed missing user delete
  Fixing tests
  Fixed unique constraint on iam_ssh_key and improved patch-replace tests
  Bunch if fixes and added V6 db update
  Fixed gitignore
  Added x509 provisioning tests
  Fixed patch-replace for x509 certificates and ssh key display and primary
  Cosmetic fix
  Cleared empty indigouser json field
  fixed patch add request with duplicated id
  Added PATCH add/remove samlId
  Cosmetic fixes
  Added tests on ssh key patch and few adjustments
  ssh key patch remove fixed to allow only display or fingerprint
  Added sshkey scim add/remove support
  • Loading branch information
andreaceccanti committed Jul 11, 2016
2 parents 7df7934 + 049bd6f commit 2910079
Show file tree
Hide file tree
Showing 48 changed files with 2,668 additions and 480 deletions.
1 change: 1 addition & 0 deletions iam-login-service/.gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
/target/
.factorypath
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler;

import it.infn.mw.iam.api.scim.exception.IllegalArgumentException;
import it.infn.mw.iam.api.scim.exception.ScimException;
import it.infn.mw.iam.api.scim.exception.ScimPatchOperationNotSupported;
import it.infn.mw.iam.api.scim.exception.ScimResourceExistsException;
import it.infn.mw.iam.api.scim.exception.ScimResourceNotFoundException;
Expand Down Expand Up @@ -69,6 +70,14 @@ public ScimErrorResponse handleInvalidArgumentException(ScimPatchOperationNotSup
return buildErrorResponse(HttpStatus.BAD_REQUEST, e.getMessage());
}

@ResponseStatus(code = HttpStatus.BAD_REQUEST)
@ExceptionHandler(ScimException.class)
@ResponseBody
public ScimErrorResponse handleInvalidArgumentException(ScimException e) {

return buildErrorResponse(HttpStatus.BAD_REQUEST, e.getMessage());
}

private ScimErrorResponse buildErrorResponse(HttpStatus status, String message) {

return new ScimErrorResponse(status.value(), message);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,50 +1,31 @@
package it.infn.mw.iam.api.scim.converter;

import java.util.Optional;

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

import it.infn.mw.iam.api.scim.model.ScimOidcId;
import it.infn.mw.iam.persistence.model.IamOidcId;
import it.infn.mw.iam.persistence.repository.IamOidcIdRepository;

@Service
public class OidcIdConverter implements Converter<ScimOidcId, IamOidcId> {

private final IamOidcIdRepository oidcIdRepository;

@Autowired
public OidcIdConverter(IamOidcIdRepository oidcIdRepository) {

this.oidcIdRepository = oidcIdRepository;
}

@Override
public IamOidcId fromScim(ScimOidcId scim) {

/* Try loading from persistence the OpenID Connect id */
Optional<IamOidcId> oidcId = oidcIdRepository.findByIssuerAndSubject(scim.issuer, scim.subject);

if (oidcId.isPresent()) {
return oidcId.get();
}
IamOidcId oidcId = new IamOidcId();
oidcId.setIssuer(scim.getIssuer());
oidcId.setSubject(scim.getSubject());
oidcId.setAccount(null);

/* It's a new OpenID Connect id */
IamOidcId oidcIdNew = new IamOidcId();
oidcIdNew.setIssuer(scim.issuer);
oidcIdNew.setSubject(scim.subject);
oidcIdNew.setAccount(null);
return oidcIdNew;
return oidcId;
}

@Override
public ScimOidcId toScim(IamOidcId entity) {

ScimOidcId.Builder builder =
ScimOidcId.builder().issuer(entity.getIssuer()).subject(entity.getSubject());
ScimOidcId.Builder builder = ScimOidcId.builder()
.issuer(entity.getIssuer())
.subject(entity.getSubject());

return builder.build();
}

}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package it.infn.mw.iam.api.scim.converter;

import org.springframework.stereotype.Service;

import it.infn.mw.iam.api.scim.model.ScimSamlId;
import it.infn.mw.iam.persistence.model.IamSamlId;

@Service
public class SamlIdConverter implements Converter<ScimSamlId, IamSamlId> {

@Override
public IamSamlId fromScim(ScimSamlId scim) {

IamSamlId samlId = new IamSamlId();
samlId.setIdpId(scim.getIdpId());
samlId.setUserId(scim.getUserId());
samlId.setAccount(null);

return samlId;
}

@Override
public ScimSamlId toScim(IamSamlId entity) {

return ScimSamlId.builder().idpId(entity.getIdpId()).userId(entity.getUserId()).build();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package it.infn.mw.iam.api.scim.converter;

import org.springframework.stereotype.Service;

import it.infn.mw.iam.api.scim.model.ScimSshKey;
import it.infn.mw.iam.persistence.model.IamSshKey;

@Service
public class SshKeyConverter implements Converter<ScimSshKey, IamSshKey> {

@Override
public IamSshKey fromScim(ScimSshKey scim) {

IamSshKey sshKey = new IamSshKey();
sshKey.setLabel(scim.getDisplay());
sshKey.setFingerprint(scim.getFingerprint());
sshKey.setValue(scim.getValue());

if (scim.isPrimary() != null) {
sshKey.setPrimary(scim.isPrimary());
} else {
sshKey.setPrimary(false);
}

sshKey.setAccount(null);

return sshKey;
}

@Override
public ScimSshKey toScim(IamSshKey entity) {

ScimSshKey.Builder builder = ScimSshKey.builder()
.display(entity.getLabel())
.primary(entity.isPrimary())
.value(entity.getValue())
.fingerprint(entity.getFingerprint());

return builder.build();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,41 +3,47 @@
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import it.infn.mw.iam.api.scim.exception.ScimResourceExistsException;
import it.infn.mw.iam.api.scim.exception.ScimException;
import it.infn.mw.iam.api.scim.model.ScimAddress;
import it.infn.mw.iam.api.scim.model.ScimEmail;
import it.infn.mw.iam.api.scim.model.ScimGroupRef;
import it.infn.mw.iam.api.scim.model.ScimIndigoUser;
import it.infn.mw.iam.api.scim.model.ScimMeta;
import it.infn.mw.iam.api.scim.model.ScimName;
import it.infn.mw.iam.api.scim.model.ScimOidcId;
import it.infn.mw.iam.api.scim.model.ScimUser;
import it.infn.mw.iam.api.scim.model.ScimX509Certificate;
import it.infn.mw.iam.persistence.model.IamAccount;
import it.infn.mw.iam.persistence.model.IamGroup;
import it.infn.mw.iam.persistence.model.IamOidcId;
import it.infn.mw.iam.persistence.model.IamSamlId;
import it.infn.mw.iam.persistence.model.IamSshKey;
import it.infn.mw.iam.persistence.model.IamUserInfo;
import it.infn.mw.iam.persistence.model.IamX509Certificate;
import it.infn.mw.iam.util.ssh.InvalidSshKeyException;
import it.infn.mw.iam.util.ssh.RSAPublicKeyUtils;

@Service
public class UserConverter implements Converter<ScimUser, IamAccount> {

private final ScimResourceLocationProvider resourceLocationProvider;

private final AddressConverter addressConverter;
private final X509CertificateConverter certificateConverter;

private final X509CertificateConverter x509CertificateConverter;
private final OidcIdConverter oidcIdConverter;
private final SshKeyConverter sshKeyConverter;
private final SamlIdConverter samlIdConverter;


@Autowired
public UserConverter(ScimResourceLocationProvider rlp, AddressConverter ac,
X509CertificateConverter cc, OidcIdConverter oidc) {
public UserConverter(ScimResourceLocationProvider rlp, X509CertificateConverter x509cc,
AddressConverter ac, OidcIdConverter oidc, SshKeyConverter sshc, SamlIdConverter samlc) {

this.resourceLocationProvider = rlp;
this.addressConverter = ac;
this.certificateConverter = cc;
this.x509CertificateConverter = x509cc;
this.oidcIdConverter = oidc;
this.sshKeyConverter = sshc;
this.samlIdConverter = samlc;
}

@Override
Expand Down Expand Up @@ -66,27 +72,67 @@ public IamAccount fromScim(ScimUser scimUser) {

account.setUserInfo(userInfo);

if (scimUser.getAddresses() != null && scimUser.getAddresses().size() > 0) {
if (scimUser.hasAddresses()) {

userInfo.setAddress(addressConverter.fromScim(scimUser.getAddresses().get(0)));

}

if (scimUser.getIndigoUser() != null) {
for (ScimOidcId oidcId : scimUser.getIndigoUser().getOidcIds()) {
if (scimUser.hasX509Certificates()) {

scimUser.getX509Certificates().forEach(scimCert -> {
IamX509Certificate iamCert = x509CertificateConverter.fromScim(scimCert);
iamCert.setAccount(account);
account.getX509Certificates().add(iamCert);
});
}

if (scimUser.hasOidcIds()) {

scimUser.getIndigoUser().getOidcIds().forEach(oidcId -> {

IamOidcId iamOidcId = oidcIdConverter.fromScim(oidcId);
iamOidcId.setAccount(account);
account.getOidcIds().add(iamOidcId);

});
}

if (iamOidcId.getAccount() != null) {
if (account.getUuid() != iamOidcId.getAccount().getUuid()) {
if (scimUser.hasSshKeys()) {

String errorMessage = String.format("OIDC id %s,%s is already mapped to another user",
iamOidcId.getIssuer(), iamOidcId.getSubject());
scimUser.getIndigoUser().getSshKeys().forEach(sshKey -> {

throw new ScimResourceExistsException(errorMessage);
IamSshKey iamSshKey = sshKeyConverter.fromScim(sshKey);

if (iamSshKey.getFingerprint() == null && iamSshKey.getValue() != null) {

try {
iamSshKey.setFingerprint(RSAPublicKeyUtils.getSHA256Fingerprint(iamSshKey.getValue()));
} catch (InvalidSshKeyException e) {
throw new ScimException(e.getMessage());
}
}
account.addOidcId(iamOidcId);
}

iamSshKey.setAccount(account);

if (iamSshKey.getLabel() == null) {

iamSshKey.setLabel(account.getUsername() + "'s personal ssh key");
}

account.getSshKeys().add(iamSshKey);
});
}

if (scimUser.hasSamlIds()) {

scimUser.getIndigoUser().getSamlIds().forEach(samlId -> {

IamSamlId iamSamlId = samlIdConverter.fromScim(samlId);
iamSamlId.setAccount(account);
account.getSamlIds().add(iamSamlId);

});
}

return account;
Expand Down Expand Up @@ -118,15 +164,10 @@ public ScimUser toScim(IamAccount entity) {
builder.addAddress(address);
}

for (IamGroup group : entity.getGroups()) {

builder.addGroup(getScimGroupRef(group));
}
entity.getGroups().forEach(group -> builder.addGroupRef(getScimGroupRef(group)));
entity.getX509Certificates()
.forEach(cert -> builder.addX509Certificate(x509CertificateConverter.toScim(cert)));

for (IamX509Certificate cert : entity.getX509Certificates()) {

builder.addX509Certificate(getScimX509Certificate(cert));
}
return builder.build();
}

Expand Down Expand Up @@ -156,13 +197,14 @@ private ScimIndigoUser getScimIndigoUser(IamAccount entity) {

ScimIndigoUser.Builder indigoUserBuilder = new ScimIndigoUser.Builder();

for (IamOidcId oidcId : entity.getOidcIds()) {
ScimOidcId scimOidcid =
new ScimOidcId.Builder().issuer(oidcId.getIssuer()).subject(oidcId.getSubject()).build();
entity.getOidcIds()
.forEach(oidcId -> indigoUserBuilder.addOidcid(oidcIdConverter.toScim(oidcId)));

indigoUserBuilder.addOidcid(scimOidcid);
entity.getSshKeys()
.forEach(sshKey -> indigoUserBuilder.addSshKey(sshKeyConverter.toScim(sshKey)));

}
entity.getSamlIds()
.forEach(samlId -> indigoUserBuilder.addSamlId(samlIdConverter.toScim(samlId)));

ScimIndigoUser indigoUser = indigoUserBuilder.build();

Expand All @@ -186,9 +228,4 @@ private ScimAddress getScimAddress(IamAccount entity) {
}
return null;
}

private ScimX509Certificate getScimX509Certificate(IamX509Certificate cert) {

return certificateConverter.toScim(cert);
}
}
Loading

0 comments on commit 2910079

Please sign in to comment.