diff --git a/felles/abac-kontekst/pom.xml b/felles/abac-kontekst/pom.xml index 1f9e4e0c9..0da7b97ef 100644 --- a/felles/abac-kontekst/pom.xml +++ b/felles/abac-kontekst/pom.xml @@ -14,17 +14,13 @@ - jakarta.enterprise - jakarta.enterprise.cdi-api + no.nav.foreldrepenger.felles.integrasjon + felles-integrasjon-rest-klient no.nav.foreldrepenger.felles felles-kontekst - - no.nav.foreldrepenger.felles - felles-oidc - no.nav.foreldrepenger.felles felles-abac diff --git a/felles/abac-kontekst/src/main/java/no/nav/foreldrepenger/sikkerhet/abac/KontekstTokenProvider.java b/felles/abac-kontekst/src/main/java/no/nav/foreldrepenger/sikkerhet/abac/KontekstTokenProvider.java index abf8fdb67..eb61837ea 100644 --- a/felles/abac-kontekst/src/main/java/no/nav/foreldrepenger/sikkerhet/abac/KontekstTokenProvider.java +++ b/felles/abac-kontekst/src/main/java/no/nav/foreldrepenger/sikkerhet/abac/KontekstTokenProvider.java @@ -1,10 +1,14 @@ package no.nav.foreldrepenger.sikkerhet.abac; +import java.util.Set; +import java.util.UUID; + import jakarta.enterprise.context.Dependent; + import no.nav.vedtak.sikkerhet.abac.TokenProvider; +import no.nav.vedtak.sikkerhet.kontekst.AnsattGruppe; import no.nav.vedtak.sikkerhet.kontekst.DefaultRequestKontekstProvider; import no.nav.vedtak.sikkerhet.kontekst.IdentType; -import no.nav.vedtak.sikkerhet.kontekst.RequestKontekst; import no.nav.vedtak.sikkerhet.kontekst.RequestKontekstProvider; import no.nav.vedtak.sikkerhet.oidc.token.OpenIDToken; @@ -27,4 +31,14 @@ public IdentType getIdentType() { public OpenIDToken openIdToken() { return PROVIDER.getToken(); } + + @Override + public UUID getOid() { + return PROVIDER.getOid(); + } + + @Override + public Set getAnsattGrupper() { + return PROVIDER.getAnsattGrupper(); + } } diff --git a/felles/abac-kontekst/src/main/java/no/nav/foreldrepenger/sikkerhet/populasjon/TilgangKlient.java b/felles/abac-kontekst/src/main/java/no/nav/foreldrepenger/sikkerhet/populasjon/TilgangKlient.java new file mode 100644 index 000000000..e69c4ee24 --- /dev/null +++ b/felles/abac-kontekst/src/main/java/no/nav/foreldrepenger/sikkerhet/populasjon/TilgangKlient.java @@ -0,0 +1,58 @@ +package no.nav.foreldrepenger.sikkerhet.populasjon; + +import java.net.URI; + +import jakarta.enterprise.context.ApplicationScoped; +import jakarta.ws.rs.core.UriBuilder; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import no.nav.vedtak.felles.integrasjon.rest.FpApplication; +import no.nav.vedtak.felles.integrasjon.rest.RestClient; +import no.nav.vedtak.felles.integrasjon.rest.RestClientConfig; +import no.nav.vedtak.felles.integrasjon.rest.RestConfig; +import no.nav.vedtak.felles.integrasjon.rest.RestRequest; +import no.nav.vedtak.felles.integrasjon.rest.TokenFlow; +import no.nav.vedtak.sikkerhet.abac.policy.Tilgangsvurdering; +import no.nav.vedtak.sikkerhet.populasjon.PopulasjonEksternRequest; +import no.nav.vedtak.sikkerhet.populasjon.PopulasjonInternRequest; +import no.nav.vedtak.sikkerhet.populasjon.PopulasjonKlient; + +@ApplicationScoped +@RestClientConfig(tokenConfig = TokenFlow.AZUREAD_CC, application = FpApplication.FPTILGANG) +public class TilgangKlient implements PopulasjonKlient { + + private static final Logger LOG = LoggerFactory.getLogger(TilgangKlient.class); + + private final URI internBrukerUri; + + private final URI eksternBrukerUri; + private final RestClient klient; + private final RestConfig restConfig; + + public TilgangKlient() { + this.klient = RestClient.client(); + this.restConfig = RestConfig.forClient(this.getClass()); + this.internBrukerUri = UriBuilder.fromUri(restConfig.fpContextPath()) + .path("/api/populasjon/internbruker") + .build(); + this.eksternBrukerUri = UriBuilder.fromUri(restConfig.fpContextPath()) + .path("/api/populasjon/eksternbruker") + .build(); + } + + @Override + public Tilgangsvurdering vurderTilgang(PopulasjonInternRequest request) { + var rrequest = RestRequest.newPOSTJson(request, internBrukerUri, restConfig); + //return klient.send(rrequest, Tilgangsvurdering.class); + return Tilgangsvurdering.godkjenn(); + } + + @Override + public Tilgangsvurdering vurderTilgang(PopulasjonEksternRequest request) { + var rrequest = RestRequest.newPOSTJson(request, eksternBrukerUri, restConfig); + //return klient.send(rrequest, Tilgangsvurdering.class); + return Tilgangsvurdering.godkjenn(); + } +} diff --git a/felles/abac/src/main/java/no/nav/vedtak/sikkerhet/abac/BeskyttetRessursInterceptor.java b/felles/abac/src/main/java/no/nav/vedtak/sikkerhet/abac/BeskyttetRessursInterceptor.java index 2365a2b5f..96b57f029 100644 --- a/felles/abac/src/main/java/no/nav/vedtak/sikkerhet/abac/BeskyttetRessursInterceptor.java +++ b/felles/abac/src/main/java/no/nav/vedtak/sikkerhet/abac/BeskyttetRessursInterceptor.java @@ -70,7 +70,7 @@ private Object ikkeTilgang(Tilgangsbeslutning beslutning) { if (!erSystembrukerKall(beslutning.beskyttetRessursAttributter())) { abacAuditlogger.loggDeny(tokenProvider.getUid(), beslutning); } else { - LOG.info("ABAC AVSLAG SYSTEMBRUKER {}", beslutning.beskyttetRessursAttributter().getUserId()); + LOG.info("ABAC AVSLAG SYSTEMBRUKER {}", beslutning.beskyttetRessursAttributter().getBrukerId()); } switch (beslutning.beslutningKode()) { @@ -83,8 +83,7 @@ private Object ikkeTilgang(Tilgangsbeslutning beslutning) { private boolean erSystembrukerKall(BeskyttetRessursAttributter beskyttetRessursAttributter) { return Optional.ofNullable(beskyttetRessursAttributter) - .map(BeskyttetRessursAttributter::getToken) - .map(Token::getIdentType) + .map(BeskyttetRessursAttributter::getIdentType) .filter(IdentType::erSystem) .isPresent(); } @@ -94,10 +93,13 @@ private BeskyttetRessursAttributter hentBeskyttetRessursAttributter(InvocationCo var method = invocationContext.getMethod(); var beskyttetRessurs = method.getAnnotation(BeskyttetRessurs.class); - var token = Token.withOidcToken(tokenProvider.openIdToken(), tokenProvider.getUid(), tokenProvider.getIdentType()); + var token = Token.withOidcToken(tokenProvider.openIdToken()); return BeskyttetRessursAttributter.builder() - .medUserId(tokenProvider.getUid()) + .medBrukerId(tokenProvider.getUid()) + .medBrukerOid(tokenProvider.getOid()) + .medIdentType(tokenProvider.getIdentType()) + .medAnsattGrupper(tokenProvider.getAnsattGrupper()) .medToken(token) .medActionType(beskyttetRessurs.actionType()) .medAvailabilityType(beskyttetRessurs.availabilityType()) diff --git a/felles/abac/src/main/java/no/nav/vedtak/sikkerhet/abac/PdpRequestBuilder.java b/felles/abac/src/main/java/no/nav/vedtak/sikkerhet/abac/PdpRequestBuilder.java index c9ce6decf..2a82c17db 100644 --- a/felles/abac/src/main/java/no/nav/vedtak/sikkerhet/abac/PdpRequestBuilder.java +++ b/felles/abac/src/main/java/no/nav/vedtak/sikkerhet/abac/PdpRequestBuilder.java @@ -1,7 +1,15 @@ package no.nav.vedtak.sikkerhet.abac; +import no.nav.vedtak.sikkerhet.abac.internal.BeskyttetRessursAttributter; import no.nav.vedtak.sikkerhet.abac.pdp.AppRessursData; +import no.nav.vedtak.sikkerhet.abac.policy.Tilgangsvurdering; +/** + * Dette grensesnittet må implementeres av alle applikasjoner: + * - Alle må implementere lagAppRessursData + * - De applikasjonene (tilbake, inntektsmelding) som skal kalle K9 sin PDP/abac må implementere abacDomene + * - + */ public interface PdpRequestBuilder { default String abacDomene() { @@ -9,4 +17,23 @@ default String abacDomene() { } AppRessursData lagAppRessursData(AbacDataAttributter dataAttributter); + + // Trenger egentlig bare sette BEHANDLING_STATUS + FAGSAK_STATUS i tilfelle FAGSAK / UPDATE for skrivetilgangs-sjekk + default AppRessursData lagAppRessursDataForSystembruker(AbacDataAttributter dataAttributter) { + return lagAppRessursData(dataAttributter); + } + + + default boolean skalVurdereTilgangLokalt(BeskyttetRessursAttributter beskyttetRessursAttributter, AppRessursData appRessursData) { + return false; + } + + // Fortsette med vanlig tilgangskontroll eller bruke svar fra lokal vurdering + default boolean kunLokalVurdering(BeskyttetRessursAttributter beskyttetRessursAttributter, AppRessursData appRessursData) { + return false; + } + + default Tilgangsvurdering vurderTilgangLokalt(BeskyttetRessursAttributter beskyttetRessursAttributter, AppRessursData appRessursData) { + throw new IllegalArgumentException("Utviklerfeil: viser lokal tilgangsvurdering, men ikke implementert metode"); + } } diff --git a/felles/abac/src/main/java/no/nav/vedtak/sikkerhet/abac/PepImpl.java b/felles/abac/src/main/java/no/nav/vedtak/sikkerhet/abac/PepImpl.java index 8c07f3a35..175a56128 100644 --- a/felles/abac/src/main/java/no/nav/vedtak/sikkerhet/abac/PepImpl.java +++ b/felles/abac/src/main/java/no/nav/vedtak/sikkerhet/abac/PepImpl.java @@ -3,99 +3,151 @@ import static no.nav.vedtak.sikkerhet.abac.AbacResultat.AVSLÅTT_ANNEN_ÅRSAK; import static no.nav.vedtak.sikkerhet.abac.AbacResultat.GODKJENT; +import java.util.HashSet; +import java.util.LinkedHashSet; +import java.util.Objects; + import jakarta.enterprise.context.ApplicationScoped; import jakarta.enterprise.inject.Default; import jakarta.inject.Inject; -import no.nav.foreldrepenger.konfig.Cluster; -import no.nav.foreldrepenger.konfig.Environment; -import no.nav.vedtak.sikkerhet.abac.beskyttet.AvailabilityType; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import no.nav.vedtak.sikkerhet.abac.beskyttet.ActionType; import no.nav.vedtak.sikkerhet.abac.internal.BeskyttetRessursAttributter; import no.nav.vedtak.sikkerhet.abac.pdp.AppRessursData; +import no.nav.vedtak.sikkerhet.abac.policy.EksternBrukerPolicies; import no.nav.vedtak.sikkerhet.abac.policy.ForeldrepengerAttributter; +import no.nav.vedtak.sikkerhet.abac.policy.InternBrukerPolicies; +import no.nav.vedtak.sikkerhet.abac.policy.SystemressursPolicies; +import no.nav.vedtak.sikkerhet.abac.policy.Tilgangsvurdering; +import no.nav.vedtak.sikkerhet.kontekst.AnsattGruppe; import no.nav.vedtak.sikkerhet.kontekst.IdentType; -import no.nav.vedtak.sikkerhet.oidc.config.AzureProperty; -import no.nav.vedtak.sikkerhet.oidc.config.OpenIDProvider; - +import no.nav.vedtak.sikkerhet.populasjon.PopulasjonEksternRequest; +import no.nav.vedtak.sikkerhet.populasjon.PopulasjonInternRequest; +import no.nav.vedtak.sikkerhet.populasjon.PopulasjonKlient; + +/** + * Dette er strengt tatt PDP (eller en PDP-proxy før kall til Abac). + * Interceptor er strengt tatt PEP (policy enforcement point) + */ @Default @ApplicationScoped public class PepImpl implements Pep { + + private static final Logger LOG = LoggerFactory.getLogger(PepImpl.class); private static final String PIP = ForeldrepengerAttributter.RESOURCE_TYPE_INTERNAL_PIP; - private static final Environment ENV = Environment.current(); private PdpKlient pdpKlient; - private PdpRequestBuilder builder; + private PopulasjonKlient populasjonKlient; + private PdpRequestBuilder pdpRequestBuilder; - private String preAuthorized; - private Cluster residentCluster; - private String residentNamespace; PepImpl() { // CDI proxy } @Inject - public PepImpl(PdpKlient pdpKlient, PdpRequestBuilder pdpRequestBuilder) { + public PepImpl(PdpKlient pdpKlient, PopulasjonKlient populasjonKlient, PdpRequestBuilder pdpRequestBuilder) { this.pdpKlient = pdpKlient; - this.builder = pdpRequestBuilder; - this.preAuthorized = ENV.getProperty(AzureProperty.AZURE_APP_PRE_AUTHORIZED_APPS.name()); // eg json array av objekt("name", "clientId") - this.residentCluster = ENV.getCluster(); - this.residentNamespace = ENV.namespace(); + this.populasjonKlient = populasjonKlient; + this.pdpRequestBuilder = pdpRequestBuilder; } @Override public Tilgangsbeslutning vurderTilgang(BeskyttetRessursAttributter beskyttetRessursAttributter) { - var appRessurser = builder.lagAppRessursData(beskyttetRessursAttributter.getDataAttributter()); + var appRessurser = pdpRequestBuilder.lagAppRessursData(beskyttetRessursAttributter.getDataAttributter()); - if (kanForetaLokalTilgangsbeslutning(beskyttetRessursAttributter.getToken())) { + if (IdentType.Systemressurs.equals(beskyttetRessursAttributter.getIdentType())) { return vurderLokalTilgang(beskyttetRessursAttributter, appRessurser); } else if (PIP.equals(beskyttetRessursAttributter.getResourceType())) { // pip tilgang bør vurderes kun lokalt return new Tilgangsbeslutning(AVSLÅTT_ANNEN_ÅRSAK, beskyttetRessursAttributter, appRessurser); } - return pdpKlient.forespørTilgang(beskyttetRessursAttributter, builder.abacDomene(), appRessurser); + var pdpResultat = pdpKlient.forespørTilgang(beskyttetRessursAttributter, pdpRequestBuilder.abacDomene(), appRessurser); + sammenlignOgLogg(beskyttetRessursAttributter, appRessurser, pdpResultat.beslutningKode()); + return pdpResultat; } protected Tilgangsbeslutning vurderLokalTilgang(BeskyttetRessursAttributter beskyttetRessursAttributter, AppRessursData appRessursData) { - var token = beskyttetRessursAttributter.getToken(); - var harTilgang = harTilgang(token.getBrukerId(), beskyttetRessursAttributter.getAvailabilityType()); + var harTilgang = SystemressursPolicies.riktigClusterNamespacePreAuth(beskyttetRessursAttributter.getBrukerId(), beskyttetRessursAttributter.getAvailabilityType()); return new Tilgangsbeslutning(harTilgang ? GODKJENT : AVSLÅTT_ANNEN_ÅRSAK, beskyttetRessursAttributter, appRessursData); } - // AzureAD CC kommer med sub som ikke ikke en bruker med vanlige AD-grupper og roller - // Token kan utvides med roles og groups - // Kan legge inn filter på claims/roles intern og/eller ekstern. - private boolean kanForetaLokalTilgangsbeslutning(Token token) { - var identType = token.getIdentType(); - var consumer = token.getBrukerId(); - - return OpenIDProvider.AZUREAD.equals(token.getOpenIDProvider()) && - IdentType.Systemressurs.equals(identType) && - consumer != null && - preAuthorized != null; + private void sammenlignOgLogg(BeskyttetRessursAttributter beskyttetRessursAttributter, AppRessursData appRessursData, AbacResultat resultat) { + try { + var lokalt = forespørTilgang(beskyttetRessursAttributter, appRessursData); + if (Objects.equals(lokalt.abacResultat(), resultat)) { + LOG.info("FPEGENTILGANG: samme svar"); + } else { + LOG.info("FPEGENTILGANG: ulikt svar - gammel {} ny {}", resultat, lokalt.abacResultat()); + } + } catch (Exception e) { + LOG.info("FPEGENTILGANG: feil", e); + } } - private boolean harTilgang(String consumerId, AvailabilityType availabilityType) { - if (consumerId == null || !preAuthorized.contains(consumerId)) { - return false; + // Skal kunne kalles fra evt subklasser av PepImpl + protected Tilgangsvurdering forespørTilgang(BeskyttetRessursAttributter beskyttetRessursAttributter, AppRessursData appRessursData) { + if (ActionType.DUMMY.equals(beskyttetRessursAttributter.getActionType())) { + return Tilgangsvurdering.avslåGenerell("ActionType DUMMY ikke støttet"); } + return switch (beskyttetRessursAttributter.getIdentType()) { + case Systemressurs -> SystemressursPolicies.vurderTilgang(beskyttetRessursAttributter, appRessursData); + case InternBruker -> forespørTilgangInternBruker(beskyttetRessursAttributter, appRessursData); + case EksternBruker -> forespørTilgangEksternBruker(beskyttetRessursAttributter, appRessursData); + default -> Tilgangsvurdering.avslåGenerell("Ukjent IdentType"); + }; + } - if (erISammeKlusterKlasseOgNamespace(consumerId)) { - return true; + private Tilgangsvurdering forespørTilgangInternBruker(BeskyttetRessursAttributter beskyttetRessursAttributter, AppRessursData appRessursData) { + HashSet kreverGrupper = new LinkedHashSet<>(); + if (pdpRequestBuilder.skalVurdereTilgangLokalt(beskyttetRessursAttributter, appRessursData)) { + var lokalVurdering = pdpRequestBuilder.vurderTilgangLokalt(beskyttetRessursAttributter, appRessursData); + if (!lokalVurdering.fikkTilgang() || pdpRequestBuilder.kunLokalVurdering(beskyttetRessursAttributter, appRessursData)) { + return lokalVurdering; + } + kreverGrupper.addAll(lokalVurdering.kreverGrupper()); } - - return AvailabilityType.ALL.equals(availabilityType); + var fagtilgang = InternBrukerPolicies.vurderTilgang(beskyttetRessursAttributter, appRessursData); + if (!fagtilgang.fikkTilgang()) { + return fagtilgang; + } + kreverGrupper.addAll(fagtilgang.kreverGrupper()); + if (kreverGrupper.isEmpty() && appRessursData.getFødselsnumre().isEmpty() && appRessursData.getAktørIdSet().isEmpty()) { + // Ikke noe å sjekke for populasjonstilgang + return Tilgangsvurdering.godkjenn(); + } + var popRequest = new PopulasjonInternRequest(beskyttetRessursAttributter.getBrukerOid(), kreverGrupper, + appRessursData.getFødselsnumre(), appRessursData.getAktørIdSet()); + var popTilgang = populasjonKlient.vurderTilgang(popRequest); + if (popTilgang == null) { + return Tilgangsvurdering.avslåGenerell("Feil ved kontakt med tilgangskontrll"); + } + return popTilgang; } - private boolean erISammeKlusterKlasseOgNamespace(String consumer) { - var elementer = consumer.split(":"); - if (elementer.length < 2) { - return false; + private Tilgangsvurdering forespørTilgangEksternBruker(BeskyttetRessursAttributter beskyttetRessursAttributter, AppRessursData appRessursData) { + if (pdpRequestBuilder.skalVurdereTilgangLokalt(beskyttetRessursAttributter, appRessursData)) { + var lokalVurdering = pdpRequestBuilder.vurderTilgangLokalt(beskyttetRessursAttributter, appRessursData); + if (!lokalVurdering.fikkTilgang() || pdpRequestBuilder.kunLokalVurdering(beskyttetRessursAttributter, appRessursData)) { + return lokalVurdering; + } } - - var consumerCluster = elementer[0]; - var consumerNamespace = elementer[1]; - return residentCluster.isSameClass(Cluster.of(consumerCluster)) && residentNamespace.equals(consumerNamespace); + var fagtilgang = EksternBrukerPolicies.vurderTilgang(beskyttetRessursAttributter, appRessursData); + if (!fagtilgang.fikkTilgang()) { + return fagtilgang; + } + // Ingen early return - skal sjekke alder på bruker. Kanskje populere attributt ved innsending. + var popRequest = new PopulasjonEksternRequest(beskyttetRessursAttributter.getBrukerId(), + appRessursData.getFødselsnumre(), appRessursData.getAktørIdSet()); + var popTilgang = populasjonKlient.vurderTilgang(popRequest); + if (popTilgang == null) { + return Tilgangsvurdering.avslåGenerell("Feil ved kontakt med tilgangskontrll"); + } + return popTilgang; } + } diff --git a/felles/abac/src/main/java/no/nav/vedtak/sikkerhet/abac/PopulasjonsTilgang.java b/felles/abac/src/main/java/no/nav/vedtak/sikkerhet/abac/PopulasjonsTilgang.java new file mode 100644 index 000000000..17cac6219 --- /dev/null +++ b/felles/abac/src/main/java/no/nav/vedtak/sikkerhet/abac/PopulasjonsTilgang.java @@ -0,0 +1,11 @@ +package no.nav.vedtak.sikkerhet.abac; + +import no.nav.vedtak.sikkerhet.abac.internal.BeskyttetRessursAttributter; +import no.nav.vedtak.sikkerhet.abac.pdp.AppRessursData; +import no.nav.vedtak.sikkerhet.abac.policy.Tilgangsvurdering; + +public interface PopulasjonsTilgang { + + Tilgangsvurdering vurderTilgang(BeskyttetRessursAttributter beskyttetRessursAttributter, AppRessursData appRessursData); + +} diff --git a/felles/abac/src/main/java/no/nav/vedtak/sikkerhet/abac/Token.java b/felles/abac/src/main/java/no/nav/vedtak/sikkerhet/abac/Token.java index e8ab44a70..d8ce03353 100644 --- a/felles/abac/src/main/java/no/nav/vedtak/sikkerhet/abac/Token.java +++ b/felles/abac/src/main/java/no/nav/vedtak/sikkerhet/abac/Token.java @@ -8,7 +8,6 @@ import org.jose4j.jwt.consumer.JwtConsumerBuilder; import no.nav.vedtak.exception.TekniskException; -import no.nav.vedtak.sikkerhet.kontekst.IdentType; import no.nav.vedtak.sikkerhet.oidc.config.OpenIDProvider; import no.nav.vedtak.sikkerhet.oidc.token.OpenIDToken; @@ -24,22 +23,15 @@ public enum TokenType { TOKENX; } - private final String token; private final TokenType tokenType; private final OpenIDToken openIDToken; - private final String brukerId; - private final IdentType identType; - - private Token(String token, TokenType tokenType, OpenIDToken openIDToken, String brukerId, IdentType identType) { - this.token = token; + private Token(TokenType tokenType, OpenIDToken openIDToken) { this.tokenType = tokenType; this.openIDToken = openIDToken; - this.brukerId = brukerId; - this.identType = identType; } - public static Token withOidcToken(OpenIDToken token, String brukerId, IdentType identType) { - return new Token(null, utledTokenType(token), token, brukerId, identType); + public static Token withOidcToken(OpenIDToken token) { + return new Token(utledTokenType(token), token); } public TokenType getTokenType() { @@ -50,14 +42,6 @@ public OpenIDProvider getOpenIDProvider() { return Optional.ofNullable(openIDToken).map(OpenIDToken::provider).orElse(null); } - public String getBrukerId() { - return brukerId; - } - - public IdentType getIdentType() { - return identType; - } - private static TokenType utledTokenType(OpenIDToken token) { return switch (token.provider()) { case AZUREAD -> TokenType.OIDC; diff --git a/felles/abac/src/main/java/no/nav/vedtak/sikkerhet/abac/TokenProvider.java b/felles/abac/src/main/java/no/nav/vedtak/sikkerhet/abac/TokenProvider.java index bd042fefa..03429a779 100644 --- a/felles/abac/src/main/java/no/nav/vedtak/sikkerhet/abac/TokenProvider.java +++ b/felles/abac/src/main/java/no/nav/vedtak/sikkerhet/abac/TokenProvider.java @@ -1,5 +1,9 @@ package no.nav.vedtak.sikkerhet.abac; +import java.util.Set; +import java.util.UUID; + +import no.nav.vedtak.sikkerhet.kontekst.AnsattGruppe; import no.nav.vedtak.sikkerhet.kontekst.IdentType; import no.nav.vedtak.sikkerhet.oidc.token.OpenIDToken; @@ -28,4 +32,18 @@ public interface TokenProvider { */ OpenIDToken openIdToken(); + /** + * Azure OID til brukeren. Kun satt for innkommende Azure-kall, ellers null + * + * @return brukers oid. + */ + UUID getOid(); + + /** + * Gjenkjente AD-grupper til brukeren. Kun satt for innkommende Azure OBO-kall, ellers tom + * + * @return brukers ansattgrupper. + */ + Set getAnsattGrupper(); + } diff --git a/felles/abac/src/main/java/no/nav/vedtak/sikkerhet/abac/beskyttet/ResourceType.java b/felles/abac/src/main/java/no/nav/vedtak/sikkerhet/abac/beskyttet/ResourceType.java index 4647fc8f4..1229129a5 100644 --- a/felles/abac/src/main/java/no/nav/vedtak/sikkerhet/abac/beskyttet/ResourceType.java +++ b/felles/abac/src/main/java/no/nav/vedtak/sikkerhet/abac/beskyttet/ResourceType.java @@ -4,10 +4,8 @@ import static no.nav.vedtak.sikkerhet.abac.policy.ForeldrepengerAttributter.RESOURCE_TYPE_FP_AVDELINGENHET; import static no.nav.vedtak.sikkerhet.abac.policy.ForeldrepengerAttributter.RESOURCE_TYPE_FP_DRIFT; import static no.nav.vedtak.sikkerhet.abac.policy.ForeldrepengerAttributter.RESOURCE_TYPE_FP_FAGSAK; -import static no.nav.vedtak.sikkerhet.abac.policy.ForeldrepengerAttributter.RESOURCE_TYPE_FP_OPPGAVEKØ; import static no.nav.vedtak.sikkerhet.abac.policy.ForeldrepengerAttributter.RESOURCE_TYPE_FP_OPPGAVESTYRING; import static no.nav.vedtak.sikkerhet.abac.policy.ForeldrepengerAttributter.RESOURCE_TYPE_FP_RISIKOKLASSIFISERING; -import static no.nav.vedtak.sikkerhet.abac.policy.ForeldrepengerAttributter.RESOURCE_TYPE_FP_SAKLISTE; import static no.nav.vedtak.sikkerhet.abac.policy.ForeldrepengerAttributter.RESOURCE_TYPE_FP_UTTAKSPLAN; import static no.nav.vedtak.sikkerhet.abac.policy.ForeldrepengerAttributter.RESOURCE_TYPE_FP_VENTEFRIST; import static no.nav.vedtak.sikkerhet.abac.policy.ForeldrepengerAttributter.RESOURCE_TYPE_INTERNAL_PIP; @@ -22,8 +20,7 @@ public enum ResourceType { // LOS OPPGAVESTYRING_AVDELINGENHET(RESOURCE_TYPE_FP_AVDELINGENHET), OPPGAVESTYRING(RESOURCE_TYPE_FP_OPPGAVESTYRING), - OPPGAVEKØ(RESOURCE_TYPE_FP_OPPGAVEKØ), - SAKLISTE(RESOURCE_TYPE_FP_SAKLISTE), + // OPPGAVEKØ(RESOURCE_TYPE_FP_OPPGAVEKØ), TODO: Vurder om skal brukes for å lese oppgaver for LOS. Nå brukes FAGSAK // Risk RISIKOKLASSIFISERING(RESOURCE_TYPE_FP_RISIKOKLASSIFISERING), // Selvbetjening diff --git a/felles/abac/src/main/java/no/nav/vedtak/sikkerhet/abac/internal/BeskyttetRessursAttributter.java b/felles/abac/src/main/java/no/nav/vedtak/sikkerhet/abac/internal/BeskyttetRessursAttributter.java index 57f2129bf..6afb73cb7 100644 --- a/felles/abac/src/main/java/no/nav/vedtak/sikkerhet/abac/internal/BeskyttetRessursAttributter.java +++ b/felles/abac/src/main/java/no/nav/vedtak/sikkerhet/abac/internal/BeskyttetRessursAttributter.java @@ -1,17 +1,25 @@ package no.nav.vedtak.sikkerhet.abac.internal; +import java.util.LinkedHashSet; import java.util.Objects; +import java.util.Set; +import java.util.UUID; import no.nav.vedtak.sikkerhet.abac.AbacDataAttributter; import no.nav.vedtak.sikkerhet.abac.Token; import no.nav.vedtak.sikkerhet.abac.beskyttet.ActionType; import no.nav.vedtak.sikkerhet.abac.beskyttet.AvailabilityType; import no.nav.vedtak.sikkerhet.abac.beskyttet.ResourceType; +import no.nav.vedtak.sikkerhet.kontekst.AnsattGruppe; +import no.nav.vedtak.sikkerhet.kontekst.IdentType; public class BeskyttetRessursAttributter { - private String userId; + private String brukerId; + private UUID brukerOid; + private IdentType identType; + private Set ansattGrupper = new LinkedHashSet<>(); private ActionType actionType; private String resourceType; private AvailabilityType availabilityType; @@ -24,8 +32,20 @@ public static Builder builder() { return new Builder(); } - public String getUserId() { - return userId; + public String getBrukerId() { + return brukerId; + } + + public IdentType getIdentType() { + return identType; + } + + public UUID getBrukerOid() { + return brukerOid; + } + + public Set getAnsattGrupper() { + return ansattGrupper; } public AvailabilityType getAvailabilityType() { @@ -69,8 +89,23 @@ public Builder() { pdpRequest = new BeskyttetRessursAttributter(); } - public Builder medUserId(String userId) { - pdpRequest.userId = userId; + public Builder medBrukerId(String brukerId) { + pdpRequest.brukerId = brukerId; + return this; + } + + public Builder medBrukerOid(UUID oid) { + pdpRequest.brukerOid = oid; + return this; + } + + public Builder medIdentType(IdentType identType) { + pdpRequest.identType = identType; + return this; + } + + public Builder medAnsattGrupper(Set ansattGrupper) { + pdpRequest.ansattGrupper.addAll(ansattGrupper); return this; } @@ -120,7 +155,7 @@ public BeskyttetRessursAttributter build() { } private void validateBeforeBuild() { - Objects.requireNonNull(pdpRequest.userId, "userId"); + Objects.requireNonNull(pdpRequest.brukerId, "userId"); Objects.requireNonNull(pdpRequest.token, "idToken"); Objects.requireNonNull(pdpRequest.actionType, "actionType"); Objects.requireNonNull(pdpRequest.resourceType, "resourceType"); diff --git a/felles/abac/src/main/java/no/nav/vedtak/sikkerhet/abac/pdp/ForeldrepengerDataKeys.java b/felles/abac/src/main/java/no/nav/vedtak/sikkerhet/abac/pdp/ForeldrepengerDataKeys.java index 38012160d..14ab04c52 100644 --- a/felles/abac/src/main/java/no/nav/vedtak/sikkerhet/abac/pdp/ForeldrepengerDataKeys.java +++ b/felles/abac/src/main/java/no/nav/vedtak/sikkerhet/abac/pdp/ForeldrepengerDataKeys.java @@ -3,6 +3,7 @@ import static no.nav.vedtak.sikkerhet.abac.policy.ForeldrepengerAttributter.RESOURCE_FP_AKSJONSPUNKT_TYPE; import static no.nav.vedtak.sikkerhet.abac.policy.ForeldrepengerAttributter.RESOURCE_FP_ALENEOMSORG; import static no.nav.vedtak.sikkerhet.abac.policy.ForeldrepengerAttributter.RESOURCE_FP_ANNEN_PART; +import static no.nav.vedtak.sikkerhet.abac.policy.ForeldrepengerAttributter.RESOURCE_FP_AVDELING_ENHET; import static no.nav.vedtak.sikkerhet.abac.policy.ForeldrepengerAttributter.RESOURCE_FP_BEHANDLING_STATUS; import static no.nav.vedtak.sikkerhet.abac.policy.ForeldrepengerAttributter.RESOURCE_FP_SAKSBEHANDLER; import static no.nav.vedtak.sikkerhet.abac.policy.ForeldrepengerAttributter.RESOURCE_FP_SAKSID; @@ -18,7 +19,10 @@ public enum ForeldrepengerDataKeys implements RessursDataKey { // Selvbetjening ALENEOMSORG(RESOURCE_FP_ALENEOMSORG), // Boolean.tostring - ANNENPART(RESOURCE_FP_ANNEN_PART), // AktørId format + ANNENPART(RESOURCE_FP_ANNEN_PART), // AktørId format // TODO - legg til fnr-versjon post abac - forenklet kontroll mot tokenx + + // LOS + AVDELING_ENHET(RESOURCE_FP_AVDELING_ENHET), // Ikke i bruk - mangler attributefinder + tilsv for behandlingUuid SAKSID(RESOURCE_FP_SAKSID), diff --git a/felles/abac/src/main/java/no/nav/vedtak/sikkerhet/abac/policy/EksternBrukerPolicies.java b/felles/abac/src/main/java/no/nav/vedtak/sikkerhet/abac/policy/EksternBrukerPolicies.java new file mode 100644 index 000000000..aa8d5aa05 --- /dev/null +++ b/felles/abac/src/main/java/no/nav/vedtak/sikkerhet/abac/policy/EksternBrukerPolicies.java @@ -0,0 +1,77 @@ +package no.nav.vedtak.sikkerhet.abac.policy; + +import java.util.Objects; +import java.util.Optional; + +import no.nav.vedtak.sikkerhet.abac.beskyttet.ActionType; +import no.nav.vedtak.sikkerhet.abac.internal.BeskyttetRessursAttributter; +import no.nav.vedtak.sikkerhet.abac.pdp.AppRessursData; +import no.nav.vedtak.sikkerhet.abac.pdp.ForeldrepengerDataKeys; +import no.nav.vedtak.sikkerhet.abac.pdp.RessursData; +import no.nav.vedtak.sikkerhet.kontekst.IdentType; + +/** + * Inneholder tilgangspolicies for innkommende kall fra EksternBruker (Client Credentials) + * - Tillatt ResourceType er APPLIKASJON, FAGSAK og etterhver UTTAKSPLAN + * - Krav til innlogging nivå 4 er håndtert i autentisering + * - Alderssjekk 15/18 år må gjøres i populasjonstilgang + * - Enn så lenge delegeres øvrige sjekker til populasjonstilgang - gjelder egen person + krav rundt uttakspln + * - Kan forenkles dersom man legger om til å populere med fnr i stedet for aktørId - må fortsatt kalle videre for alderssjekk + */ +public class EksternBrukerPolicies { + + private EksternBrukerPolicies() { + // Hindre instans + } + + public static Tilgangsvurdering vurderTilgang(BeskyttetRessursAttributter beskyttetRessursAttributter, AppRessursData appRessursData) { + if (!IdentType.EksternBruker.equals(beskyttetRessursAttributter.getIdentType())) { + return Tilgangsvurdering.avslåGenerell("Utviklerfeil identType er ikke EksternBruker"); + } + + return switch (beskyttetRessursAttributter.getResourceType()) { + case null -> Tilgangsvurdering.avslåGenerell("ikke angitt ressurs"); + case ForeldrepengerAttributter.RESOURCE_TYPE_FP_APPLIKASJON -> applikasjonPolicy(beskyttetRessursAttributter, appRessursData); + case ForeldrepengerAttributter.RESOURCE_TYPE_FP_FAGSAK -> fagsakPolicy(beskyttetRessursAttributter, appRessursData); + case ForeldrepengerAttributter.RESOURCE_TYPE_FP_UTTAKSPLAN -> uttaksplanPolicy(beskyttetRessursAttributter, appRessursData); + default -> Tilgangsvurdering.avslåGenerell("EksternBruker har ikke tilgang til ressurs"); + }; + } + + private static Tilgangsvurdering fagsakPolicy(BeskyttetRessursAttributter beskyttetRessursAttributter, AppRessursData appRessursData) { + if (ActionType.READ.equals(beskyttetRessursAttributter.getActionType()) || ActionType.CREATE.equals(beskyttetRessursAttributter.getActionType())) { + // Vurder å sjekke for appressursdato.fnr() - men må uansett videre til alderssjekk + return Tilgangsvurdering.godkjenn(); + } else { + return Tilgangsvurdering.avslåGenerell("EksternBruker kan ikke utføre handling på fagsak"); + } + } + + private static Tilgangsvurdering applikasjonPolicy(BeskyttetRessursAttributter beskyttetRessursAttributter, AppRessursData appRessursData) { + if (!appRessursData.getFødselsnumre().isEmpty() || !appRessursData.getAktørIdSet().isEmpty()) { + return Tilgangsvurdering.avslåGenerell("Applikasjon-ressurs kan ikke ha personer / saker"); + } + if (ActionType.READ.equals(beskyttetRessursAttributter.getActionType())) { + return Tilgangsvurdering.godkjenn(); + } else { + return Tilgangsvurdering.avslåGenerell("EksternBruker kan ikke utføre handling for ressurs"); + } + } + + private static Tilgangsvurdering uttaksplanPolicy(BeskyttetRessursAttributter beskyttetRessursAttributter, AppRessursData appRessursData) { + var annenpart = Optional.ofNullable(appRessursData.getResource(ForeldrepengerDataKeys.ANNENPART)).map(RessursData::verdi).orElse(null); + var aleneomsorg = Optional.ofNullable(appRessursData.getResource(ForeldrepengerDataKeys.ALENEOMSORG)).map(RessursData::verdi).orElse(null); + if (ActionType.READ.equals(beskyttetRessursAttributter.getActionType())) { + // Tester for om gjelderEgenPerson eller brukerId = annenpart_fnr + return Tilgangsvurdering.avslåGenerell("Ikke implementert"); // TODO fortsett med mindre Deny + } else { + return Tilgangsvurdering.avslåGenerell("EksternBruker kan ikke utføre handling for ressurs"); + } + } + + private static boolean gjelderEgenPersonFnr(BeskyttetRessursAttributter beskyttetRessursAttributter, AppRessursData appRessursData) { + var fnr = appRessursData.getFødselsnumre(); + return fnr.size() == 1 && Objects.equals(beskyttetRessursAttributter.getBrukerId(), fnr.stream().findFirst().orElse(null)); + } + +} diff --git a/felles/abac/src/main/java/no/nav/vedtak/sikkerhet/abac/policy/ForeldrepengerAttributter.java b/felles/abac/src/main/java/no/nav/vedtak/sikkerhet/abac/policy/ForeldrepengerAttributter.java index f823c4a71..5ec02ac39 100644 --- a/felles/abac/src/main/java/no/nav/vedtak/sikkerhet/abac/policy/ForeldrepengerAttributter.java +++ b/felles/abac/src/main/java/no/nav/vedtak/sikkerhet/abac/policy/ForeldrepengerAttributter.java @@ -18,8 +18,11 @@ private ForeldrepengerAttributter() { public static final String RESOURCE_FP_BEHANDLING_STATUS = "no.nav.abac.attributter.resource.foreldrepenger.sak.behandlingsstatus"; public static final String RESOURCE_FP_SAK_STATUS = "no.nav.abac.attributter.resource.foreldrepenger.sak.saksstatus"; // Selvbetjeningsrelatert - public static final String RESOURCE_FP_ALENEOMSORG = "no.nav.abac.attributter.resource.foreldrepenger.aleneomsorg"; + public static final String RESOURCE_FP_ALENEOMSORG = "no.nav.abac.attributter.resource.foreldrepenger.aleneomsorg"; // Boolean + // TODO - legg til annen_part_fnr etter sanering abac - forenklet kontroll mot tokenx public static final String RESOURCE_FP_ANNEN_PART = "no.nav.abac.attributter.resource.foreldrepenger.annen_part"; + // LOS-relatert - merk samme path som resource ... + public static final String RESOURCE_FP_AVDELING_ENHET = "no.nav.abac.attributter.foreldrepenger.oppgavestyring.avdelingsenhet"; // Ikke tatt i bruk - mangler attributefinder + tilsv for behandlingUuid public static final String RESOURCE_FP_SAKSID = "no.nav.abac.attributter.foreldrepenger.fp_saksid"; @@ -32,19 +35,22 @@ private ForeldrepengerAttributter() { public static final String VALUE_FP_BEHANDLING_STATUS_UTREDES = "Behandling utredes"; public static final String VALUE_FP_BEHANDLING_STATUS_VEDTAK = "Kontroller og fatte vedtak"; public static final String VALUE_FP_AKSJONSPUNKT_OVERSTYRING = "Overstyring"; + public static final String VALUE_FP_AVDELING_ENHET_ADRESSEBESKYTTET = "2103"; + public static final String VALUE_FP_AVDELING_ENHET_SKJERMET = "4883"; /** * Attributter brukt som resource_type + * TODO: Behov for AvdelingEnhet og OppgaveStyring? Fjerne risikoklassifisering? + * TODO: OPPGAVEKØ ikke i bruk - vurder FAGSAK vs OPPGAVEKØ + evt bruk som dataattributt (køer på 2103. Mangler policies) */ public static final String RESOURCE_TYPE_FP_APPLIKASJON = "no.nav.abac.attributter.foreldrepenger"; public static final String RESOURCE_TYPE_FP_DRIFT = "no.nav.abac.attributter.foreldrepenger.drift"; public static final String RESOURCE_TYPE_FP_FAGSAK = "no.nav.abac.attributter.foreldrepenger.fagsak"; public static final String RESOURCE_TYPE_FP_VENTEFRIST = "no.nav.abac.attributter.foreldrepenger.fagsak.ventefrist"; public static final String RESOURCE_TYPE_FP_AVDELINGENHET = "no.nav.abac.attributter.foreldrepenger.oppgavestyring.avdelingsenhet"; - public static final String RESOURCE_TYPE_FP_OPPGAVEKØ = "no.nav.abac.attributter.foreldrepenger.oppgaveko"; + // public static final String RESOURCE_TYPE_FP_OPPGAVEKØ = "no.nav.abac.attributter.foreldrepenger.oppgaveko"; TODO: Vurder om skal brukes for å lese oppgaver for LOS. Nå brukes FAGSAK. Evt bruk som dataAttributt. public static final String RESOURCE_TYPE_FP_OPPGAVESTYRING = "no.nav.abac.attributter.foreldrepenger.oppgavestyring"; public static final String RESOURCE_TYPE_FP_RISIKOKLASSIFISERING = "no.nav.abac.attributter.foreldrepenger.risikoklassifisering"; - public static final String RESOURCE_TYPE_FP_SAKLISTE = "no.nav.abac.attributter.foreldrepenger.sakliste"; public static final String RESOURCE_TYPE_FP_UTTAKSPLAN = "no.nav.abac.attributter.resource.foreldrepenger.uttaksplan"; /** diff --git a/felles/abac/src/main/java/no/nav/vedtak/sikkerhet/abac/policy/InternBrukerPolicies.java b/felles/abac/src/main/java/no/nav/vedtak/sikkerhet/abac/policy/InternBrukerPolicies.java new file mode 100644 index 000000000..cfe843b85 --- /dev/null +++ b/felles/abac/src/main/java/no/nav/vedtak/sikkerhet/abac/policy/InternBrukerPolicies.java @@ -0,0 +1,150 @@ +package no.nav.vedtak.sikkerhet.abac.policy; + +import java.util.Objects; +import java.util.Optional; +import java.util.Set; + +import no.nav.vedtak.sikkerhet.abac.beskyttet.ActionType; +import no.nav.vedtak.sikkerhet.abac.internal.BeskyttetRessursAttributter; +import no.nav.vedtak.sikkerhet.abac.pdp.AppRessursData; +import no.nav.vedtak.sikkerhet.abac.pdp.ForeldrepengerDataKeys; +import no.nav.vedtak.sikkerhet.abac.pdp.RessursData; +import no.nav.vedtak.sikkerhet.kontekst.AnsattGruppe; +import no.nav.vedtak.sikkerhet.kontekst.IdentType; + +/** + * Inneholder tilgangspolicies for innkommende kall fra InternBruker (OBO), dvs saksbehandler, veileder, mm. + * - Tillatt ResourceType er alle utenom PIP og UTTAKSPLAN + * - Vil ferdig-evaluere fagsakstatus/behandlingstatus for FAGSAK/UPDATE + */ +public class InternBrukerPolicies { + + private static final Set VEILEDER_SAKSBEHANDLER = Set.of(AnsattGruppe.SAKSBEHANDLER, AnsattGruppe.VEILEDER); + + private InternBrukerPolicies() { + // Hindre instans + } + + public static Tilgangsvurdering vurderTilgang(BeskyttetRessursAttributter beskyttetRessursAttributter, AppRessursData appRessursData) { + if (!IdentType.InternBruker.equals(beskyttetRessursAttributter.getIdentType())) { + return Tilgangsvurdering.avslåGenerell("Utviklerfeil identType er ikke InternBruker"); + } + + return switch (beskyttetRessursAttributter.getResourceType()) { + case null -> Tilgangsvurdering.avslåGenerell("ikke angitt ressurs"); + case ForeldrepengerAttributter.RESOURCE_TYPE_FP_APPLIKASJON -> applikasjonPolicy(beskyttetRessursAttributter, appRessursData); + case ForeldrepengerAttributter.RESOURCE_TYPE_FP_DRIFT -> driftPolicy(beskyttetRessursAttributter); + case ForeldrepengerAttributter.RESOURCE_TYPE_FP_FAGSAK -> fagsakPolicy(beskyttetRessursAttributter, appRessursData); + case ForeldrepengerAttributter.RESOURCE_TYPE_FP_VENTEFRIST -> ventefristPolicy(beskyttetRessursAttributter); + case ForeldrepengerAttributter.RESOURCE_TYPE_FP_AVDELINGENHET -> avdelingEnhetPolicy(beskyttetRessursAttributter, appRessursData); + case ForeldrepengerAttributter.RESOURCE_TYPE_FP_OPPGAVESTYRING -> oppgavestyrerPolicy(beskyttetRessursAttributter); + case ForeldrepengerAttributter.RESOURCE_TYPE_FP_RISIKOKLASSIFISERING -> veilederEllerSaksbehandler(beskyttetRessursAttributter); + default -> Tilgangsvurdering.avslåGenerell("InternBruker har ikke tilgang til ressurs"); + }; + } + + private static Tilgangsvurdering fagsakPolicy(BeskyttetRessursAttributter beskyttetRessursAttributter, AppRessursData appRessursData) { + return switch (beskyttetRessursAttributter.getActionType()) { + case READ -> veilederEllerSaksbehandler(beskyttetRessursAttributter); + case CREATE -> harGruppe(beskyttetRessursAttributter, AnsattGruppe.SAKSBEHANDLER) ? Tilgangsvurdering.godkjenn() : Tilgangsvurdering.avslåGenerell("InternRessurs er ikke saksbehandler"); + case UPDATE -> fagsakUpdatePolicy(beskyttetRessursAttributter, appRessursData); + case null, default -> Tilgangsvurdering.avslåGenerell("InternRessurs kan ikke utføre handling på fagsak"); + }; + } + + private static Tilgangsvurdering fagsakUpdatePolicy(BeskyttetRessursAttributter beskyttetRessursAttributter, AppRessursData appRessursData) { + if (!harGruppe(beskyttetRessursAttributter, AnsattGruppe.SAKSBEHANDLER)) { + return Tilgangsvurdering.avslåGenerell("Internbruker er ikke saksbehandler"); + } + var overstyring = Optional.ofNullable(appRessursData.getResource(ForeldrepengerDataKeys.AKSJONSPUNKT_OVERSTYRING)).map(RessursData::verdi).orElse(null); + var behandlingStatus = Optional.ofNullable(appRessursData.getResource(ForeldrepengerDataKeys.BEHANDLING_STATUS)).map(RessursData::verdi).orElse(null); + var fagsakStatus = Optional.ofNullable(appRessursData.getResource(ForeldrepengerDataKeys.FAGSAK_STATUS)).map(RessursData::verdi).orElse(null); + // Beslutter fatter vedtak + if (ForeldrepengerAttributter.VALUE_FP_BEHANDLING_STATUS_VEDTAK.equals(behandlingStatus) && + ForeldrepengerAttributter.VALUE_FP_SAK_STATUS_BEHANDLES.equals(fagsakStatus) && + !ForeldrepengerAttributter.VALUE_FP_AKSJONSPUNKT_OVERSTYRING.equals(overstyring)) { + var saksbehandler = Optional.ofNullable(appRessursData.getResource(ForeldrepengerDataKeys.SAKSBEHANDLER)).map(RessursData::verdi).orElse(null); + var beslutterLikSaksbehandler = Objects.equals(beskyttetRessursAttributter.getBrukerId(), saksbehandler); + return beslutterLikSaksbehandler ? Tilgangsvurdering.avslåGenerell("Beslutter er lik saksbehandler") : Tilgangsvurdering.godkjenn(AnsattGruppe.BESLUTTER); + } + // Overstyring + if (ForeldrepengerAttributter.VALUE_FP_BEHANDLING_STATUS_UTREDES.equals(behandlingStatus) && + ForeldrepengerAttributter.VALUE_FP_SAK_STATUS_BEHANDLES.equals(fagsakStatus) && + ForeldrepengerAttributter.VALUE_FP_AKSJONSPUNKT_OVERSTYRING.equals(overstyring)) { + return Tilgangsvurdering.godkjenn(AnsattGruppe.OVERSTYRER); + } + // Ordinær saksbehandling + if ((ForeldrepengerAttributter.VALUE_FP_BEHANDLING_STATUS_UTREDES.equals(behandlingStatus) || ForeldrepengerAttributter.VALUE_FP_BEHANDLING_STATUS_OPPRETTET.equals(behandlingStatus)) && + (ForeldrepengerAttributter.VALUE_FP_SAK_STATUS_BEHANDLES.equals(fagsakStatus) || ForeldrepengerAttributter.VALUE_FP_SAK_STATUS_OPPRETTET.equals(fagsakStatus)) && + !ForeldrepengerAttributter.VALUE_FP_AKSJONSPUNKT_OVERSTYRING.equals(overstyring)) { + return Tilgangsvurdering.godkjenn(); + } + return Tilgangsvurdering.avslåGenerell("InternRessurs har ikke tilgang til å oppdatere fagsak"); + } + + private static Tilgangsvurdering applikasjonPolicy(BeskyttetRessursAttributter beskyttetRessursAttributter, AppRessursData appRessursData) { + if (!appRessursData.getFødselsnumre().isEmpty() || !appRessursData.getAktørIdSet().isEmpty()) { + return Tilgangsvurdering.avslåGenerell("Applikasjon-ressurs kan ikke ha personer / saker"); + } + if (ActionType.READ.equals(beskyttetRessursAttributter.getActionType())) { + return veilederEllerSaksbehandler(beskyttetRessursAttributter); + } else { + return Tilgangsvurdering.avslåGenerell("InternBruker kan ikke utføre handling for ressurs"); + } + } + + private static Tilgangsvurdering ventefristPolicy(BeskyttetRessursAttributter beskyttetRessursAttributter) { + if (ActionType.UPDATE.equals(beskyttetRessursAttributter.getActionType())) { + return veilederEllerSaksbehandler(beskyttetRessursAttributter); + } else { + return Tilgangsvurdering.avslåGenerell("InternBruker kan ikke utføre handling for ressurs"); + } + } + + private static Tilgangsvurdering driftPolicy(BeskyttetRessursAttributter beskyttetRessursAttributter) { + if (ActionType.READ.equals(beskyttetRessursAttributter.getActionType()) || ActionType.CREATE.equals(beskyttetRessursAttributter.getActionType())) { + if (harGruppe(beskyttetRessursAttributter, AnsattGruppe.DRIFT)) { + return Tilgangsvurdering.godkjenn(); + } else { + return Tilgangsvurdering.godkjenn(AnsattGruppe.DRIFT); + } + } else { + return Tilgangsvurdering.avslåGenerell("InternRessurs kan ikke utføre handling på ressurs"); + } + } + + private static Tilgangsvurdering oppgavestyrerPolicy(BeskyttetRessursAttributter beskyttetRessursAttributter) { + if (harGruppe(beskyttetRessursAttributter, AnsattGruppe.OPPGAVESTYRER)) { + return Tilgangsvurdering.godkjenn(); + } else { + return Tilgangsvurdering.godkjenn(AnsattGruppe.OPPGAVESTYRER); + } + } + + private static Tilgangsvurdering avdelingEnhetPolicy(BeskyttetRessursAttributter beskyttetRessursAttributter, AppRessursData appRessursData) { + var enhetAdresseBeskyttelse = Optional.ofNullable(appRessursData.getResource(ForeldrepengerDataKeys.AVDELING_ENHET)) + .map(RessursData::verdi) + .filter(ForeldrepengerAttributter.VALUE_FP_AVDELING_ENHET_ADRESSEBESKYTTET::equals) + .isPresent(); + var erOppgavestyrer = harGruppe(beskyttetRessursAttributter, AnsattGruppe.OPPGAVESTYRER); + if (enhetAdresseBeskyttelse) { + return erOppgavestyrer ? Tilgangsvurdering.godkjenn() : Tilgangsvurdering.godkjenn(Set.of(AnsattGruppe.OPPGAVESTYRER, AnsattGruppe.STRENGTFORTROLIG)); + } else { + return erOppgavestyrer ? Tilgangsvurdering.godkjenn() : Tilgangsvurdering.godkjenn(AnsattGruppe.OPPGAVESTYRER); + } + } + + + private static Tilgangsvurdering veilederEllerSaksbehandler(BeskyttetRessursAttributter beskyttetRessursAttributter) { + if (beskyttetRessursAttributter.getAnsattGrupper().stream().anyMatch(VEILEDER_SAKSBEHANDLER::contains)) { + return Tilgangsvurdering.godkjenn(); + } else { + return Tilgangsvurdering.avslåGenerell("InternBruker ikke veileder eller saksbehandler"); + } + } + + private static boolean harGruppe(BeskyttetRessursAttributter beskyttetRessursAttributter, AnsattGruppe gruppe) { + return beskyttetRessursAttributter.getAnsattGrupper().stream().anyMatch(gruppe::equals); + } + +} diff --git a/felles/abac/src/main/java/no/nav/vedtak/sikkerhet/abac/policy/SystemressursPolicies.java b/felles/abac/src/main/java/no/nav/vedtak/sikkerhet/abac/policy/SystemressursPolicies.java new file mode 100644 index 000000000..2c5228616 --- /dev/null +++ b/felles/abac/src/main/java/no/nav/vedtak/sikkerhet/abac/policy/SystemressursPolicies.java @@ -0,0 +1,80 @@ +package no.nav.vedtak.sikkerhet.abac.policy; + +import java.util.Objects; +import java.util.Set; + +import no.nav.foreldrepenger.konfig.Cluster; +import no.nav.foreldrepenger.konfig.Environment; +import no.nav.vedtak.sikkerhet.abac.beskyttet.ActionType; +import no.nav.vedtak.sikkerhet.abac.beskyttet.AvailabilityType; +import no.nav.vedtak.sikkerhet.abac.internal.BeskyttetRessursAttributter; +import no.nav.vedtak.sikkerhet.abac.pdp.AppRessursData; +import no.nav.vedtak.sikkerhet.abac.pdp.ForeldrepengerDataKeys; +import no.nav.vedtak.sikkerhet.oidc.config.AzureProperty; + +/** + * Inneholder tilgangspolicies for innkommende kall fra Systemressurs (Client Credentials) + * - ConsumerId fra andre cluster-klasser er ikke tillatt (prod - dev) + * - ConsumerId fra andre namespace er bare tillatt når endepunktet har AvailabilityType = ALL + * - Tillatt ResourceType er alle utenom UTTAKSPLAN (evt bare APPLIKASJON, FAGSAK og PIP etter rydding) + * - ActionType CUD og ResourceType FAGSAK krever at ForeldrepengerDataKeys BEHANDLING_STATUS eller FAGSAK_STATUS har verdi + */ +public class SystemressursPolicies { + + private static final Environment ENV = Environment.current(); + + // Format: json array av objekt("name", "clientId"); + private static final String PRE_AUTHORIZED = ENV.getProperty(AzureProperty.AZURE_APP_PRE_AUTHORIZED_APPS.name()); + private static final Cluster RESIDENT_CLUSTER = ENV.getCluster(); + private static final String RESIDENT_NAMESPACE = ENV.namespace(); + private static final Set IKKE_TILLATT_RESOURCE_TYPE = Set.of(ForeldrepengerAttributter.RESOURCE_TYPE_FP_UTTAKSPLAN); + + private SystemressursPolicies() { + // Hindre instans + } + + public static Tilgangsvurdering vurderTilgang(BeskyttetRessursAttributter beskyttetRessursAttributter, AppRessursData appRessursData) { + if (!beskyttetRessursAttributter.getIdentType().erSystem()) { + return Tilgangsvurdering.avslåGenerell("IdentType ikke Systemressurs"); + } + if (!riktigClusterNamespacePreAuth(beskyttetRessursAttributter.getBrukerId(), beskyttetRessursAttributter.getAvailabilityType())) { + return Tilgangsvurdering.avslåGenerell("Cluster/Namespace ikke tillatt"); + } + if (IKKE_TILLATT_RESOURCE_TYPE.contains(beskyttetRessursAttributter.getResourceType())) { + return Tilgangsvurdering.avslåGenerell("ResourceType UTTAKSPLAN ikke tillatt"); + } + if (ActionType.UPDATE.equals(beskyttetRessursAttributter.getActionType()) && + skriveBeskyttet(beskyttetRessursAttributter, appRessursData)) { + return Tilgangsvurdering.avslåGenerell("Sak/Behandling avsluttet"); + } + // Skal ikke utføre videre kontroll (fagtilgang, populasjonstilgang) for System. Returner GODKJENT. + return Tilgangsvurdering.godkjenn(); + } + + public static boolean riktigClusterNamespacePreAuth(String consumerId, AvailabilityType availabilityType) { + if (consumerId == null || !PRE_AUTHORIZED.contains(consumerId)) { + return false; + } + var splittConsumerId = consumerId.split(":"); + return erISammeClusterKlasse(splittConsumerId) && erISammeNamespace(splittConsumerId, availabilityType); + } + + private static boolean erISammeClusterKlasse(String[] elementer) { + return elementer.length > 0 && RESIDENT_CLUSTER.isSameClass(Cluster.of(elementer[0])); + } + + private static boolean erISammeNamespace(String[] elementer, AvailabilityType availabilityType) { + return AvailabilityType.ALL.equals(availabilityType) || elementer.length > 1 && RESIDENT_NAMESPACE.equals(elementer[1]); + } + + private static boolean skriveBeskyttet(BeskyttetRessursAttributter beskyttetRessursAttributter, AppRessursData appRessursData) { + if (Objects.equals(ForeldrepengerAttributter.RESOURCE_TYPE_FP_FAGSAK, beskyttetRessursAttributter.getResourceType())) { + var behandlingStatus = appRessursData.getResource(ForeldrepengerDataKeys.BEHANDLING_STATUS); + var fagsakStatus = appRessursData.getResource(ForeldrepengerDataKeys.FAGSAK_STATUS); + return behandlingStatus == null && fagsakStatus == null; // Må kunne oppdatere behandling med status IVED. Helst ikke AVSLU. + } else { + return true; // TODO vurder om skriving kun skal være tillatt for FAGSAK (må fikse noe callback fra abakus) + } + } + +} diff --git a/felles/abac/src/main/java/no/nav/vedtak/sikkerhet/abac/policy/Tilgangsvurdering.java b/felles/abac/src/main/java/no/nav/vedtak/sikkerhet/abac/policy/Tilgangsvurdering.java new file mode 100644 index 000000000..7d9e9e474 --- /dev/null +++ b/felles/abac/src/main/java/no/nav/vedtak/sikkerhet/abac/policy/Tilgangsvurdering.java @@ -0,0 +1,29 @@ +package no.nav.vedtak.sikkerhet.abac.policy; + +import java.util.Set; + +import no.nav.vedtak.sikkerhet.abac.AbacResultat; +import no.nav.vedtak.sikkerhet.kontekst.AnsattGruppe; + +public record Tilgangsvurdering(AbacResultat abacResultat, String årsak, Set kreverGrupper) { + + public boolean fikkTilgang() { + return abacResultat == AbacResultat.GODKJENT; + } + + public static Tilgangsvurdering godkjenn() { + return new Tilgangsvurdering(AbacResultat.GODKJENT, "", Set.of()); + } + + public static Tilgangsvurdering godkjenn(AnsattGruppe kreverGruppe) { + return new Tilgangsvurdering(AbacResultat.GODKJENT, "", Set.of(kreverGruppe)); + } + + public static Tilgangsvurdering godkjenn(Set kreverGrupper) { + return new Tilgangsvurdering(AbacResultat.GODKJENT, "", kreverGrupper); + } + + public static Tilgangsvurdering avslåGenerell(String årsak) { + return new Tilgangsvurdering(AbacResultat.AVSLÅTT_ANNEN_ÅRSAK, årsak, Set.of()); + } +} diff --git a/felles/abac/src/main/java/no/nav/vedtak/sikkerhet/populasjon/PopulasjonEksternRequest.java b/felles/abac/src/main/java/no/nav/vedtak/sikkerhet/populasjon/PopulasjonEksternRequest.java new file mode 100644 index 000000000..bc79d21cb --- /dev/null +++ b/felles/abac/src/main/java/no/nav/vedtak/sikkerhet/populasjon/PopulasjonEksternRequest.java @@ -0,0 +1,9 @@ +package no.nav.vedtak.sikkerhet.populasjon; + +import java.util.Set; + +public record PopulasjonEksternRequest(String subjectPersonIdent, + Set personIdenter, + Set aktørIdenter) { + +} diff --git a/felles/abac/src/main/java/no/nav/vedtak/sikkerhet/populasjon/PopulasjonInternRequest.java b/felles/abac/src/main/java/no/nav/vedtak/sikkerhet/populasjon/PopulasjonInternRequest.java new file mode 100644 index 000000000..adcb7019c --- /dev/null +++ b/felles/abac/src/main/java/no/nav/vedtak/sikkerhet/populasjon/PopulasjonInternRequest.java @@ -0,0 +1,13 @@ +package no.nav.vedtak.sikkerhet.populasjon; + +import java.util.Set; +import java.util.UUID; + +import no.nav.vedtak.sikkerhet.kontekst.AnsattGruppe; + +public record PopulasjonInternRequest(UUID ansattOid, + Set kreverGrupper, + Set personIdenter, + Set aktørIdenter) { + +} diff --git a/felles/abac/src/main/java/no/nav/vedtak/sikkerhet/populasjon/PopulasjonKlient.java b/felles/abac/src/main/java/no/nav/vedtak/sikkerhet/populasjon/PopulasjonKlient.java new file mode 100644 index 000000000..34c595c23 --- /dev/null +++ b/felles/abac/src/main/java/no/nav/vedtak/sikkerhet/populasjon/PopulasjonKlient.java @@ -0,0 +1,10 @@ +package no.nav.vedtak.sikkerhet.populasjon; + +import no.nav.vedtak.sikkerhet.abac.policy.Tilgangsvurdering; + +public interface PopulasjonKlient { + + Tilgangsvurdering vurderTilgang(PopulasjonInternRequest request); + Tilgangsvurdering vurderTilgang(PopulasjonEksternRequest request); + +} diff --git a/felles/abac/src/test/java/no/nav/vedtak/sikkerhet/abac/PepImplTest.java b/felles/abac/src/test/java/no/nav/vedtak/sikkerhet/abac/PepImplTest.java index dc86ca2df..cd350171a 100644 --- a/felles/abac/src/test/java/no/nav/vedtak/sikkerhet/abac/PepImplTest.java +++ b/felles/abac/src/test/java/no/nav/vedtak/sikkerhet/abac/PepImplTest.java @@ -8,6 +8,9 @@ import static org.mockito.Mockito.verifyNoInteractions; import static org.mockito.Mockito.when; +import java.util.Set; +import java.util.UUID; + import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.BeforeEach; @@ -23,11 +26,14 @@ import no.nav.vedtak.sikkerhet.abac.internal.BeskyttetRessursInterceptorTest; import no.nav.vedtak.sikkerhet.abac.pdp.AppRessursData; import no.nav.vedtak.sikkerhet.abac.policy.ForeldrepengerAttributter; +import no.nav.vedtak.sikkerhet.kontekst.AnsattGruppe; import no.nav.vedtak.sikkerhet.kontekst.IdentType; import no.nav.vedtak.sikkerhet.oidc.config.AzureProperty; import no.nav.vedtak.sikkerhet.oidc.config.OpenIDProvider; import no.nav.vedtak.sikkerhet.oidc.token.OpenIDToken; import no.nav.vedtak.sikkerhet.oidc.token.TokenString; +import no.nav.vedtak.sikkerhet.populasjon.PopulasjonInternRequest; +import no.nav.vedtak.sikkerhet.populasjon.PopulasjonKlient; @ExtendWith(MockitoExtension.class) class PepImplTest { @@ -40,6 +46,8 @@ class PepImplTest { @Mock private PdpKlient pdpKlientMock; @Mock + private PopulasjonKlient popKlientMock; + @Mock private PdpRequestBuilder pdpRequestBuilder; @BeforeAll @@ -54,7 +62,7 @@ static void avsluttEnv() { @BeforeEach void setUp() { - pep = new PepImpl(pdpKlientMock, pdpRequestBuilder); + this.pep = new PepImpl(pdpKlientMock, popKlientMock, pdpRequestBuilder); } @Test @@ -67,6 +75,7 @@ void skal_ikke_gi_tilgang_til_srvpdp_for_piptjeneste_siden_sts_brukere_ikke_stot Tilgangsbeslutning permit = pep.vurderTilgang(attributter); assertThat(permit.fikkTilgang()).isFalse(); verifyNoInteractions(pdpKlientMock); + verifyNoInteractions(popKlientMock); } @Test @@ -79,6 +88,7 @@ void skal_nekte_tilgang_til_saksbehandler_for_piptjeneste() { Tilgangsbeslutning permit = pep.vurderTilgang(attributter); assertThat(permit.fikkTilgang()).isFalse(); verifyNoInteractions(pdpKlientMock); + verifyNoInteractions(popKlientMock); } @Test @@ -92,6 +102,7 @@ void skal_gi_tilgang_for_intern_azure_cc() { Tilgangsbeslutning permit = pep.vurderTilgang(attributter); assertThat(permit.fikkTilgang()).isTrue(); verifyNoInteractions(pdpKlientMock); + verifyNoInteractions(popKlientMock); } @Test @@ -106,6 +117,7 @@ void skal_gi_avslag_for_ekstern_azure_cc() { Tilgangsbeslutning permit = pep.vurderTilgang(attributter); assertThat(permit.fikkTilgang()).isFalse(); verifyNoInteractions(pdpKlientMock); + verifyNoInteractions(popKlientMock); } @Test @@ -120,6 +132,7 @@ void skal_gi_avslag_for_godkjent_ekstern_azure_cc_men_i_feil_klusterklasse() { Tilgangsbeslutning permit = pep.vurderTilgang(attributter); assertThat(permit.fikkTilgang()).isFalse(); verifyNoInteractions(pdpKlientMock); + verifyNoInteractions(popKlientMock); } @@ -135,24 +148,31 @@ void skal_gi_tilgang_for_godkjent_ekstern_azure_cc() { Tilgangsbeslutning permit = pep.vurderTilgang(attributter); assertThat(permit.fikkTilgang()).isTrue(); verifyNoInteractions(pdpKlientMock); + verifyNoInteractions(popKlientMock); } @Test void skal_kalle_pdp_for_annet_enn_pip_tjenester() { when(tokenProvider.getUid()).thenReturn("z142443"); var attributter = lagBeskyttetRessursAttributter(); + var appressursData = AppRessursData.builder().leggTilAktørId("1234567890123").build(); - when(pdpRequestBuilder.lagAppRessursData(any())).thenReturn(AppRessursData.builder().build()); + when(pdpRequestBuilder.lagAppRessursData(any())).thenReturn(appressursData); when(pdpRequestBuilder.abacDomene()).thenReturn("foreldrepenger"); + when(pdpKlientMock.forespørTilgang(any(), any(), any())).thenReturn(new Tilgangsbeslutning(AbacResultat.GODKJENT, attributter, appressursData)); @SuppressWarnings("unused") Tilgangsbeslutning permit = pep.vurderTilgang(attributter); verify(pdpKlientMock).forespørTilgang(eq(attributter), any(String.class), any(AppRessursData.class)); + verify(popKlientMock).vurderTilgang(new PopulasjonInternRequest(attributter.getBrukerOid(), Set.of(), Set.of(), appressursData.getAktørIdSet())); } private BeskyttetRessursAttributter lagBeskyttetRessursAttributter() { return BeskyttetRessursAttributter.builder() - .medUserId(tokenProvider.getUid()) - .medToken(Token.withOidcToken(BeskyttetRessursInterceptorTest.DUMMY_OPENID_TOKEN, "TEST", IdentType.InternBruker)) + .medBrukerId(tokenProvider.getUid()) + .medBrukerOid(UUID.randomUUID()) + .medIdentType(IdentType.InternBruker) + .medAnsattGrupper(Set.of(AnsattGruppe.SAKSBEHANDLER)) + .medToken(Token.withOidcToken(BeskyttetRessursInterceptorTest.DUMMY_OPENID_TOKEN)) .medResourceType(ForeldrepengerAttributter.RESOURCE_TYPE_FP_FAGSAK) .medActionType(ActionType.READ) .medPepId("local-app") @@ -163,8 +183,9 @@ private BeskyttetRessursAttributter lagBeskyttetRessursAttributter() { private BeskyttetRessursAttributter lagBeskyttetRessursAttributterPip() { return BeskyttetRessursAttributter.builder() - .medUserId(tokenProvider.getUid()) - .medToken(Token.withOidcToken(BeskyttetRessursInterceptorTest.DUMMY_OPENID_TOKEN, "TEST", IdentType.InternBruker)) + .medBrukerId(tokenProvider.getUid()) + .medIdentType(IdentType.InternBruker) + .medToken(Token.withOidcToken(BeskyttetRessursInterceptorTest.DUMMY_OPENID_TOKEN)) .medResourceType(RESOURCE_TYPE_INTERNAL_PIP) .medActionType(ActionType.READ) .medPepId("local-app") @@ -178,8 +199,9 @@ private BeskyttetRessursAttributter lagBeskyttetRessursAttributterAzure(Availabi String brukerId, IdentType identType) { return BeskyttetRessursAttributter.builder() - .medUserId(tokenProvider.getUid()) - .medToken(Token.withOidcToken(token, brukerId, identType)) + .medBrukerId(tokenProvider.getUid()) + .medIdentType(identType) + .medToken(Token.withOidcToken(token)) .medResourceType(ForeldrepengerAttributter.RESOURCE_TYPE_FP_FAGSAK) .medActionType(ActionType.READ) .medAvailabilityType(availabilityType) diff --git a/felles/abac/src/test/java/no/nav/vedtak/sikkerhet/abac/RessursAttributterTest.java b/felles/abac/src/test/java/no/nav/vedtak/sikkerhet/abac/RessursAttributterTest.java index 32f1caab3..b10c26d64 100644 --- a/felles/abac/src/test/java/no/nav/vedtak/sikkerhet/abac/RessursAttributterTest.java +++ b/felles/abac/src/test/java/no/nav/vedtak/sikkerhet/abac/RessursAttributterTest.java @@ -43,7 +43,7 @@ void skal_lage_kryssprodukt_mellom_identer() { @Test void skal_fungere_uten_fnr() { - var req = AppRessursData.builder().leggTilRessurs(ForeldrepengerDataKeys.SAKSBEHANDLER, "A000000").build(); + var req = AppRessursData.builder().medAnsvarligSaksbehandler("A000000").build(); assertThat(getFnrFromList(req, 0)).isNotPresent(); assertThat(getFnrFromList(req, 1)).isNotPresent(); diff --git a/felles/abac/src/test/java/no/nav/vedtak/sikkerhet/abac/policy/EksternBrukerTest.java b/felles/abac/src/test/java/no/nav/vedtak/sikkerhet/abac/policy/EksternBrukerTest.java new file mode 100644 index 000000000..08246a6a0 --- /dev/null +++ b/felles/abac/src/test/java/no/nav/vedtak/sikkerhet/abac/policy/EksternBrukerTest.java @@ -0,0 +1,107 @@ +package no.nav.vedtak.sikkerhet.abac.policy; + +import static org.assertj.core.api.AssertionsForClassTypes.assertThat; + +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.junit.jupiter.MockitoExtension; + +import no.nav.vedtak.sikkerhet.abac.AbacDataAttributter; +import no.nav.vedtak.sikkerhet.abac.Token; +import no.nav.vedtak.sikkerhet.abac.beskyttet.ActionType; +import no.nav.vedtak.sikkerhet.abac.internal.BeskyttetRessursAttributter; +import no.nav.vedtak.sikkerhet.abac.internal.BeskyttetRessursInterceptorTest; +import no.nav.vedtak.sikkerhet.abac.pdp.AppRessursData; +import no.nav.vedtak.sikkerhet.kontekst.IdentType; + +@ExtendWith(MockitoExtension.class) +class EksternBrukerTest { + + + @Test + void tilgang_fagsak_read() { + var attributter = lagAttributter(ActionType.READ, ForeldrepengerAttributter.RESOURCE_TYPE_FP_FAGSAK); + + var resultat = EksternBrukerPolicies.vurderTilgang(attributter, AppRessursData.builder().build()); + assertThat(resultat.fikkTilgang()).isTrue(); + } + + @Test + void tilgang_fagsak_create() { + var attributter = lagAttributter(ActionType.CREATE, ForeldrepengerAttributter.RESOURCE_TYPE_FP_FAGSAK); + + var resultat = EksternBrukerPolicies.vurderTilgang(attributter, AppRessursData.builder().build()); + assertThat(resultat.fikkTilgang()).isTrue(); + } + + @Test + void avslag_fagsak_update() { + var attributter = lagAttributter(ActionType.UPDATE, ForeldrepengerAttributter.RESOURCE_TYPE_FP_FAGSAK); + + var resultat = EksternBrukerPolicies.vurderTilgang(attributter, AppRessursData.builder().build()); + assertThat(resultat.fikkTilgang()).isFalse(); + } + + @Test + void avslag_fagsak_delete() { + var attributter = lagAttributter(ActionType.DELETE, ForeldrepengerAttributter.RESOURCE_TYPE_FP_FAGSAK); + + var resultat = EksternBrukerPolicies.vurderTilgang(attributter, AppRessursData.builder().build()); + assertThat(resultat.fikkTilgang()).isFalse(); + } + + @Test + void avslag_uttaksplan_read() { // TODO - rydde, ta med ressursdata og endre til oppfylt. Nå er den ikke implementert + var attributter = lagAttributter(ActionType.READ, ForeldrepengerAttributter.RESOURCE_TYPE_FP_UTTAKSPLAN); + + var resultat = EksternBrukerPolicies.vurderTilgang(attributter, AppRessursData.builder().build()); + assertThat(resultat.fikkTilgang()).isFalse(); + } + + @Test + void avslag_uttaksplan_update() { // Skal forble avslag + var attributter = lagAttributter(ActionType.UPDATE, ForeldrepengerAttributter.RESOURCE_TYPE_FP_UTTAKSPLAN); + + var resultat = EksternBrukerPolicies.vurderTilgang(attributter, AppRessursData.builder().build()); + assertThat(resultat.fikkTilgang()).isFalse(); + } + + @Test + void tilgang_applikasjon_read() { + var attributter = lagAttributter(ActionType.READ, ForeldrepengerAttributter.RESOURCE_TYPE_FP_APPLIKASJON); + + var resultat = EksternBrukerPolicies.vurderTilgang(attributter, AppRessursData.builder().build()); + assertThat(resultat.fikkTilgang()).isTrue(); + } + + @Test + void avslag_applikasjon_read_med_personer() { + var attributter = lagAttributter(ActionType.READ, ForeldrepengerAttributter.RESOURCE_TYPE_FP_APPLIKASJON); + var ressursdata = AppRessursData.builder().leggTilAktørId("1234567890123").build(); + + var resultat = EksternBrukerPolicies.vurderTilgang(attributter, ressursdata); + assertThat(resultat.fikkTilgang()).isFalse(); + } + + @Test + void avslag_applikasjon_create() { + var attributter = lagAttributter(ActionType.CREATE, ForeldrepengerAttributter.RESOURCE_TYPE_FP_APPLIKASJON); + + var resultat = EksternBrukerPolicies.vurderTilgang(attributter, AppRessursData.builder().build()); + assertThat(resultat.fikkTilgang()).isFalse(); + } + + + private BeskyttetRessursAttributter lagAttributter(ActionType actionType, String resourceType) { + return BeskyttetRessursAttributter.builder() + .medBrukerId("12345678901") + .medIdentType(IdentType.EksternBruker) + .medToken(Token.withOidcToken(BeskyttetRessursInterceptorTest.DUMMY_OPENID_TOKEN)) + .medResourceType(resourceType) + .medActionType(actionType) + .medPepId("local-app") + .medServicePath("/metode") + .medDataAttributter(AbacDataAttributter.opprett()) + .build(); + } +} diff --git a/felles/abac/src/test/java/no/nav/vedtak/sikkerhet/abac/policy/InternBrukerFagsakTest.java b/felles/abac/src/test/java/no/nav/vedtak/sikkerhet/abac/policy/InternBrukerFagsakTest.java new file mode 100644 index 000000000..a42e54f76 --- /dev/null +++ b/felles/abac/src/test/java/no/nav/vedtak/sikkerhet/abac/policy/InternBrukerFagsakTest.java @@ -0,0 +1,242 @@ +package no.nav.vedtak.sikkerhet.abac.policy; + +import static org.assertj.core.api.AssertionsForClassTypes.assertThat; + +import java.util.Set; +import java.util.UUID; + +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.junit.jupiter.MockitoExtension; + +import no.nav.vedtak.sikkerhet.abac.AbacDataAttributter; +import no.nav.vedtak.sikkerhet.abac.Token; +import no.nav.vedtak.sikkerhet.abac.beskyttet.ActionType; +import no.nav.vedtak.sikkerhet.abac.internal.BeskyttetRessursAttributter; +import no.nav.vedtak.sikkerhet.abac.internal.BeskyttetRessursInterceptorTest; +import no.nav.vedtak.sikkerhet.abac.pdp.AppRessursData; +import no.nav.vedtak.sikkerhet.abac.pipdata.PipBehandlingStatus; +import no.nav.vedtak.sikkerhet.abac.pipdata.PipFagsakStatus; +import no.nav.vedtak.sikkerhet.abac.pipdata.PipOverstyring; +import no.nav.vedtak.sikkerhet.kontekst.AnsattGruppe; +import no.nav.vedtak.sikkerhet.kontekst.IdentType; + +@ExtendWith(MockitoExtension.class) +class InternBrukerFagsakTest { + + + @Test + void tilgang_fagsak_read_veileder() { + var attributter = lagAttributter(AnsattGruppe.VEILEDER, ActionType.READ); + var ressurs = AppRessursData.builder() + .medFagsakStatus(PipFagsakStatus.UNDER_BEHANDLING) + .medBehandlingStatus(PipBehandlingStatus.UTREDES) + .medAnsvarligSaksbehandler("veileder") + .build(); + + var resultat = InternBrukerPolicies.vurderTilgang(attributter, ressurs); + assertThat(resultat.fikkTilgang()).isTrue(); + assertThat(resultat.kreverGrupper().isEmpty()).isTrue(); + } + + @Test + void avslå_fagsak_create_veileder() { + var attributter = lagAttributter(AnsattGruppe.VEILEDER, ActionType.CREATE); + var ressurs = AppRessursData.builder() + .medFagsakStatus(PipFagsakStatus.UNDER_BEHANDLING) + .medAnsvarligSaksbehandler("veileder") + .build(); + + var resultat = InternBrukerPolicies.vurderTilgang(attributter, ressurs); + assertThat(resultat.fikkTilgang()).isFalse(); + } + + @Test + void avslå_fagsak_update_veileder() { + var attributter = lagAttributter(AnsattGruppe.VEILEDER, ActionType.UPDATE); + var ressurs = AppRessursData.builder() + .medFagsakStatus(PipFagsakStatus.UNDER_BEHANDLING) + .medBehandlingStatus(PipBehandlingStatus.UTREDES) + .medAnsvarligSaksbehandler("veileder") + .build(); + + var resultat = InternBrukerPolicies.vurderTilgang(attributter, ressurs); + assertThat(resultat.fikkTilgang()).isFalse(); + } + + @Test + void tilgang_fagsak_read() { + var attributter = lagAttributter(AnsattGruppe.SAKSBEHANDLER, ActionType.READ); + var ressurs = AppRessursData.builder() + .medFagsakStatus(PipFagsakStatus.UNDER_BEHANDLING) + .medBehandlingStatus(PipBehandlingStatus.UTREDES) + .medAnsvarligSaksbehandler("saksbehandler") + .build(); + + var resultat = InternBrukerPolicies.vurderTilgang(attributter, ressurs); + assertThat(resultat.fikkTilgang()).isTrue(); + assertThat(resultat.kreverGrupper().isEmpty()).isTrue(); + } + + @Test + void tilgang_fagsak_read1() { + var attributter = lagAttributter(AnsattGruppe.SAKSBEHANDLER, ActionType.READ); + var ressurs = AppRessursData.builder() + .medFagsakStatus(PipFagsakStatus.UNDER_BEHANDLING) + .medAnsvarligSaksbehandler("saksbehandler") + .build(); + + var resultat = InternBrukerPolicies.vurderTilgang(attributter, ressurs); + assertThat(resultat.fikkTilgang()).isTrue(); + assertThat(resultat.kreverGrupper().isEmpty()).isTrue(); + } + + @Test + void tilgang_fagsak_read2() { + var attributter = lagAttributter(AnsattGruppe.SAKSBEHANDLER, ActionType.READ); + var ressurs = AppRessursData.builder() + .medAnsvarligSaksbehandler("saksbehandler") + .build(); + + var resultat = InternBrukerPolicies.vurderTilgang(attributter, ressurs); + assertThat(resultat.fikkTilgang()).isTrue(); + assertThat(resultat.kreverGrupper().isEmpty()).isTrue(); + } + + @Test + void tilgang_fagsak_create() { + var attributter = lagAttributter(AnsattGruppe.SAKSBEHANDLER, ActionType.CREATE); + var ressurs = AppRessursData.builder() + .medFagsakStatus(PipFagsakStatus.UNDER_BEHANDLING) + .medAnsvarligSaksbehandler("saksbehandler") + .build(); + + var resultat = InternBrukerPolicies.vurderTilgang(attributter, ressurs); + assertThat(resultat.fikkTilgang()).isTrue(); + assertThat(resultat.kreverGrupper().isEmpty()).isTrue(); + } + + @Test + void avslag_fagsak_update_uten_status() { + var attributter = lagAttributter(AnsattGruppe.SAKSBEHANDLER, ActionType.UPDATE); + var ressurs = AppRessursData.builder() + .medFagsakStatus(PipFagsakStatus.UNDER_BEHANDLING) + .medAnsvarligSaksbehandler("saksbehandler") + .build(); + + var resultat = InternBrukerPolicies.vurderTilgang(attributter, ressurs); + assertThat(resultat.fikkTilgang()).isFalse(); + } + + @Test + void tillat_fagsak_update_vanlig() { + var attributter = lagAttributter(AnsattGruppe.SAKSBEHANDLER, ActionType.UPDATE); + var ressurs = AppRessursData.builder() + .medFagsakStatus(PipFagsakStatus.UNDER_BEHANDLING) + .medBehandlingStatus(PipBehandlingStatus.UTREDES) + .medAnsvarligSaksbehandler("saksbehandler") + .build(); + + var resultat = InternBrukerPolicies.vurderTilgang(attributter, ressurs); + assertThat(resultat.fikkTilgang()).isTrue(); + assertThat(resultat.kreverGrupper().isEmpty()).isTrue(); + } + + @Test + void tillat_fagsak_update_beslutter() { + var attributter = lagAttributter(AnsattGruppe.SAKSBEHANDLER, ActionType.UPDATE); + var ressurs = AppRessursData.builder() + .medFagsakStatus(PipFagsakStatus.UNDER_BEHANDLING) + .medBehandlingStatus(PipBehandlingStatus.FATTE_VEDTAK) + .medAnsvarligSaksbehandler("saksbehandler") + .build(); + + var resultat = InternBrukerPolicies.vurderTilgang(attributter, ressurs); + assertThat(resultat.fikkTilgang()).isTrue(); + assertThat(resultat.kreverGrupper().contains(AnsattGruppe.BESLUTTER)).isTrue(); + } + + @Test + void avslå_fagsak_update_beslutter_lik_saksbehandler() { + var attributter = lagAttributter(AnsattGruppe.SAKSBEHANDLER, ActionType.UPDATE); + var ressurs = AppRessursData.builder() + .medFagsakStatus(PipFagsakStatus.UNDER_BEHANDLING) + .medBehandlingStatus(PipBehandlingStatus.FATTE_VEDTAK) + .medAnsvarligSaksbehandler("IBRUKER") + .build(); + + var resultat = InternBrukerPolicies.vurderTilgang(attributter, ressurs); + assertThat(resultat.fikkTilgang()).isFalse(); + } + + @Test + void tillat_fagsak_update_overstyr() { + var attributter = lagAttributter(AnsattGruppe.SAKSBEHANDLER, ActionType.UPDATE); + var ressurs = AppRessursData.builder() + .medFagsakStatus(PipFagsakStatus.UNDER_BEHANDLING) + .medBehandlingStatus(PipBehandlingStatus.UTREDES) + .medAnsvarligSaksbehandler("saksbehandler") + .medOverstyring(PipOverstyring.OVERSTYRING) + .build(); + + var resultat = InternBrukerPolicies.vurderTilgang(attributter, ressurs); + assertThat(resultat.fikkTilgang()).isTrue(); + assertThat(resultat.kreverGrupper().contains(AnsattGruppe.OVERSTYRER)).isTrue(); + } + + @Test + void avslå_fagsak_update_overstyr_fved() { + var attributter = lagAttributter(AnsattGruppe.SAKSBEHANDLER, ActionType.UPDATE); + var ressurs = AppRessursData.builder() + .medFagsakStatus(PipFagsakStatus.UNDER_BEHANDLING) + .medBehandlingStatus(PipBehandlingStatus.FATTE_VEDTAK) + .medAnsvarligSaksbehandler("saksbehandler") + .medOverstyring(PipOverstyring.OVERSTYRING) + .build(); + + var resultat = InternBrukerPolicies.vurderTilgang(attributter, ressurs); + assertThat(resultat.fikkTilgang()).isFalse(); + } + + @Test + void avslå_fagsak_update_overstyr_opprett() { + var attributter = lagAttributter(AnsattGruppe.SAKSBEHANDLER, ActionType.UPDATE); + var ressurs = AppRessursData.builder() + .medFagsakStatus(PipFagsakStatus.UNDER_BEHANDLING) + .medBehandlingStatus(PipBehandlingStatus.OPPRETTET) + .medAnsvarligSaksbehandler("saksbehandler") + .medOverstyring(PipOverstyring.OVERSTYRING) + .build(); + + var resultat = InternBrukerPolicies.vurderTilgang(attributter, ressurs); + assertThat(resultat.fikkTilgang()).isFalse(); + } + + @Test + void avslag_fagsak_delete() { + var attributter = lagAttributter(AnsattGruppe.SAKSBEHANDLER, ActionType.DELETE); + var ressurs = AppRessursData.builder() + .medFagsakStatus(PipFagsakStatus.UNDER_BEHANDLING) + .medBehandlingStatus(PipBehandlingStatus.UTREDES) + .medAnsvarligSaksbehandler("saksbehandler") + .build(); + + var resultat = InternBrukerPolicies.vurderTilgang(attributter, ressurs); + assertThat(resultat.fikkTilgang()).isFalse(); + } + + private BeskyttetRessursAttributter lagAttributter(AnsattGruppe ansattGruppe, ActionType actionType) { + return BeskyttetRessursAttributter.builder() + .medBrukerId("IBRUKER") + .medBrukerOid(UUID.randomUUID()) + .medIdentType(IdentType.InternBruker) + .medAnsattGrupper(Set.of(ansattGruppe)) + .medToken(Token.withOidcToken(BeskyttetRessursInterceptorTest.DUMMY_OPENID_TOKEN)) + .medResourceType(ForeldrepengerAttributter.RESOURCE_TYPE_FP_FAGSAK) + .medActionType(actionType) + .medPepId("local-app") + .medServicePath("/metode") + .medDataAttributter(AbacDataAttributter.opprett()) + .build(); + } +} diff --git a/felles/abac/src/test/java/no/nav/vedtak/sikkerhet/abac/policy/InternBrukerTest.java b/felles/abac/src/test/java/no/nav/vedtak/sikkerhet/abac/policy/InternBrukerTest.java new file mode 100644 index 000000000..34f907ac9 --- /dev/null +++ b/felles/abac/src/test/java/no/nav/vedtak/sikkerhet/abac/policy/InternBrukerTest.java @@ -0,0 +1,195 @@ +package no.nav.vedtak.sikkerhet.abac.policy; + +import static org.assertj.core.api.AssertionsForClassTypes.assertThat; + +import java.util.Set; +import java.util.UUID; + +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.junit.jupiter.MockitoExtension; + +import no.nav.vedtak.sikkerhet.abac.AbacDataAttributter; +import no.nav.vedtak.sikkerhet.abac.Token; +import no.nav.vedtak.sikkerhet.abac.beskyttet.ActionType; +import no.nav.vedtak.sikkerhet.abac.internal.BeskyttetRessursAttributter; +import no.nav.vedtak.sikkerhet.abac.internal.BeskyttetRessursInterceptorTest; +import no.nav.vedtak.sikkerhet.abac.pdp.AppRessursData; +import no.nav.vedtak.sikkerhet.abac.pdp.ForeldrepengerDataKeys; +import no.nav.vedtak.sikkerhet.kontekst.AnsattGruppe; +import no.nav.vedtak.sikkerhet.kontekst.IdentType; + +@ExtendWith(MockitoExtension.class) +class InternBrukerTest { + + @Test + void tilgang_applikasjon_read() { + var attributter = lagAttributter(AnsattGruppe.VEILEDER, ActionType.READ, ForeldrepengerAttributter.RESOURCE_TYPE_FP_APPLIKASJON); + + var resultat = InternBrukerPolicies.vurderTilgang(attributter, AppRessursData.builder().build()); + assertThat(resultat.fikkTilgang()).isTrue(); + assertThat(resultat.kreverGrupper().isEmpty()).isTrue(); + } + + @Test + void avslag_applikasjon_read_med_personer() { + var attributter = lagAttributter(AnsattGruppe.SAKSBEHANDLER, ActionType.READ, ForeldrepengerAttributter.RESOURCE_TYPE_FP_APPLIKASJON); + var ressursdata = AppRessursData.builder().leggTilAktørId("1234567890123").build(); + + var resultat = InternBrukerPolicies.vurderTilgang(attributter, ressursdata); + assertThat(resultat.fikkTilgang()).isFalse(); + } + + @Test + void avslag_applikasjon_create() { + var attributter = lagAttributter(AnsattGruppe.VEILEDER, ActionType.CREATE, ForeldrepengerAttributter.RESOURCE_TYPE_FP_APPLIKASJON); + + var resultat = InternBrukerPolicies.vurderTilgang(attributter, AppRessursData.builder().build()); + assertThat(resultat.fikkTilgang()).isFalse(); + } + + @Test + void tilgang_drift_read() { + var attributter = lagAttributter(AnsattGruppe.SAKSBEHANDLER, ActionType.READ, ForeldrepengerAttributter.RESOURCE_TYPE_FP_DRIFT); + + var resultat = InternBrukerPolicies.vurderTilgang(attributter, AppRessursData.builder().build()); + assertThat(resultat.fikkTilgang()).isTrue(); + assertThat(resultat.kreverGrupper().contains(AnsattGruppe.DRIFT)).isTrue(); + } + + @Test + void tilgang_drift_create() { + var attributter = lagAttributter(AnsattGruppe.VEILEDER, ActionType.CREATE, ForeldrepengerAttributter.RESOURCE_TYPE_FP_DRIFT); + + var resultat = InternBrukerPolicies.vurderTilgang(attributter, AppRessursData.builder().build()); + assertThat(resultat.fikkTilgang()).isTrue(); + assertThat(resultat.kreverGrupper().contains(AnsattGruppe.DRIFT)).isTrue(); + } + + @Test + void avslå_drift_update() { + var attributter = lagAttributter(AnsattGruppe.VEILEDER, ActionType.UPDATE, ForeldrepengerAttributter.RESOURCE_TYPE_FP_DRIFT); + + var resultat = InternBrukerPolicies.vurderTilgang(attributter, AppRessursData.builder().build()); + assertThat(resultat.fikkTilgang()).isFalse(); + } + + @Test + void avslå_ventefrist_read() { + var attributter = lagAttributter(AnsattGruppe.SAKSBEHANDLER, ActionType.CREATE, ForeldrepengerAttributter.RESOURCE_TYPE_FP_VENTEFRIST); + + var resultat = InternBrukerPolicies.vurderTilgang(attributter, AppRessursData.builder().build()); + assertThat(resultat.fikkTilgang()).isFalse(); + } + + @Test + void tilgang_ventefrist_update_veileder() { + var attributter = lagAttributter(AnsattGruppe.VEILEDER, ActionType.UPDATE, ForeldrepengerAttributter.RESOURCE_TYPE_FP_VENTEFRIST); + + var resultat = InternBrukerPolicies.vurderTilgang(attributter, AppRessursData.builder().build()); + assertThat(resultat.fikkTilgang()).isTrue(); + assertThat(resultat.kreverGrupper().isEmpty()).isTrue(); + } + + @Test + void tilgang_ventefrist_update_saksbehandler() { + var attributter = lagAttributter(AnsattGruppe.SAKSBEHANDLER, ActionType.UPDATE, ForeldrepengerAttributter.RESOURCE_TYPE_FP_VENTEFRIST); + + var resultat = InternBrukerPolicies.vurderTilgang(attributter, AppRessursData.builder().build()); + assertThat(resultat.fikkTilgang()).isTrue(); + assertThat(resultat.kreverGrupper().isEmpty()).isTrue(); + } + + @Test + void tilgang_risiko_read() { + var attributter = lagAttributter(AnsattGruppe.VEILEDER, ActionType.READ, ForeldrepengerAttributter.RESOURCE_TYPE_FP_RISIKOKLASSIFISERING); + + var resultat = InternBrukerPolicies.vurderTilgang(attributter, AppRessursData.builder().build()); + assertThat(resultat.fikkTilgang()).isTrue(); + } + + @Test + void tilgang_risiko_create() { + var attributter = lagAttributter(AnsattGruppe.SAKSBEHANDLER, ActionType.CREATE, ForeldrepengerAttributter.RESOURCE_TYPE_FP_RISIKOKLASSIFISERING); + + var resultat = InternBrukerPolicies.vurderTilgang(attributter, AppRessursData.builder().build()); + assertThat(resultat.fikkTilgang()).isTrue(); + assertThat(resultat.kreverGrupper().isEmpty()).isTrue(); + } + + @Test + void tilgang_risiko_update() { + var attributter = lagAttributter(AnsattGruppe.VEILEDER, ActionType.UPDATE, ForeldrepengerAttributter.RESOURCE_TYPE_FP_RISIKOKLASSIFISERING); + + var resultat = InternBrukerPolicies.vurderTilgang(attributter, AppRessursData.builder().build()); + assertThat(resultat.fikkTilgang()).isTrue(); + assertThat(resultat.kreverGrupper().isEmpty()).isTrue(); + } + + @Test + void tilgang_oppgavestyrer_read() { + var attributter = lagAttributter(AnsattGruppe.SAKSBEHANDLER, ActionType.READ, ForeldrepengerAttributter.RESOURCE_TYPE_FP_OPPGAVESTYRING); + + var resultat = InternBrukerPolicies.vurderTilgang(attributter, AppRessursData.builder().build()); + assertThat(resultat.fikkTilgang()).isTrue(); + assertThat(resultat.kreverGrupper().contains(AnsattGruppe.OPPGAVESTYRER)).isTrue(); + } + + @Test + void tilgang_oppgavestyrer_update() { + var attributter = lagAttributter(AnsattGruppe.VEILEDER, ActionType.UPDATE, ForeldrepengerAttributter.RESOURCE_TYPE_FP_OPPGAVESTYRING); + + var resultat = InternBrukerPolicies.vurderTilgang(attributter, AppRessursData.builder().build()); + assertThat(resultat.fikkTilgang()).isTrue(); + assertThat(resultat.kreverGrupper().contains(AnsattGruppe.OPPGAVESTYRER)).isTrue(); + } + + + @Test + void tilgang_avdelingenhet_create() { + var attributter = lagAttributter(AnsattGruppe.SAKSBEHANDLER, ActionType.CREATE, ForeldrepengerAttributter.RESOURCE_TYPE_FP_AVDELINGENHET); + var ressurs = AppRessursData.builder().leggTilRessurs(ForeldrepengerDataKeys.AVDELING_ENHET, "4867").build(); + + var resultat = InternBrukerPolicies.vurderTilgang(attributter, ressurs); + assertThat(resultat.fikkTilgang()).isTrue(); + assertThat(resultat.kreverGrupper().contains(AnsattGruppe.OPPGAVESTYRER)).isTrue(); + assertThat(resultat.kreverGrupper().contains(AnsattGruppe.STRENGTFORTROLIG)).isFalse(); + } + + @Test + void tilgang_avdelingenhet_delete() { + var attributter = lagAttributter(AnsattGruppe.VEILEDER, ActionType.DELETE, ForeldrepengerAttributter.RESOURCE_TYPE_FP_AVDELINGENHET); + var ressurs = AppRessursData.builder().leggTilRessurs(ForeldrepengerDataKeys.AVDELING_ENHET, "4867").build(); + + var resultat = InternBrukerPolicies.vurderTilgang(attributter, ressurs); + assertThat(resultat.fikkTilgang()).isTrue(); + assertThat(resultat.kreverGrupper().contains(AnsattGruppe.OPPGAVESTYRER)).isTrue(); + assertThat(resultat.kreverGrupper().contains(AnsattGruppe.STRENGTFORTROLIG)).isFalse(); + } + + @Test + void tilgang_avdelingenhet_update_sf() { + var attributter = lagAttributter(AnsattGruppe.SAKSBEHANDLER, ActionType.UPDATE, ForeldrepengerAttributter.RESOURCE_TYPE_FP_AVDELINGENHET); + var ressurs = AppRessursData.builder().leggTilRessurs(ForeldrepengerDataKeys.AVDELING_ENHET, "2103").build(); + + var resultat = InternBrukerPolicies.vurderTilgang(attributter, ressurs);assertThat(resultat.fikkTilgang()).isTrue(); + assertThat(resultat.kreverGrupper().contains(AnsattGruppe.OPPGAVESTYRER)).isTrue(); + assertThat(resultat.kreverGrupper().contains(AnsattGruppe.STRENGTFORTROLIG)).isTrue(); + } + + + private BeskyttetRessursAttributter lagAttributter(AnsattGruppe ansattGruppe, ActionType actionType, String resourceType) { + return BeskyttetRessursAttributter.builder() + .medBrukerId("12345678901") + .medBrukerOid(UUID.randomUUID()) + .medIdentType(IdentType.InternBruker) + .medAnsattGrupper(Set.of(ansattGruppe)) + .medToken(Token.withOidcToken(BeskyttetRessursInterceptorTest.DUMMY_OPENID_TOKEN)) + .medResourceType(resourceType) + .medActionType(actionType) + .medPepId("local-app") + .medServicePath("/metode") + .medDataAttributter(AbacDataAttributter.opprett()) + .build(); + } +} diff --git a/felles/abac/src/test/java/no/nav/vedtak/sikkerhet/abac/policy/SystemressursTest.java b/felles/abac/src/test/java/no/nav/vedtak/sikkerhet/abac/policy/SystemressursTest.java new file mode 100644 index 000000000..046099b19 --- /dev/null +++ b/felles/abac/src/test/java/no/nav/vedtak/sikkerhet/abac/policy/SystemressursTest.java @@ -0,0 +1,116 @@ +package no.nav.vedtak.sikkerhet.abac.policy; + +import static org.assertj.core.api.AssertionsForClassTypes.assertThat; + +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.junit.jupiter.MockitoExtension; + +import no.nav.foreldrepenger.konfig.Namespace; +import no.nav.vedtak.sikkerhet.abac.AbacDataAttributter; +import no.nav.vedtak.sikkerhet.abac.Token; +import no.nav.vedtak.sikkerhet.abac.beskyttet.ActionType; +import no.nav.vedtak.sikkerhet.abac.beskyttet.AvailabilityType; +import no.nav.vedtak.sikkerhet.abac.internal.BeskyttetRessursAttributter; +import no.nav.vedtak.sikkerhet.abac.internal.BeskyttetRessursInterceptorTest; +import no.nav.vedtak.sikkerhet.abac.pdp.AppRessursData; +import no.nav.vedtak.sikkerhet.abac.pipdata.PipBehandlingStatus; +import no.nav.vedtak.sikkerhet.kontekst.IdentType; +import no.nav.vedtak.sikkerhet.oidc.config.AzureProperty; + +@ExtendWith(MockitoExtension.class) +class SystemressursTest { + + private static final String LOCAL_APP = "vtp:" + Namespace.foreldrepenger().getName() + ":application"; + + @BeforeAll + static void initEnv() { + System.setProperty(AzureProperty.AZURE_APP_PRE_AUTHORIZED_APPS.name(), LOCAL_APP + ", vtp:annetnamespace:eksternapplication"); + } + + @AfterAll + static void avsluttEnv() { + System.clearProperty(AzureProperty.AZURE_APP_PRE_AUTHORIZED_APPS.name()); + } + + + @Test + void skal_gi_tilgang_for_intern_azure_cc() { + var attributter = lagBeskyttetRessursAttributterAzure(AvailabilityType.INTERNAL, LOCAL_APP); + + var resultat = SystemressursPolicies.vurderTilgang(attributter, AppRessursData.builder().build()); + assertThat(resultat.fikkTilgang()).isTrue(); + } + + @Test + void skal_gi_avslag_for_ekstern_azure_cc() { + var attributter = lagBeskyttetRessursAttributterAzure(AvailabilityType.INTERNAL, "vtp:annetnamespace:ukjentapplication"); + + var resultat = SystemressursPolicies.vurderTilgang(attributter, AppRessursData.builder().build()); + assertThat(resultat.fikkTilgang()).isFalse(); + } + + @Test + void skal_gi_avslag_for_godkjent_ekstern_azure_cc_men_i_feil_klusterklasse() { + var attributter = lagBeskyttetRessursAttributterAzure(AvailabilityType.INTERNAL, "vtp:annetnamespace:eksternapplication"); + + var resultat = SystemressursPolicies.vurderTilgang(attributter, AppRessursData.builder().build()); + assertThat(resultat.fikkTilgang()).isFalse(); + } + + + @Test + void skal_gi_tilgang_for_godkjent_ekstern_azure_cc() { + var attributter = lagBeskyttetRessursAttributterAzure(AvailabilityType.ALL, "vtp:annetnamespace:eksternapplication"); + + var resultat = SystemressursPolicies.vurderTilgang(attributter, AppRessursData.builder().build()); + assertThat(resultat.fikkTilgang()).isTrue(); + } + + @Test + void godta_fagsak_update_med_beh_status() { + var attributter = lagBeskyttetRessursAttributter(); + var appressursData = AppRessursData.builder().medBehandlingStatus(PipBehandlingStatus.UTREDES).build(); + + var resultat = SystemressursPolicies.vurderTilgang(attributter, appressursData); + assertThat(resultat.fikkTilgang()).isTrue(); + } + + @Test + void avslå_fagsak_update_uten_beh_status() { + var attributter = lagBeskyttetRessursAttributter(); + var appressursData = AppRessursData.builder().build(); + + var resultat = SystemressursPolicies.vurderTilgang(attributter, appressursData); + assertThat(resultat.fikkTilgang()).isFalse(); + } + + private BeskyttetRessursAttributter lagBeskyttetRessursAttributter() { + return BeskyttetRessursAttributter.builder() + .medBrukerId(LOCAL_APP) + .medIdentType(IdentType.Systemressurs) + .medToken(Token.withOidcToken(BeskyttetRessursInterceptorTest.DUMMY_OPENID_TOKEN)) + .medResourceType(ForeldrepengerAttributter.RESOURCE_TYPE_FP_FAGSAK) + .medActionType(ActionType.UPDATE) + .medPepId("local-app") + .medServicePath("/metode") + .medDataAttributter(AbacDataAttributter.opprett()) + .build(); + } + + private BeskyttetRessursAttributter lagBeskyttetRessursAttributterAzure(AvailabilityType availabilityType, String brukerId) { + return BeskyttetRessursAttributter.builder() + .medBrukerId(brukerId) + .medIdentType(IdentType.Systemressurs) + .medToken(Token.withOidcToken(BeskyttetRessursInterceptorTest.DUMMY_OPENID_TOKEN)) + .medResourceType(ForeldrepengerAttributter.RESOURCE_TYPE_FP_APPLIKASJON) + .medActionType(ActionType.READ) + .medAvailabilityType(availabilityType) + .medPepId("local-app") + .medServicePath("/metode") + .medDataAttributter(AbacDataAttributter.opprett()) + .build(); + } +} diff --git a/felles/abac/src/test/java/no/nav/vedtak/sikkerhet/pdp/PdpKlientImplTest.java b/felles/abac/src/test/java/no/nav/vedtak/sikkerhet/pdp/PdpKlientImplTest.java index 17f88ac3f..c79e5ca63 100644 --- a/felles/abac/src/test/java/no/nav/vedtak/sikkerhet/pdp/PdpKlientImplTest.java +++ b/felles/abac/src/test/java/no/nav/vedtak/sikkerhet/pdp/PdpKlientImplTest.java @@ -56,7 +56,7 @@ public void setUp() { @Test void kallPdpUtenFnrResourceHvisPersonlisteErTom() { - var idToken = Token.withOidcToken(JWT_TOKEN, "TEST", IdentType.InternBruker); + var idToken = Token.withOidcToken(JWT_TOKEN); var responseWrapper = createResponse("xacmlresponse.json"); var captor = ArgumentCaptor.forClass(XacmlRequest.class); @@ -71,7 +71,7 @@ void kallPdpUtenFnrResourceHvisPersonlisteErTom() { @Test void kallPdpMedJwtTokenBodyNårIdTokenErJwtToken() { - var idToken = Token.withOidcToken(JWT_TOKEN, "TEST", IdentType.InternBruker); + var idToken = Token.withOidcToken(JWT_TOKEN); var responseWrapper = createResponse("xacmlresponse.json"); var captor = ArgumentCaptor.forClass(XacmlRequest.class); @@ -86,7 +86,7 @@ void kallPdpUtenFnrResourceHvisPersonlisteErTom() { @Test void kallPdpMedJwtTokenBodyNårIdTokenErTokeXToken() { - var idToken = Token.withOidcToken(JWT_TOKENX_TOKEN, "TEST", IdentType.InternBruker); + var idToken = Token.withOidcToken(JWT_TOKENX_TOKEN); var responseWrapper = createResponse("xacmlresponse.json"); var captor = ArgumentCaptor.forClass(XacmlRequest.class); @@ -101,7 +101,7 @@ void kallPdpUtenFnrResourceHvisPersonlisteErTom() { @Test void kallPdpMedFlereAttributtSettNårPersonlisteStørreEnn1() { - var idToken = Token.withOidcToken(JWT_TOKEN, "TEST", IdentType.InternBruker); + var idToken = Token.withOidcToken(JWT_TOKEN); var responseWrapper = createResponse("xacml3response.json"); var captor = ArgumentCaptor.forClass(XacmlRequest.class); @@ -124,7 +124,7 @@ void kallPdpUtenFnrResourceHvisPersonlisteErTom() { @Test void kallPdpMedFlereAttributtSettNårPersonlisteStørreEnn2() { - var idToken = Token.withOidcToken(JWT_TOKEN, "TEST", IdentType.InternBruker); + var idToken = Token.withOidcToken(JWT_TOKEN); var responseWrapper = createResponse("xacmlresponse-array.json"); var captor = ArgumentCaptor.forClass(XacmlRequest.class); @@ -147,7 +147,7 @@ void kallPdpUtenFnrResourceHvisPersonlisteErTom() { @Test void sporingsloggListeSkalHaSammeRekkefølgePåidenterSomXacmlRequest() { - var idToken = Token.withOidcToken(JWT_TOKEN, "TEST", IdentType.InternBruker); + var idToken = Token.withOidcToken(JWT_TOKEN); var responseWrapper = createResponse("xacml3response.json"); var captor = ArgumentCaptor.forClass(XacmlRequest.class); @@ -178,7 +178,7 @@ void kallPdpUtenFnrResourceHvisPersonlisteErTom() { @Test void skal_bare_ta_med_deny_advice() { - var idToken = Token.withOidcToken(JWT_TOKENX_TOKEN, "meg", IdentType.EksternBruker); + var idToken = Token.withOidcToken(JWT_TOKENX_TOKEN); var responseWrapper = createResponse("xacmlresponse_1deny_1permit.json"); var captor = ArgumentCaptor.forClass(XacmlRequest.class); @@ -188,7 +188,7 @@ void skal_bare_ta_med_deny_advice() { personnr.add("12345678900"); personnr.add("07078515206"); - var felles = lagBeskyttetRessursAttributter(idToken, AbacDataAttributter.opprett()); + var felles = lagBeskyttetRessursAttributter(idToken, AbacDataAttributter.opprett(), IdentType.EksternBruker); var ressurs = AppRessursData.builder().leggTilFødselsnumre(personnr).build(); var resultat = pdpKlient.forespørTilgang(felles, DOMENE, ressurs); @@ -211,7 +211,7 @@ private void assertHasAttribute(List attributes, String @Test void skalFeileVedUkjentObligation() { - var idToken = Token.withOidcToken(new OpenIDToken(OpenIDProvider.TOKENX, new TokenString("OIDC")), "OIDC", IdentType.InternBruker); + var idToken = Token.withOidcToken(new OpenIDToken(OpenIDProvider.TOKENX, new TokenString("OIDC"))); var responseWrapper = createResponse("xacmlresponse_multiple_obligation.json"); when(pdpConsumerMock.evaluate(any(XacmlRequest.class))).thenReturn(responseWrapper); @@ -229,7 +229,7 @@ void skalFeileVedUkjentObligation() { @Test void skal_håndtere_blanding_av_fnr_og_aktør_id() { - var idToken = Token.withOidcToken(JWT_TOKEN, "TEST", IdentType.InternBruker); + var idToken = Token.withOidcToken(JWT_TOKEN); var responseWrapper = createResponse("xacml3response.json"); var captor = ArgumentCaptor.forClass(XacmlRequest.class); @@ -253,8 +253,15 @@ void skalFeileVedUkjentObligation() { } private BeskyttetRessursAttributter lagBeskyttetRessursAttributter(Token token, AbacDataAttributter dataAttributter) { + return lagBeskyttetRessursAttributter(token, dataAttributter, IdentType.InternBruker); + } + + private BeskyttetRessursAttributter lagBeskyttetRessursAttributter(Token token, + AbacDataAttributter dataAttributter, + IdentType identType) { return BeskyttetRessursAttributter.builder() - .medUserId("IDENT") + .medBrukerId("IDENT") + .medIdentType(identType) .medToken(token) .medResourceType(ForeldrepengerAttributter.RESOURCE_TYPE_FP_FAGSAK) .medActionType(ActionType.READ) @@ -280,7 +287,7 @@ void lese_sammenligne_request() throws IOException { File file = new File(getClass().getClassLoader().getResource("request.json").getFile()); var target = DefaultJsonMapper.getObjectMapper().readValue(file, XacmlRequest.class); - var felles = lagBeskyttetRessursAttributter(Token.withOidcToken(JWT_TOKEN, "TEST", IdentType.InternBruker), AbacDataAttributter.opprett()); + var felles = lagBeskyttetRessursAttributter(Token.withOidcToken(JWT_TOKEN), AbacDataAttributter.opprett()); var ressurs = AppRessursData.builder().leggTilAktørId("11111").leggTilFødselsnummer("12345678900").build(); var request = XacmlRequestMapper.lagXacmlRequest(felles, DOMENE, ressurs); diff --git a/felles/oidc/src/main/java/no/nav/vedtak/sikkerhet/kontekst/RequestKontekstProvider.java b/felles/oidc/src/main/java/no/nav/vedtak/sikkerhet/kontekst/RequestKontekstProvider.java index f1a883c09..de73ee69b 100644 --- a/felles/oidc/src/main/java/no/nav/vedtak/sikkerhet/kontekst/RequestKontekstProvider.java +++ b/felles/oidc/src/main/java/no/nav/vedtak/sikkerhet/kontekst/RequestKontekstProvider.java @@ -1,9 +1,10 @@ package no.nav.vedtak.sikkerhet.kontekst; -import no.nav.vedtak.sikkerhet.oidc.token.OpenIDToken; - +import java.util.Set; import java.util.UUID; +import no.nav.vedtak.sikkerhet.oidc.token.OpenIDToken; + public interface RequestKontekstProvider extends KontekstProvider { default OpenIDToken getToken() { @@ -14,4 +15,8 @@ default UUID getOid() { return getKontekst() instanceof RequestKontekst tk ? tk.getOid() : null; } + default Set getAnsattGrupper() { + return getKontekst() instanceof RequestKontekst tk ? tk.getGrupper() : Set.of(); + } + }