-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
31afb79
commit 70f64d2
Showing
7 changed files
with
258 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
108 changes: 108 additions & 0 deletions
108
src/main/kotlin/no/nav/syfo/narmesteleder/NarmesteLederClient.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,108 @@ | ||
package no.nav.syfo.narmesteleder | ||
|
||
import no.nav.security.token.support.core.context.TokenValidationContextHolder | ||
import no.nav.syfo.auth.oidc.TokenUtil | ||
import no.nav.syfo.auth.tokenx.TokenXUtil | ||
import no.nav.syfo.auth.tokenx.tokendings.TokenDingsConsumer | ||
import no.nav.syfo.util.* | ||
import org.slf4j.LoggerFactory | ||
import org.springframework.beans.factory.annotation.Value | ||
import org.springframework.cache.annotation.Cacheable | ||
import org.springframework.http.HttpEntity | ||
import org.springframework.http.HttpHeaders | ||
import org.springframework.http.HttpMethod | ||
import org.springframework.http.MediaType | ||
import org.springframework.http.ResponseEntity | ||
import org.springframework.stereotype.Service | ||
import org.springframework.web.client.RestClientResponseException | ||
import org.springframework.web.client.RestTemplate | ||
import java.util.* | ||
|
||
@Service | ||
class NarmesteLederClient( | ||
@Value("\${narmesteleder.url}") private val baseUrl: String, | ||
@Value("\${narmesteleder.client.id}") private var targetApp: String, | ||
private val tokenDingsConsumer: TokenDingsConsumer, | ||
private val contextHolder: TokenValidationContextHolder, | ||
) { | ||
@Cacheable(value = ["aktive_ledere"], key = "#ansattFnr", condition = "#ansattFnr != null") | ||
fun alleAktiveLedereForSykmeldt( | ||
ansattFnr: String, | ||
): List<NarmesteLederRelasjonDTO> { | ||
|
||
val issuerToken = TokenUtil.getIssuerToken(contextHolder, TokenXUtil.TokenXIssuer.TOKENX) | ||
val exchangedToken = tokenDingsConsumer.exchangeToken(issuerToken, targetApp) | ||
|
||
try { | ||
val response = getResponse( | ||
fnr = ansattFnr, | ||
accessToken = exchangedToken | ||
) | ||
|
||
val relasjoner = response.body ?: emptyArray() | ||
|
||
return relasjoner | ||
.filter { it.status == NarmesteLederRelasjonStatus.INNMELDT_AKTIV.name } | ||
.filter { it.arbeidstakerPersonIdentNumber == ansattFnr } | ||
.distinctBy { it.narmesteLederPersonIdentNumber } | ||
} catch (e: RestClientResponseException) { | ||
log.error( | ||
"Error while requesting all NarmesteLeder of sykmeldt. Stacktrace: {}", | ||
e.stackTraceToString() | ||
) | ||
return emptyList() | ||
} | ||
} | ||
|
||
@Cacheable(value = ["aktive_ansatte"], key = "#narmesteLederIdent", condition = "#narmesteLederIdent != null") | ||
fun aktivNarmesteLederIVirksomhet( | ||
ansattFnr: String, | ||
narmesteLederIdent: String, | ||
virksomhetsnummer: String, | ||
): NarmesteLederRelasjonDTO? { | ||
try { | ||
val narmesteLederRelasjoner = alleAktiveLedereForSykmeldt(ansattFnr) | ||
|
||
return narmesteLederRelasjoner | ||
.filter { it.narmesteLederPersonIdentNumber == narmesteLederIdent } | ||
.firstOrNull { it.virksomhetsnummer == virksomhetsnummer } | ||
} catch (e: RestClientResponseException) { | ||
log.error( | ||
"Error while requesting aktive ansatte of leder. Stacktrace: {}", | ||
e.stackTraceToString() | ||
) | ||
return null | ||
} | ||
} | ||
|
||
private fun headers(fnr: String, accessToken: String): HttpEntity<String> { | ||
val headers = HttpHeaders() | ||
headers.contentType = MediaType.APPLICATION_JSON | ||
headers[HttpHeaders.AUTHORIZATION] = bearerHeader(accessToken) | ||
headers[NAV_PERSONIDENT_HEADER] = fnr | ||
headers[NAV_CALL_ID_HEADER] = createCallId() | ||
return HttpEntity(headers) | ||
} | ||
|
||
private fun getResponse( | ||
fnr: String, | ||
accessToken: String | ||
): ResponseEntity<Array<NarmesteLederRelasjonDTO>> { | ||
return RestTemplate().exchange( | ||
"$baseUrl/api/selvbetjening/v1/narmestelederrelasjoner", | ||
HttpMethod.GET, | ||
headers(fnr, accessToken), | ||
Array<NarmesteLederRelasjonDTO>::class.java, | ||
) | ||
} | ||
|
||
companion object { | ||
private val log = LoggerFactory.getLogger(NarmesteLederClient::class.java) | ||
|
||
private fun createCallId(): String { | ||
val randomUUID = UUID.randomUUID().toString() | ||
return "oppfolgingsplan-backend-$randomUUID" | ||
} | ||
} | ||
|
||
} |
105 changes: 105 additions & 0 deletions
105
src/main/kotlin/no/nav/syfo/narmesteleder/NarmesteLederController.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,105 @@ | ||
package no.nav.syfo.narmesteleder | ||
|
||
import no.nav.security.token.support.core.api.ProtectedWithClaims | ||
import no.nav.security.token.support.core.context.TokenValidationContextHolder | ||
import no.nav.syfo.auth.tokenx.TokenXUtil | ||
import no.nav.syfo.auth.tokenx.TokenXUtil.TokenXIssuer.TOKENX | ||
import no.nav.syfo.auth.tokenx.TokenXUtil.fnrFromIdportenTokenX | ||
import no.nav.syfo.brukertilgang.BrukertilgangService | ||
import no.nav.syfo.metric.Metrikk | ||
import no.nav.syfo.util.NAV_PERSONIDENT_HEADER | ||
import no.nav.syfo.util.ORGNUMMER_HEADER | ||
import no.nav.syfo.util.fodselsnummerInvalid | ||
import org.slf4j.LoggerFactory | ||
import org.springframework.beans.factory.annotation.Autowired | ||
import org.springframework.beans.factory.annotation.Value | ||
import org.springframework.http.HttpStatus | ||
import org.springframework.http.MediaType | ||
import org.springframework.http.ResponseEntity | ||
import org.springframework.web.bind.annotation.GetMapping | ||
import org.springframework.web.bind.annotation.RequestHeader | ||
import org.springframework.web.bind.annotation.RequestMapping | ||
import org.springframework.web.bind.annotation.ResponseBody | ||
import org.springframework.web.bind.annotation.RestController | ||
|
||
@RestController | ||
@ProtectedWithClaims(issuer = TOKENX, claimMap = ["acr=Level4", "acr=idporten-loa-high"], combineWithOr = true) | ||
@RequestMapping(value = ["/api/v1/narmesteleder"]) | ||
class NarmesteLederController @Autowired constructor( | ||
private val contextHolder: TokenValidationContextHolder, | ||
private val metrikk: Metrikk, | ||
private val narmesteLederClient: NarmesteLederClient, | ||
@Value("\${oppfolgingsplan.frontend.client.id}") | ||
private val oppfolgingsplanClientId: String, | ||
private val brukertilgangService: BrukertilgangService, | ||
) { | ||
|
||
@ResponseBody | ||
@GetMapping(produces = [MediaType.APPLICATION_JSON_VALUE], path = ["/virksomhet"]) | ||
fun getAktivNarmesteLederIVirksomhet( | ||
@RequestHeader(NAV_PERSONIDENT_HEADER) fnr: String, | ||
@RequestHeader(ORGNUMMER_HEADER) virksomhetsnummer: String, | ||
): ResponseEntity<NarmesteLederRelasjonDTO?> { | ||
metrikk.tellHendelse("get_narmesteledere") | ||
|
||
val innloggetIdent = TokenXUtil.validateTokenXClaims(contextHolder, oppfolgingsplanClientId) | ||
.fnrFromIdportenTokenX() | ||
.value | ||
|
||
return if (fodselsnummerInvalid(fnr)) { | ||
LOG.error("Ugyldig fnr ved henting av nærmeste ledere") | ||
ResponseEntity | ||
.status(HttpStatus.FORBIDDEN) | ||
.build() | ||
} else { | ||
if (!brukertilgangService.tilgangTilOppslattIdent(innloggetIdent, fnr)) { | ||
LOG.error("Ikke tilgang til nærmeste ledere: Bruker spør om noen andre enn seg selv eller egne ansatte") | ||
ResponseEntity | ||
.status(HttpStatus.FORBIDDEN) | ||
.build() | ||
} else { | ||
val narmesteLedere = narmesteLederClient.aktivNarmesteLederIVirksomhet( | ||
ansattFnr = fnr, | ||
narmesteLederIdent = innloggetIdent, | ||
virksomhetsnummer = virksomhetsnummer | ||
) | ||
if (narmesteLedere != null) { | ||
return ResponseEntity | ||
.status(HttpStatus.OK) | ||
.body(narmesteLedere) | ||
} else { | ||
return ResponseEntity | ||
.status(HttpStatus.NO_CONTENT) | ||
.build() | ||
} | ||
} | ||
} | ||
} | ||
|
||
@ResponseBody | ||
@GetMapping(produces = [MediaType.APPLICATION_JSON_VALUE], path = ["/alle"]) | ||
fun getNarmesteLedere(): ResponseEntity<List<NarmesteLederRelasjonDTO>> { | ||
metrikk.tellHendelse("get_narmesteledere") | ||
|
||
val innloggetIdent = TokenXUtil.validateTokenXClaims(contextHolder, oppfolgingsplanClientId) | ||
.fnrFromIdportenTokenX() | ||
.value | ||
|
||
val narmesteLedere = narmesteLederClient.alleAktiveLedereForSykmeldt(ansattFnr = innloggetIdent) | ||
|
||
return if (narmesteLedere.isNotEmpty()) { | ||
ResponseEntity | ||
.status(HttpStatus.OK) | ||
.body(narmesteLedere) | ||
} else { | ||
ResponseEntity | ||
.status(HttpStatus.NO_CONTENT) | ||
.build() | ||
} | ||
} | ||
|
||
|
||
companion object { | ||
private val LOG = LoggerFactory.getLogger(NarmesteLederController::class.java) | ||
} | ||
} |
29 changes: 29 additions & 0 deletions
29
src/main/kotlin/no/nav/syfo/narmesteleder/NarmesteLederRelasjonDTO.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
package no.nav.syfo.narmesteleder | ||
|
||
import java.time.* | ||
|
||
data class NarmesteLederRelasjonDTO( | ||
val uuid: String, | ||
val arbeidstakerPersonIdentNumber: String, | ||
val virksomhetsnavn: String?, | ||
val virksomhetsnummer: String, | ||
val narmesteLederPersonIdentNumber: String, | ||
val narmesteLederTelefonnummer: String, | ||
val narmesteLederEpost: String, | ||
val narmesteLederNavn: String?, | ||
val aktivFom: LocalDate, | ||
val aktivTom: LocalDate?, | ||
val arbeidsgiverForskutterer: Boolean?, | ||
val timestamp: LocalDateTime, | ||
val status: String, | ||
) | ||
|
||
enum class NarmesteLederRelasjonStatus { | ||
INNMELDT_AKTIV, | ||
DEAKTIVERT, | ||
DEAKTIVERT_ARBEIDSTAKER, | ||
DEAKTIVERT_ARBEIDSTAKER_INNSENDT_SYKMELDING, | ||
DEAKTIVERT_LEDER, | ||
DEAKTIVERT_ARBEIDSFORHOLD, | ||
DEAKTIVERT_NY_LEDER, | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters