Skip to content

Commit

Permalink
feat: implement crit
Browse files Browse the repository at this point in the history
  • Loading branch information
jcmelati committed Aug 24, 2024
1 parent 900a3c3 commit 1ee74c9
Show file tree
Hide file tree
Showing 10 changed files with 140 additions and 1 deletion.
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package com.sphereon.oid.fed.server.admin.controllers

import com.sphereon.oid.fed.openapi.models.CreateCritDTO
import com.sphereon.oid.fed.persistence.models.Crit
import com.sphereon.oid.fed.services.CritService
import org.springframework.web.bind.annotation.DeleteMapping
import org.springframework.web.bind.annotation.GetMapping
import org.springframework.web.bind.annotation.PathVariable
import org.springframework.web.bind.annotation.PostMapping
import org.springframework.web.bind.annotation.RequestBody
import org.springframework.web.bind.annotation.RequestMapping
import org.springframework.web.bind.annotation.RestController

@RestController
@RequestMapping("/accounts/{accountUsername}/crits")
class CritController {
private val critService = CritService()

@PostMapping
fun createCrit(
@PathVariable accountUsername: String,
@RequestBody body: CreateCritDTO
): Crit {
return critService.create(accountUsername, body.claim)
}

@GetMapping
fun getCrits(
@PathVariable accountUsername: String
): Array<Crit> {
return critService.findByAccountUsername(accountUsername)
}

@DeleteMapping("/{id}")
fun deleteCrit(
@PathVariable accountUsername: String,
@PathVariable id: Int
): Crit {
return critService.delete(accountUsername, id)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -1959,6 +1959,16 @@ components:
example: 2024-08-06T12:34:56Z
nullable: true

CreateCritDTO:
type: object
x-tags:
- federation
properties:
claim:
type: string
description: A critical claims that must be understood and processed.
required:
- claim

SubordinateStatement:
allOf:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ class EntityConfigurationStatementBuilder {
private lateinit var jwks: Array<JwkDTO>
private var metadata: MutableMap<String, JsonObject> = mutableMapOf()
private val authorityHints: MutableList<String> = mutableListOf()
private val crit: MutableList<String> = mutableListOf()

fun iss(iss: String) = apply { this.iss = iss }
fun exp(exp: Int) = apply { this.exp = exp }
Expand All @@ -30,6 +31,10 @@ class EntityConfigurationStatementBuilder {
this.authorityHints.add(hint)
}

fun crit(claim: String) = apply {
this.crit.add(claim)
}

@OptIn(ExperimentalSerializationApi::class)
private fun createJwks(jwks: Array<JwkDTO>): JsonObject {
val jsonArray: JsonArray = Json.encodeToJsonElement(ArraySerializer(JwkDTO.serializer()), jwks) as JsonArray
Expand All @@ -47,7 +52,8 @@ class EntityConfigurationStatementBuilder {
iat = iat ?: throw IllegalArgumentException("iat must be provided"),
jwks = createJwks(jwks),
metadata = JsonObject(metadata),
authorityHints = if (authorityHints.isNotEmpty()) authorityHints.toTypedArray() else null
authorityHints = if (authorityHints.isNotEmpty()) authorityHints.toTypedArray() else null,
crit = if (crit.isNotEmpty()) crit.toTypedArray() else null
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package com.sphereon.oid.fed.persistence

import com.sphereon.oid.fed.persistence.models.AccountQueries
import com.sphereon.oid.fed.persistence.models.AuthorityHintQueries
import com.sphereon.oid.fed.persistence.models.CritQueries
import com.sphereon.oid.fed.persistence.models.EntityConfigurationMetadataQueries
import com.sphereon.oid.fed.persistence.models.EntityConfigurationStatementQueries
import com.sphereon.oid.fed.persistence.models.KeyQueries
Expand All @@ -14,4 +15,5 @@ expect object Persistence {
val subordinateQueries: SubordinateQueries
val entityConfigurationMetadataQueries: EntityConfigurationMetadataQueries
val authorityHintQueries: AuthorityHintQueries
val critQueries: CritQueries
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
CREATE TABLE Crit (
id SERIAL PRIMARY KEY,
account_id INT NOT NULL,
claim TEXT NOT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
deleted_at TIMESTAMP,
CONSTRAINT FK_ParentCrit FOREIGN KEY (account_id) REFERENCES Account (id)
);

CREATE INDEX crit_account_id_index ON Crit (account_id);
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
findByAccountId:
SELECT * FROM Crit WHERE account_id = ? AND deleted_at IS NULL;

findByAccountIdAndClaim:
SELECT * FROM Crit WHERE account_id = ? AND claim = ? AND deleted_at IS NULL;

deleteByAccountIdAndId:
UPDATE Crit SET deleted_at = CURRENT_TIMESTAMP WHERE account_id = ? AND id = ? AND deleted_at IS NULL RETURNING *;

deleteById:
UPDATE Crit SET deleted_at = CURRENT_TIMESTAMP WHERE id = ? RETURNING *;

create:
INSERT INTO Crit (account_id, claim) VALUES (?, ?) RETURNING *;

findByAccountIdAndId:
SELECT * FROM Crit WHERE account_id = ? AND id = ? AND deleted_at IS NULL;
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import app.cash.sqldelight.db.SqlDriver
import com.sphereon.oid.fed.persistence.database.PlatformSqlDriver
import com.sphereon.oid.fed.persistence.models.AccountQueries
import com.sphereon.oid.fed.persistence.models.AuthorityHintQueries
import com.sphereon.oid.fed.persistence.models.CritQueries
import com.sphereon.oid.fed.persistence.models.EntityConfigurationMetadataQueries
import com.sphereon.oid.fed.persistence.models.EntityConfigurationStatementQueries
import com.sphereon.oid.fed.persistence.models.KeyQueries
Expand All @@ -18,6 +19,7 @@ actual object Persistence {
actual val subordinateQueries: SubordinateQueries
actual val entityConfigurationMetadataQueries: EntityConfigurationMetadataQueries
actual val authorityHintQueries: AuthorityHintQueries
actual val critQueries: CritQueries

init {
val driver = getDriver()
Expand All @@ -30,6 +32,7 @@ actual object Persistence {
subordinateQueries = database.subordinateQueries
entityConfigurationMetadataQueries = database.entityConfigurationMetadataQueries
authorityHintQueries = database.authorityHintQueries
critQueries = database.critQueries
}

private fun getDriver(): SqlDriver {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,5 +14,9 @@ class Constants {
const val AUTHORITY_HINT_NOT_FOUND = "Authority hint not found"
const val FAILED_TO_DELETE_AUTHORITY_HINT = "Failed to delete authority hint"
const val AUTHORITY_HINT_ALREADY_EXISTS = "Authority hint already exists"
const val CRIT_ALREADY_EXISTS = "Crit already exists"
const val FAILED_TO_CREATE_CRIT = "Failed to create crit"
const val CRIT_NOT_FOUND = "Crit not found"
const val FAILED_TO_DELETE_CRIT = "Failed to delete crit"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package com.sphereon.oid.fed.services

import com.sphereon.oid.fed.persistence.Persistence
import com.sphereon.oid.fed.persistence.models.Crit

class CritService {

fun create(accountUsername: String, claim: String): Crit {
val account = Persistence.accountQueries.findByUsername(accountUsername).executeAsOneOrNull()
?: throw IllegalArgumentException(Constants.ACCOUNT_NOT_FOUND)

val critAlreadyExists =
Persistence.critQueries.findByAccountIdAndClaim(account.id, claim).executeAsOneOrNull()

if (critAlreadyExists != null) {
throw IllegalArgumentException(Constants.CRIT_ALREADY_EXISTS)
}

return Persistence.critQueries.create(account.id, claim).executeAsOneOrNull()
?: throw IllegalStateException(Constants.FAILED_TO_CREATE_CRIT)
}

fun delete(accountUsername: String, id: Int): Crit {
val account = Persistence.accountQueries.findByUsername(accountUsername).executeAsOneOrNull()
?: throw IllegalArgumentException(Constants.ACCOUNT_NOT_FOUND)

return Persistence.critQueries.deleteByAccountIdAndId(account.id, id).executeAsOneOrNull()
?: throw IllegalStateException(Constants.FAILED_TO_DELETE_CRIT)
}

fun findByAccountId(accountId: Int): Array<Crit> {
return Persistence.critQueries.findByAccountId(accountId).executeAsList().toTypedArray()
}

fun findByAccountUsername(accountUsername: String): Array<Crit> {
val account = Persistence.accountQueries.findByUsername(accountUsername).executeAsOneOrNull()
?: throw IllegalArgumentException(Constants.ACCOUNT_NOT_FOUND)

return findByAccountId(account.id)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ class EntityConfigurationStatementService {
val hasSubordinates = subordinateQueries.findByAccountId(account.id).executeAsList().isNotEmpty()
val authorityHints =
authorityHintQueries.findByAccountId(account.id).executeAsList().map { it.identifier }.toTypedArray()
val crits = Persistence.critQueries.findByAccountId(account.id).executeAsList().map { it.claim }.toTypedArray()
val metadata = Persistence.entityConfigurationMetadataQueries.findByAccountId(account.id).executeAsList()

val entityConfigurationStatement = EntityConfigurationStatementBuilder()
Expand Down Expand Up @@ -56,6 +57,10 @@ class EntityConfigurationStatementService {
)
}

crits.forEach {
entityConfigurationStatement.crit(it)
}

return entityConfigurationStatement.build()
}

Expand Down

0 comments on commit 1ee74c9

Please sign in to comment.