Skip to content

Commit

Permalink
OK-326 WIP Add encoded token to migri link
Browse files Browse the repository at this point in the history
  • Loading branch information
msiukola committed Nov 16, 2023
1 parent 00a0002 commit 52c573d
Show file tree
Hide file tree
Showing 15 changed files with 73 additions and 15 deletions.
1 change: 1 addition & 0 deletions src/main/js/controllers/hakutoiveidenMuokkaus.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ export default ['$scope', '$location', '$http', '$cookies', function($scope, $lo
$scope.loading = false;
$scope.application = new Hakemus(response.data);
$scope.application.oiliJwt = response.oiliJwt;
$scope.application.migriJwt = response.migriJwt;
$scope.application.token = token;
$scope.application.isHakutoiveidenMuokkaus = true;
const henkilotiedot = response.data.hakemus.answers.henkilotiedot;
Expand Down
3 changes: 2 additions & 1 deletion src/main/js/directives/application.html
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,8 @@ <h2>{{application.haku.name }}</h2>
</section>

<section class="migri" ng-if="application.showMigriURL()">
<migri migri="application.showMigriURL()">
<migri migri="application.showMigriURL()"
token="{{application.migriJwt}}">
</migri>
</section>

Expand Down
10 changes: 9 additions & 1 deletion src/main/js/directives/migri.html
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,13 @@
<strong>{{ localization('migri.otsikko') }}</strong>
</header>
<div ng-bind-html="localization('migri.ohje-teksti')"></div>
<div class="linkki" ng-bind-html="localization('migri.linkki-teksti')"></div>
<div class="linkki">
<a class="linkki" href="{{parsedUrl}}" target="_blank">{{localization('migri.linkki-teksti')}}</a>
<p ng-click="constructUrl()">
{{justSomeToken}} {{migriToken}}
</p>
<p ng-click="constructUrl()">
{{parsedUrl}}
</p>
</div>
</div>
14 changes: 13 additions & 1 deletion src/main/js/directives/migri.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,23 @@ export default function () {
return {
restrict: 'E',
scope: {
migri: '&'
migri: '&migri',
token: '@token'
},
template: require('./migri.html'),
link: function (scope, element, attrs) {
console.log('linking', scope);
scope.localization = localize;
scope.justSomeToken = 'c d e f g'
scope.migriTokenParsed = scope.token || 'no token found';
scope.constructUrl = function() {
const base = "https://opintopolkumigri.fi?token=";
const localized = scope.localization('migri.linkki-pohja');
console.log("Getting migri url for base " + (localized || base) + ". Token: " + scope.migriTokenParsed);
scope.parsedUrl = (localized || base) + scope.migriTokenParsed;
return (localized || base) + scope.migriTokenParsed;
}
scope.constructUrl();
}
}
}
1 change: 1 addition & 0 deletions src/main/js/interceptors/nonSensitiveHakemus.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ export default ['$cookies', function HakemusInterceptor($cookies) {
if (shouldAuthenticate(response.config) && response.data && response.data.jsonWebToken) {
setBearerToken($cookies, response.data.jsonWebToken);
response.oiliJwt = response.data.oiliJwt;
response.migriJwt = response.data.migriJwt;
response.data = response.data.response
}
return response
Expand Down
7 changes: 7 additions & 0 deletions src/main/js/models/hakemus.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ export default class Hakemus {
postOffice: json.hakemus.postOffice
};
this.oiliJwt = null;
this.migriJwt = "abcdefg";
this.hakemusSource = json.hakemusSource;
this.previewUrl = json.previewUrl;
}
Expand Down Expand Up @@ -149,10 +150,16 @@ export default class Hakemus {

showMigriURL() {
return _.chain(this.valintatulosHakutoiveet()).map(function(tulos) {
console.log("Show migri url?", tulos)
return tulos.showMigriURL
}).filter(function(k) {return k}).head().value()
}

getMigriUrl(base) {
console.log("Getting migri url for base " + base + ". Token: " + this.migriJwt)
return base + this.migriJwt;
}

oiliUrl() {
var oiliJwt = this.oiliJwt;
return _.chain(this.valintatulosHakutoiveet()).map(function(tulos) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ host.virkailija={{host_virkailija}}
host.oppija={{host_oppija}}

omatsivut.crypto.aes.key={{omatsivut_crypto_aes_key}}
omatsivut.migri.crypto.hmac.key={{omatsivut_crypto_hmac_key}}
omatsivut.crypto.hmac.key={{omatsivut_crypto_hmac_key}}

cas.url=https://{{host_virkailija}}/cas
Expand Down
1 change: 1 addition & 0 deletions src/main/resources/oph-configuration/dev-vars.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ mongodb_hakemus_password: ""
omatsivut_cas_ticket_url: "http://localhost/cas/v1/tickets"
omatsivut_crypto_aes_key: "akuankkaakuankka"
omatsivut_crypto_hmac_key: "akuankkaakuankkaakuankkaakuankka"
omatsivut_migri_crypto_hmac_key: "roopeankkaroopeankkaroopeankkaro"
omatsivut_haku_app_username: ""
omatsivut_haku_app_password: ""
omatsivut_authentication_service_username: ""
Expand Down
3 changes: 2 additions & 1 deletion src/main/resources/translations/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -219,7 +219,8 @@
"migri": {
"otsikko": "You can now apply for a residence permit",
"ohje-teksti": "<ul><li>Please first see instructions on how to apply for a residence permit: <a href='https://migri.fi/en/guide-for-students' target='_blank'>Guide for students</a></li><li>In order to apply for the residence permit, you need to attach your national learner ID on the residence permit application. <a href='/konfo/en/sivu/national-learner-id' target='_blank'>Learn more about the national learner ID</a></li></ul>",
"linkki-teksti": "<a href='https://migri.fi/en/residence-permit-application-for-studies' target='_blank'>Click here to apply for the residence permit</a>"
"linkki-teksti": "Click here to apply for the residence permit",
"linkki-pohja": "https://migri.fi/en/residence-permit-application-for-studies?token="
},

"emailNote": {
Expand Down
3 changes: 2 additions & 1 deletion src/main/resources/translations/fi.json
Original file line number Diff line number Diff line change
Expand Up @@ -219,7 +219,8 @@
"migri": {
"otsikko": "Voit nyt hakea oleskelulupaa",
"ohje-teksti": "<ul><li>Tutustuthan ensin oleskeluluvan hakuohjeisiin: <a href='https://migri.fi/opiskelijan-opas' target='_blank'>Opiskelijan opas</a></li><li>Sinun pitää lisätä oleskelulupahakemuksellesi oppijanumerosi. <a href='/konfo/fi/sivu/oppijanumero' target='_blank'>Lue lisää oppijanumerosta</a></li></ul>",
"linkki-teksti": "<a href='https://migri.fi/opiskelijan-oleskelulupahakemus' target='_blank'>Siirry tästä oleskeluluvan hakemiseen</a>"
"linkki-teksti": "Siirry tästä oleskeluluvan hakemiseen",
"linkki-pohja": "https://migri.fi/opiskelijan-oleskelulupahakemus?token="
},

"emailNote": {
Expand Down
3 changes: 2 additions & 1 deletion src/main/resources/translations/sv.json
Original file line number Diff line number Diff line change
Expand Up @@ -219,7 +219,8 @@
"migri": {
"otsikko": "Du kan nu ansöka om uppehållstillstånd",
"ohje-teksti": "<ul><li>Bekanta dig först med anvisningarna för att ansöka om uppehållstillstånd: <a href='https://migri.fi/sv/guiden-for-studerande' target='_blank'>Guiden för studerande</a></li><li>Du måste lägga in ditt studentnummer på din ansökan om uppehållstillstånd.<a href='/konfo/sv/sivu/studentnummer' target='_blank'>Läs mera om studentnummer</a></li></ul>",
"linkki-teksti": "<a href='https://migri.fi/sv/ansokan-om-uppehallstillstand-for-studier' target='_blank'>Klicka här för att ansöka om uppehållstillstånd</a>"
"linkki-teksti": "Klicka här för att ansöka om uppehållstillstånd",
"linkki-pohja": "https://migri.fi/sv/ansokan-om-uppehallstillstand-for-studier?token="
},

"emailNote": {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ case class ApplicationSettings(config: Config) extends GroupEmailerSettings(conf

val aesKey : String = config.getString("omatsivut.crypto.aes.key")
val hmacKey : String = config.getString("omatsivut.crypto.hmac.key")
val hmacKeyMigri : String = config.getString("omatsivut.crypto.hmac.key") //Todo actually use a different secret for migri

val oppijaBaseUrlEn = config.getString("oppija.base.url.en")
val oppijaBaseUrlFi = config.getString("oppija.base.url.fi")
Expand Down
15 changes: 15 additions & 0 deletions src/main/scala/fi/vm/sade/omatsivut/security/JsonWebToken.scala
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,21 @@ import scala.util.{Failure, Success, Try}
case class HakemusJWT(oid: Oid, answersFromThisSession: Set[AnswerId], personOid: Oid)
case class OiliJWT(hakijaOid: Oid, expires: Long)

case class MigriJWT(hakijaOid: Oid, expires: Long)

class MigriJsonWebToken(val secret: String) {
implicit val jsonFormats = formats(NoTypeHints)

if (secret.getBytes.size * 8 < 256) throw new RuntimeException("(MIGRI) HMAC secret has to be at least 256 bits")

val algo = JwtAlgorithm.HS256

def createMigriJWT(hakijaOid: String): String = {
val migriJwt = MigriJWT(hakijaOid, System.currentTimeMillis + (3600 * 2 * 1000)) //two hours expiry time
JwtJson4s.encode(write(migriJwt), secret, algo)
}
}

class JsonWebToken(val secret: String) {
implicit val jsonFormats = formats(NoTypeHints)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import fi.vm.sade.hakemuseditori.viestintapalvelu.{AccessibleHtml, Pdf}
import fi.vm.sade.omatsivut.config.AppConfig
import fi.vm.sade.omatsivut.config.AppConfig.AppConfig
import fi.vm.sade.omatsivut.hakemuspreview.HakemusPreviewGeneratorComponent
import fi.vm.sade.omatsivut.security.{AuthenticationRequiringServlet, SessionService}
import fi.vm.sade.omatsivut.security.{AuthenticationRequiringServlet, JsonWebToken, MigriJsonWebToken, SessionService}
import fi.vm.sade.omatsivut.vastaanotto.{Vastaanotto, VastaanottoComponent}
import fi.vm.sade.utils.cas.{CasAuthenticatingClient, CasClient, CasParams}
import org.http4s.client.blaze
Expand All @@ -41,6 +41,8 @@ trait ApplicationsServletContainer {
extends OmatSivutServletBase
with JsonFormats with JacksonJsonSupport with AuthenticationRequiringServlet with HakemusEditoriUserContext {

private val migriJwt = new MigriJsonWebToken(appConfig.settings.hmacKeyMigri)

def user = Oppija(personOid())
private val hakemusEditori = newEditor(this)
protected val applicationDescription = "Oppijan henkilökohtaisen palvelun REST API, jolla voi hakea ja muokata hakemuksia ja omia tietoja"
Expand All @@ -67,14 +69,15 @@ trait ApplicationsServletContainer {
}
}

//Todo, tarvitaanko migritokenia tällä puolella lainkaan?
get("/") {
val oid = personOid()
hakemusEditori.fetchByPersonOid(request, oid, Fetch) match {
case FullSuccess(hakemukset) =>
Map("allApplicationsFetched" -> true, "applications" -> hakemukset)
Map("allApplicationsFetched" -> true, "applications" -> hakemukset, "migriJwt" -> migriJwt.createMigriJWT(oid))
case PartialSuccess(hakemukset, exceptions) =>
exceptions.foreach(logger.warn(s"Failed to fetch all applications for oid $oid",_))
Map("allApplicationsFetched" -> false, "applications" -> hakemukset)
Map("allApplicationsFetched" -> false, "applications" -> hakemukset, "migriJwt" -> migriJwt.createMigriJWT(oid))
case FullFailure(exceptions) =>
exceptions.foreach(logger.error(s"Failed to fetch applications for oid $oid", _))
throw exceptions.head
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import fi.vm.sade.hakemuseditori.viestintapalvelu.{AccessibleHtml, Pdf}
import fi.vm.sade.omatsivut.NonSensitiveHakemusInfo.answerIds
import fi.vm.sade.omatsivut.config.AppConfig.AppConfig
import fi.vm.sade.omatsivut.oppijantunnistus.{ExpiredTokenException, InvalidTokenException, OppijanTunnistusComponent}
import fi.vm.sade.omatsivut.security.{HakemusJWT, JsonWebToken}
import fi.vm.sade.omatsivut.security.{HakemusJWT, JsonWebToken, MigriJsonWebToken}
import fi.vm.sade.omatsivut.vastaanotto.{Vastaanotto, VastaanottoComponent}
import fi.vm.sade.omatsivut.{NonSensitiveHakemus, NonSensitiveHakemusInfo, NonSensitiveHakemusInfoSerializer, NonSensitiveHakemusSerializer}
import org.json4s._
Expand All @@ -29,7 +29,7 @@ sealed trait InsecureResponse {
}

case class InsecureHakemus(jsonWebToken: String, response: NonSensitiveHakemus) extends InsecureResponse
case class InsecureHakemusInfo(jsonWebToken: String, response: NonSensitiveHakemusInfo, oiliJwt: String = null) extends InsecureResponse
case class InsecureHakemusInfo(jsonWebToken: String, response: NonSensitiveHakemusInfo, oiliJwt: String = null, migriJwt: String = null) extends InsecureResponse

trait NonSensitiveApplicationServletContainer {
this: HakemusRepositoryComponent with
Expand All @@ -44,6 +44,7 @@ trait NonSensitiveApplicationServletContainer {
protected val applicationDescription = "Oppijan henkilökohtaisen palvelun REST API, jolla voi muokata hakemusta heikosti tunnistautuneena"
private val hakemusEditori = newEditor(this)
private val jwt = new JsonWebToken(appConfig.settings.hmacKey)
private val migriJwt = new MigriJsonWebToken(appConfig.settings.hmacKeyMigri)

class UnauthorizedException(msg: String) extends RuntimeException(msg)
class ForbiddenException(msg: String) extends RuntimeException(msg)
Expand Down Expand Up @@ -152,10 +153,12 @@ trait NonSensitiveApplicationServletContainer {
token <- jwtAuthorize
hakemus <- fetchHakemus(token.oid, Some(token.personOid))
} yield {
val personOid = oppijanumerorekisteriService.henkilo(token.personOid).oid
Ok(InsecureHakemusInfo(
jwt.encode(token),
new NonSensitiveHakemusInfo(hakemus, token.answersFromThisSession),
oiliJwt = jwt.createOiliJwt(oppijanumerorekisteriService.henkilo(token.personOid).oid)
oiliJwt = jwt.createOiliJwt(personOid),
migriJwt = migriJwt.createMigriJWT(personOid)
))
}).get
}
Expand Down Expand Up @@ -184,13 +187,14 @@ trait NonSensitiveApplicationServletContainer {
get("/applications/application/token/:token") {
(for {
metadata <- oppijanTunnistusService.validateToken(params("token"))
hakemus <- fetchHakemus(metadata.hakemusOid, metadata.personOid)
hakemus: HakemusInfo <- fetchHakemus(metadata.hakemusOid, metadata.personOid)
} yield {
val personOid = oppijanumerorekisteriService.henkilo(hakemus.hakemus.personOid).oid
Ok(InsecureHakemusInfo(
jwt.encode(HakemusJWT(metadata.hakemusOid, Set(), hakemus.hakemus.personOid)),
new NonSensitiveHakemusInfo(hakemus, Set()),
oiliJwt = jwt.createOiliJwt(
oppijanumerorekisteriService.henkilo(hakemus.hakemus.personOid).oid)
oiliJwt = jwt.createOiliJwt(personOid),
migriJwt = migriJwt.createMigriJWT(personOid)
))
}).get
}
Expand Down

0 comments on commit 52c573d

Please sign in to comment.