Skip to content

Commit

Permalink
OK-751 käyttäjän oikeudet sessioon WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
marjakari committed Nov 27, 2024
1 parent 7e18743 commit 2bc85c4
Show file tree
Hide file tree
Showing 9 changed files with 138 additions and 45 deletions.
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package fi.oph.viestinvalitys.raportointi.configuration

import com.zaxxer.hikari.HikariDataSource
import fi.oph.viestinvalitys.raportointi.App
import fi.oph.viestinvalitys.raportointi.resource.RaportointiAPIConstants
import fi.oph.viestinvalitys.util.DbUtil
import fi.vm.sade.javautils.kayttooikeusclient.OphUserDetailsServiceImpl
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import fi.oph.viestinvalitys.util.ConfigurationUtil
import fi.vm.sade.javautils.nio.cas.{CasClient, CasClientBuilder}
import org.asynchttpclient.RequestBuilder
import org.slf4j.LoggerFactory
import upickle.default.*

import java.util.concurrent.TimeUnit
import scala.concurrent.Await
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ class OrganisaatioCache {

val childOidsLoader = new CacheLoader[String, Response[String]] {
def load(oid: String): Response[String] =
LOG.info(s"Ladataan lapsiorganisaatio-cache oidille $oid")
val uri: Uri = uri"https://virkailija.$opintopolkuDomain/organisaatio-service/api/$oid/childoids?$queryParams"
quickRequest
.headers(headers)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ class OrganisaatioService {
val LOG = LoggerFactory.getLogger(classOf[OrganisaatioService])

def getAllChildOidsFlat(oid: String): Set[String] =
LOG.info(s"Haetaan lapsiorganisaatiot cachesta oidille $oid")
if (!OrganisaatioOid.isValid(oid))
LOG.error(s"Organisaation oid $oid on virheellinen")
throw new RuntimeException(s"Organisaation oid $oid on virheellinen")
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
package fi.oph.viestinvalitys.raportointi.resource

import fi.oph.viestinvalitys.raportointi.integration.{ONRService}
import fi.oph.viestinvalitys.raportointi.integration.ONRService
import fi.oph.viestinvalitys.raportointi.security.SecurityOperaatiot
import io.swagger.v3.oas.annotations.Operation
import io.swagger.v3.oas.annotations.responses.ApiResponse
import io.swagger.v3.oas.annotations.tags.Tag
import jakarta.servlet.http.{HttpServletRequest, HttpSession}
import org.slf4j.LoggerFactory
import org.springframework.http.{HttpStatus, MediaType, ResponseEntity}
import org.springframework.web.bind.annotation.{GetMapping, RequestMapping, RestController}
Expand All @@ -27,8 +28,10 @@ class HenkiloResource {
responses = Array(
new ApiResponse(responseCode = "200", description = "Palauttaa asiointikielen"),
))
def getAsiointikieli() = {
def getAsiointikieli(request: HttpServletRequest) = {
LOG.info("Haetaan asiointikieli")
val session: HttpSession = request.getSession(false)
LOG.warn(s"sessio: ${session}")
val securityOperaatiot = new SecurityOperaatiot
val result = OnrService.haeAsiointikieli(securityOperaatiot.getIdentiteetti())
result match
Expand Down

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
package fi.oph.viestinvalitys.raportointi.security

import fi.oph.viestinvalitys.business.Kayttooikeus
import fi.oph.viestinvalitys.business.{KantaOperaatiot, Kayttooikeus}
import fi.oph.viestinvalitys.raportointi.integration.OrganisaatioService
import fi.oph.viestinvalitys.raportointi.security.SecurityConstants.OPH_ORGANISAATIO_OID
import fi.oph.viestinvalitys.util.DbUtil
import jakarta.servlet.http.HttpSession
import org.slf4j.LoggerFactory
import org.springframework.security.core.context.SecurityContextHolder

Expand All @@ -27,11 +29,13 @@ object SecurityConstants {
}

class SecurityOperaatiot(
getOikeudet: () => Seq[String] = () => SecurityContextHolder.getContext.getAuthentication.getAuthorities.asScala.map(a => a.getAuthority).toSeq,
getUsername: () => String = () => SecurityContextHolder.getContext.getAuthentication.getName(),
organisaatioClient: OrganisaatioService = OrganisaatioService) {
getOikeudet: () => Seq[String] = () => SecurityContextHolder.getContext.getAuthentication.getAuthorities.asScala.map(a => a.getAuthority).toSeq,
getUsername: () => String = () => SecurityContextHolder.getContext.getAuthentication.getName(),
organisaatioClient: OrganisaatioService = OrganisaatioService,
optionalHttpSession: Option[HttpSession] = None) {

val LOG = LoggerFactory.getLogger(classOf[SecurityOperaatiot])
val kantaOperaatiot = new KantaOperaatiot(DbUtil.database)
final val SECURITY_ROOLI_PREFIX_PATTERN = "^ROLE_"
private lazy val kayttajanCasOikeudet: Set[Kayttooikeus] = {
getOikeudet()
Expand All @@ -50,14 +54,44 @@ class SecurityOperaatiot(
if(onPaakayttaja())
kayttajanCasOikeudet // ei tarvitse mapata kaikkia lapsiorganisaatioita
else
val lapsioikeudet = kayttajanCasOikeudet
.filter(kayttajanOikeus => kayttajanOikeus.organisaatio.isDefined)
.map(kayttajanOikeus =>
organisaatioClient.getAllChildOidsFlat(kayttajanOikeus.organisaatio.get)
.map(o => Kayttooikeus(kayttajanOikeus.oikeus, Some(o)))
).flatten
kayttajanCasOikeudet ++ lapsioikeudet
optionalHttpSession match {
case Some(n) if optionalHttpSession.get.getAttribute("kayttooikeudet") != null =>
LOG.warn("oikat sessiosta!")
getSetOfKayttooikeusFromSession(optionalHttpSession.get, "kayttooikeudet").getOrElse(Set.empty)
case _ =>
LOG.warn("parsitaan oikat!")
LOG.info("Haetaan käyttöoikeuksien organisaatioiden aliorganisaatiot")
val lapsioikeudet = kayttajanCasOikeudet
.filter(kayttajanOikeus => kayttajanOikeus.organisaatio.isDefined)
.map(kayttajanOikeus =>
organisaatioClient.getAllChildOidsFlat(kayttajanOikeus.organisaatio.get)
.map(o => Kayttooikeus(kayttajanOikeus.oikeus, Some(o)))).flatten
if(optionalHttpSession.isDefined)
optionalHttpSession.get.setAttribute("kayttooikeudet", kayttajanCasOikeudet ++ lapsioikeudet)
kayttajanCasOikeudet ++ lapsioikeudet
}
}

private lazy val kayttajanKayttooikeustunnisteet: Option[Set[Int]] = {
val pk = onPaakayttaja()
if (onPaakayttaja())
Option.empty
else
optionalHttpSession match {
case None =>
LOG.warn("ei sessiota, oikkatunnisteet kannasta!")
Option.apply(kantaOperaatiot.getKayttooikeusTunnisteet(kayttajanOikeudet.toSeq))
case Some(n) if optionalHttpSession.get.getAttribute("kayttooikeustunnisteet") != null =>
LOG.warn("oikkatunnisteet sessiosta!")
getSetOfIntsFromSession(optionalHttpSession.get, "kayttooikeustunnisteet")
case _ =>
LOG.warn("oikkatunnisteet kannasta ja laitetaan sessioon!")
val tunnisteet = kantaOperaatiot.getKayttooikeusTunnisteet(kayttajanOikeudet.toSeq)
optionalHttpSession.get.setAttribute("kayttooikeustunnisteet", tunnisteet)
Some(tunnisteet)
}
}

val identiteetti = getUsername()

def getIdentiteetti(): String =
Expand Down Expand Up @@ -93,9 +127,31 @@ class SecurityOperaatiot(

def getKayttajanOikeudet(): Set[Kayttooikeus] = kayttajanOikeudet

def getKayttajanKayttooikeustunnisteet(): Option[Set[Int]] = kayttajanKayttooikeustunnisteet

/**
* Palauttaa käyttäjän käyttöoikeuksien organisaatiot ilman lapsihierarkiaa
*/
def getCasOrganisaatiot(): Set[String] =
kayttajanCasOikeudet.filter(kayttooikeus => kayttooikeus.organisaatio.isDefined).map(ko => ko.organisaatio.get)

def getSetOfIntsFromSession(session: HttpSession, attributeName: String): Option[Set[Int]] = {
Option(session.getAttribute(attributeName)) match {
case Some(value: Set[_]) =>
// Safely cast elements to Int, filter out invalid ones
Some(value.collect { case i: Int => i })
case _ =>
None
}
}

def getSetOfKayttooikeusFromSession(session: HttpSession, attributeName: String): Option[Set[Kayttooikeus]] = {
Option(session.getAttribute(attributeName)) match {
case Some(value: Set[_]) =>
// Safely cast elements to Kayttooikeus, filter out invalid ones
Some(value.collect { case i: Kayttooikeus => i })
case _ =>
None
}
}
}
Original file line number Diff line number Diff line change
@@ -1,15 +1,18 @@
package fi.oph.viestinvalitys.raportointi

import fi.oph.viestinvalitys.business.Kayttooikeus
import fi.oph.viestinvalitys.business.{KantaOperaatiot, Kayttooikeus}
import fi.oph.viestinvalitys.raportointi.integration.OrganisaatioService
import fi.oph.viestinvalitys.raportointi.security.SecurityConstants.OPH_ORGANISAATIO_OID
import fi.oph.viestinvalitys.raportointi.security.{SecurityConstants, SecurityOperaatiot}
import fi.oph.viestinvalitys.util.DbUtil
import fi.oph.viestinvalitys.vastaanotto.security.SecurityConstants.SECURITY_ROOLI_PAAKAYTTAJA_FULL
import jakarta.servlet.http.HttpSession
import org.junit.jupiter.api.*
import org.junit.jupiter.api.TestInstance.Lifecycle
import org.mockito.ArgumentMatchers.any
import org.mockito.Mockito.{reset, times, verify, when}
import org.scalatestplus.mockito.MockitoSugar.mock
import slick.jdbc.JdbcBackend.Database

@TestInstance(Lifecycle.PER_CLASS)
class SecurityOperaatiotTest {
Expand All @@ -20,10 +23,15 @@ class SecurityOperaatiotTest {
val ORGANISAATIO2 = "1.2.246.562.10.79559059674"

val mockOrganisaatioService = mock[OrganisaatioService]
val mockKantaoperaatiot = mock[KantaOperaatiot]
val mockHttpSession = mock[HttpSession]

@BeforeAll def setup(): Unit = {
System.setProperty("MODE", "LOCAL") // kantaa ei saanut mockattua joten oikaistaan tällä
}

@Test def testKayttajanOikeudet(): Unit =
val OIKEUS = "APP_OIKEUS1"

when(mockOrganisaatioService.getAllChildOidsFlat(ORGANISAATIO)).thenReturn(Set("1.2.246.562.10.2014041814455745619200"))
val securityOperaatiot = SecurityOperaatiot(() => Seq("ROLE_" + OIKEUS + "_" + ORGANISAATIO), () => "", mockOrganisaatioService)
Assertions.assertEquals(Set(Kayttooikeus(OIKEUS, Some(ORGANISAATIO)), Kayttooikeus(OIKEUS, Some("1.2.246.562.10.2014041814455745619200"))), securityOperaatiot.getKayttajanOikeudet())
Expand Down
6 changes: 6 additions & 0 deletions viestinvalitys-raportointi/src/app/lib/data.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ const REVALIDATE_TIME_SECONDS = 60 * 60 * 2;
const REVALIDATE_ASIOINTIKIELI = 60;

export async function fetchLahetykset(hakuParams: LahetysHakuParams) {
console.info('Haetaan lähetykset')
const fetchUrlBase = `${apiUrl}/lahetykset/lista?enintaan=${LAHETYKSET_SIVUTUS_KOKO}`;
let fetchParams = hakuParams.seuraavatAlkaen
? `&alkaen=${hakuParams.seuraavatAlkaen}`
Expand All @@ -33,21 +34,25 @@ export async function fetchLahetykset(hakuParams: LahetysHakuParams) {
const res = await makeRequest(fetchUrlBase.concat(fetchParams), {
cache: 'no-store',
});
console.info('saatiin lähetykset')
return res.data;
}

export async function fetchLahetys(lahetysTunnus: string) {
console.info('haetaan lähetys')
const url = `${apiUrl}/lahetykset/${lahetysTunnus}`;
const res = await makeRequest(url, {
cache: 'no-store',
});
console.info('saatiin lähetys')
return res.data;
}

export async function fetchLahetyksenVastaanottajat(
lahetysTunnus: string,
hakuParams: VastaanottajatHakuParams,
) {
console.info('haetaan vastaanottajat')
const url = `${apiUrl}/lahetykset/${lahetysTunnus}/vastaanottajat?enintaan=${VASTAANOTTAJAT_SIVUTUS_KOKO}`;
let fetchParams = hakuParams.alkaen ? `&alkaen=${hakuParams.alkaen}` : '';
if (hakuParams.hakusana) {
Expand All @@ -63,6 +68,7 @@ export async function fetchLahetyksenVastaanottajat(
const res = await makeRequest(url.concat(fetchParams), {
cache: 'no-store',
});
console.info('saatiin vastaanottajat')
return res.data;
}

Expand Down

0 comments on commit 2bc85c4

Please sign in to comment.