-
Notifications
You must be signed in to change notification settings - Fork 15
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(pollux): implement the DAL for CRUD on the verifiable policy ent…
…ity. ATL-2478 (#368) * feat(pollux): implement the DAL for CRUD on the verifiable policy entity ATL-2487
- Loading branch information
1 parent
a2d9c98
commit b290a18
Showing
10 changed files
with
786 additions
and
3 deletions.
There are no files selected for viewing
31 changes: 31 additions & 0 deletions
31
pollux/lib/core/src/main/scala/io/iohk/atala/pollux/core/model/VerificationPolicy.scala
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,31 @@ | ||
package io.iohk.atala.pollux.core.model | ||
|
||
import zio.{Clock, Random, ZIO} | ||
|
||
import java.time.{OffsetDateTime, ZoneId, ZoneOffset} | ||
import java.util.UUID | ||
|
||
case class VerificationPolicy( | ||
id: UUID, | ||
name: String, | ||
description: String, | ||
createdAt: OffsetDateTime, | ||
updatedAt: OffsetDateTime, | ||
constrains: Seq[VerificationPolicyConstraint] | ||
) { | ||
def nonce: Int = hashCode() | ||
} | ||
|
||
object VerificationPolicy { | ||
def make(name: String, description: String, constraints: Seq[VerificationPolicyConstraint]) = | ||
for { | ||
id <- Random.nextUUID | ||
ts <- Clock.currentDateTime.map(_.atZoneSameInstant(ZoneOffset.UTC).toOffsetDateTime) | ||
} yield VerificationPolicy(id, name, description, createdAt = ts, updatedAt = ts, constrains = constraints) | ||
} | ||
sealed trait VerificationPolicyConstraint | ||
|
||
case class CredentialSchemaAndTrustedIssuersConstraint( | ||
schemaId: String, | ||
trustedIssuers: Seq[String] | ||
) extends VerificationPolicyConstraint |
10 changes: 10 additions & 0 deletions
10
...b/core/src/main/scala/io/iohk/atala/pollux/core/model/error/VerificationPolicyError.scala
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,10 @@ | ||
package io.iohk.atala.pollux.core.model.error | ||
|
||
import java.util.UUID | ||
|
||
sealed trait VerificationPolicyError | ||
object VerificationPolicyError { | ||
final case class RepositoryError(cause: Throwable) extends VerificationPolicyError | ||
final case class NotFoundError(id: UUID) extends VerificationPolicyError | ||
final case class UnexpectedError(cause: Throwable) extends VerificationPolicyError | ||
} |
34 changes: 34 additions & 0 deletions
34
...re/src/main/scala/io/iohk/atala/pollux/core/repository/VerificationPolicyRepository.scala
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,34 @@ | ||
package io.iohk.atala.pollux.core.repository | ||
|
||
import io.iohk.atala.pollux.core.model.{VerificationPolicy, VerificationPolicyConstraint} | ||
|
||
import java.util.UUID | ||
|
||
trait VerificationPolicyRepository[F[_]] { | ||
|
||
def create(verificationPolicy: VerificationPolicy): F[VerificationPolicy] | ||
|
||
def get(id: UUID): F[Option[VerificationPolicy]] | ||
|
||
def exists(id: UUID): F[Boolean] | ||
|
||
def getHash(id: UUID): F[Option[Int]] | ||
|
||
def update( | ||
id: UUID, | ||
nonce: Int, | ||
verificationPolicy: VerificationPolicy | ||
): F[Option[VerificationPolicy]] | ||
|
||
def delete(id: UUID, hash: Int): F[Option[VerificationPolicy]] | ||
|
||
def totalCount(): F[Long] | ||
|
||
def filteredCount(nameOpt: Option[String]): F[Long] | ||
|
||
def lookup( | ||
nameOpt: Option[String], | ||
offsetOpt: Option[Int], | ||
limitOpt: Option[Int] | ||
): F[List[VerificationPolicy]] | ||
} |
39 changes: 39 additions & 0 deletions
39
...lib/core/src/main/scala/io/iohk/atala/pollux/core/service/VerificationPolicyService.scala
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,39 @@ | ||
package io.iohk.atala.pollux.core.service | ||
|
||
import io.iohk.atala.pollux.core.model.error.VerificationPolicyError | ||
import io.iohk.atala.pollux.core.model.error.VerificationPolicyError.* | ||
import io.iohk.atala.pollux.core.model.{VerificationPolicy, VerificationPolicyConstraint} | ||
import zio.IO | ||
|
||
import java.util.UUID | ||
|
||
trait VerificationPolicyService { | ||
|
||
def create( | ||
name: String, | ||
description: String, | ||
constraints: Seq[VerificationPolicyConstraint] = Seq.empty | ||
): IO[VerificationPolicyError, VerificationPolicy] | ||
|
||
def get(id: UUID): IO[VerificationPolicyError, Option[VerificationPolicy]] | ||
|
||
def getHash(id: UUID): IO[VerificationPolicyError, Option[Int]] | ||
|
||
def update( | ||
id: UUID, | ||
hash: Int, | ||
verificationPolicy: VerificationPolicy | ||
): IO[VerificationPolicyError, Option[VerificationPolicy]] | ||
|
||
def delete(id: UUID, hash: Int): IO[VerificationPolicyError, Option[VerificationPolicy]] | ||
|
||
def totalCount(): IO[VerificationPolicyError, Long] | ||
|
||
def filteredCount(name: Option[String]): IO[VerificationPolicyError, Long] | ||
|
||
def lookup( | ||
name: Option[String], | ||
offset: Option[Int], | ||
limit: Option[Int] | ||
): IO[VerificationPolicyError, List[VerificationPolicy]] | ||
} |
73 changes: 73 additions & 0 deletions
73
...core/src/main/scala/io/iohk/atala/pollux/core/service/VerificationPolicyServiceImpl.scala
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,73 @@ | ||
package io.iohk.atala.pollux.core.service | ||
|
||
import io.iohk.atala.pollux.core.model.{VerificationPolicy, VerificationPolicyConstraint} | ||
import io.iohk.atala.pollux.core.model.error.VerificationPolicyError | ||
import io.iohk.atala.pollux.core.repository.VerificationPolicyRepository | ||
import zio.{Clock, IO, Random, Task, URLayer, ZLayer} | ||
|
||
import java.util.UUID | ||
|
||
object VerificationPolicyServiceImpl { | ||
val layer: URLayer[VerificationPolicyRepository[Task], VerificationPolicyService] = | ||
ZLayer.fromFunction(VerificationPolicyServiceImpl(_)) | ||
} | ||
|
||
class VerificationPolicyServiceImpl( | ||
repository: VerificationPolicyRepository[Task] | ||
) extends VerificationPolicyService { | ||
|
||
private val throwableToVerificationPolicyError: Throwable => VerificationPolicyError = | ||
VerificationPolicyError.RepositoryError.apply | ||
|
||
override def create( | ||
name: String, | ||
description: String, | ||
constraints: Seq[VerificationPolicyConstraint] | ||
): IO[VerificationPolicyError, VerificationPolicy] = { | ||
for { | ||
verificationPolicy <- VerificationPolicy.make(name, description, constraints) | ||
createdVerificationPolicy <- repository.create(verificationPolicy) | ||
} yield createdVerificationPolicy | ||
}.mapError(throwableToVerificationPolicyError) | ||
|
||
override def get(id: UUID): IO[VerificationPolicyError, Option[VerificationPolicy]] = | ||
repository | ||
.get(id) | ||
.mapError(throwableToVerificationPolicyError) | ||
|
||
override def getHash(id: UUID): IO[VerificationPolicyError, Option[Int]] = | ||
repository | ||
.getHash(id) | ||
.mapError(throwableToVerificationPolicyError) | ||
|
||
override def update( | ||
id: UUID, | ||
hash: Int, | ||
verificationPolicy: VerificationPolicy | ||
): IO[VerificationPolicyError, Option[VerificationPolicy]] = | ||
repository | ||
.update(id, hash, verificationPolicy) | ||
.mapError(throwableToVerificationPolicyError) | ||
|
||
override def delete(id: UUID, hash: Int): IO[VerificationPolicyError, Option[VerificationPolicy]] = | ||
repository | ||
.delete(id, hash) | ||
.mapError(throwableToVerificationPolicyError) | ||
|
||
override def totalCount(): IO[VerificationPolicyError, Long] = | ||
repository.totalCount().mapError(throwableToVerificationPolicyError) | ||
|
||
override def filteredCount( | ||
name: Option[String] | ||
): IO[VerificationPolicyError, Long] = | ||
repository.filteredCount(name).mapError(throwableToVerificationPolicyError) | ||
|
||
override def lookup( | ||
name: Option[String], | ||
offset: Option[Int], | ||
limit: Option[Int] | ||
): IO[VerificationPolicyError, List[VerificationPolicy]] = | ||
repository | ||
.lookup(name, offset, limit) | ||
.mapError(throwableToVerificationPolicyError) | ||
} |
34 changes: 34 additions & 0 deletions
34
pollux/lib/sql-doobie/src/main/resources/sql/pollux/V6__verification_policy_tables.sql
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,34 @@ | ||
CREATE TABLE public.verification_policy | ||
( | ||
id UUID PRIMARY KEY default gen_random_uuid(), | ||
name VARCHAR(255) NOT NULL, | ||
nonce INTEGER NOT NULL, | ||
description TEXT NULL, | ||
created_at TIMESTAMP WITH TIME ZONE NOT NULL default now(), | ||
updated_at TIMESTAMP WITH TIME ZONE NOT NULL default now() | ||
); | ||
|
||
CREATE INDEX verification_policy_name_index ON public.verification_policy (name); | ||
CREATE INDEX verification_policy_created_at_index ON public.verification_policy (created_at); | ||
CREATE INDEX verification_policy_updated_at_index ON public.verification_policy (updated_at); | ||
|
||
CREATE TABLE public.verification_policy_constraint | ||
( | ||
fk_id UUID NOT NULL, | ||
index INT NOT NULL, | ||
type VARCHAR(128) NOT NULL, | ||
schema_id VARCHAR(255), | ||
trusted_issuers VARCHAR(255) ARRAY, | ||
|
||
UNIQUE (fk_id, index), | ||
|
||
CONSTRAINT fk_verification_policy | ||
FOREIGN KEY (fk_id) | ||
REFERENCES public.verification_policy (id) | ||
ON DELETE CASCADE | ||
); | ||
|
||
CREATE INDEX verification_policy_constraint_fk_id_index ON public.verification_policy_constraint (fk_id); | ||
CREATE INDEX verification_policy_constraint_type_index ON public.verification_policy_constraint (type); | ||
|
||
|
144 changes: 144 additions & 0 deletions
144
.../lib/sql-doobie/src/main/scala/io/iohk/atala/pollux/sql/model/db/VerificationPolicy.scala
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,144 @@ | ||
package io.iohk.atala.pollux.sql.model.db | ||
|
||
import io.getquill.InsertMeta | ||
|
||
import java.util.UUID | ||
import io.getquill.* | ||
import io.getquill.doobie.DoobieContext | ||
|
||
import java.time.OffsetDateTime | ||
import io.getquill.* | ||
import io.getquill.idiom.* | ||
import io.iohk.atala.pollux.sql.model.VerifiableCredentialSchema.sql.run | ||
|
||
case class VerificationPolicy( | ||
id: UUID, | ||
nonce: Int, | ||
name: String, | ||
description: String, | ||
createdAt: OffsetDateTime, | ||
updatedAt: OffsetDateTime | ||
) | ||
|
||
case class VerificationPolicyConstraint( | ||
fk_id: UUID, | ||
index: Int, | ||
`type`: String, | ||
schemaId: String, | ||
trustedIssuers: Seq[String] | ||
) | ||
|
||
object VerificationPolicySql extends DoobieContext.Postgres(SnakeCase) { | ||
import io.iohk.atala.pollux.sql.repository.VerificationPolicyExtensions._ | ||
|
||
def insert(verificationPolicy: VerificationPolicy) = { | ||
inline given InsertMeta[VerificationPolicy] = insertMeta(exclude = _.id, _.createdAt, _.updatedAt) | ||
run(quote(query[VerificationPolicy].insertValue(lift(verificationPolicy)).returning(vp => vp))) | ||
} | ||
|
||
def insertConstraints(constraints: Seq[VerificationPolicyConstraint]) = { | ||
run( | ||
quote(liftQuery(constraints).foreach(c => query[VerificationPolicyConstraint].insertValue(c).returning(c => c))) | ||
) | ||
} | ||
|
||
def dropConstraintsByVerificationPolicyId(fk_id: UUID) = { | ||
run(quote(query[VerificationPolicyConstraint].filter(_.fk_id == lift(fk_id)).delete)) | ||
} | ||
|
||
def getById(id: UUID) = | ||
run( | ||
quote( | ||
query[VerificationPolicy] | ||
.filter(_.id == lift(id)) | ||
) | ||
).map(_.headOption) | ||
|
||
def getHashById(id: UUID) = | ||
run( | ||
quote( | ||
query[VerificationPolicy] | ||
.filter(_.id == lift(id)) | ||
.map(_.nonce) | ||
) | ||
).map(_.headOption) | ||
|
||
def exists(id: UUID) = | ||
run(quote(query[VerificationPolicy].filter(_.id == lift(id)).isEmpty)) | ||
|
||
def exists(id: UUID, hash: Int) = | ||
run( | ||
quote( | ||
query[VerificationPolicy] | ||
.filter(_.id == lift(id)) | ||
.filter(_.nonce == lift(hash)) | ||
.isEmpty | ||
) | ||
) | ||
|
||
def getVerificationPolicyConstrains(fk_ids: Seq[UUID]) = | ||
run( | ||
quote( | ||
query[VerificationPolicyConstraint].filter(vpc => liftQuery(fk_ids).contains(vpc.fk_id)) | ||
) | ||
) | ||
|
||
def update(verificationPolicy: VerificationPolicy, nonce: Int) = | ||
inline given UpdateMeta[VerificationPolicy] = updateMeta(exclude = _.id) | ||
run( | ||
quote( | ||
query[VerificationPolicy] | ||
.filter(_.id == lift(verificationPolicy.id)) | ||
.filter(_.nonce == lift(nonce)) | ||
.update( | ||
_.nonce -> lift(verificationPolicy.nonce), | ||
_.description -> lift(verificationPolicy.description), | ||
_.name -> lift(verificationPolicy.name), | ||
_.updatedAt -> lift(verificationPolicy.updatedAt) | ||
) | ||
.returning(vp => vp) | ||
) | ||
) | ||
|
||
def delete(id: UUID) = | ||
run( | ||
quote(query[VerificationPolicy]) | ||
.filter(_.id == lift(id)) | ||
.delete | ||
.returning(vp => vp) | ||
) | ||
|
||
def delete(id: UUID, hash: Int) = | ||
run( | ||
quote(query[VerificationPolicy]) | ||
.filter(_.id == lift(id)) | ||
.filter(_.nonce == lift(hash)) | ||
.delete | ||
.returning(vp => vp) | ||
) | ||
|
||
def deleteAll() = run(quote(query[VerificationPolicy].delete)) | ||
|
||
def deleteConstraints(fk_id: UUID) = | ||
run(quote(query[VerificationPolicyConstraint]).filter(_.fk_id == lift(fk_id)).delete) | ||
|
||
def count() = run(quote(query[VerificationPolicy].size)) | ||
|
||
def countOfConstraints() = run(quote(query[VerificationPolicyConstraint]).size) | ||
|
||
def countFiltered(nameOpt: Option[String]) = | ||
run( | ||
quote(query[VerificationPolicy]).dynamic | ||
.filterOpt(nameOpt)((vp, name) => quote(vp.name.like(name))) | ||
.size | ||
) | ||
|
||
def filteredVerificationPolicies(nameOpt: Option[String], offsetOpt: Option[Int], limitOpt: Option[Int]) = run { | ||
|
||
quote(query[VerificationPolicy]).dynamic | ||
.filterOpt(nameOpt)((vcs, name) => quote(vcs.name.like(name))) | ||
.sortBy(_.id) | ||
.dropOpt(offsetOpt) | ||
.take(limitOpt.getOrElse(1000)) | ||
} | ||
} |
Oops, something went wrong.