-
Notifications
You must be signed in to change notification settings - Fork 23
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: add anoncreds credential definition rest api (#624)
Signed-off-by: Bassam Riman <[email protected]> Signed-off-by: Anton Baliasnikov <[email protected]> Co-authored-by: Anton Baliasnikov <[email protected]>
- Loading branch information
1 parent
c61999d
commit 99e338a
Showing
56 changed files
with
3,250 additions
and
56 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
Binary file added
BIN
+12.9 MB
pollux/lib/anoncreds/native-lib/NATIVE/linux-aarch64/libuniffi_anoncreds.so
Binary file not shown.
Binary file renamed
BIN
+13 MB
...NATIVE/linux/amd64/libuniffi_anoncreds.so → ...ATIVE/linux-x86-64/libuniffi_anoncreds.so
Binary file not shown.
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
1 change: 1 addition & 0 deletions
1
pollux/lib/anoncredsTest/src/test/scala/io/iohk/atala/pollux/anoncreds/PoCNewLib.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
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
143 changes: 143 additions & 0 deletions
143
...lib/core/src/main/scala/io/iohk/atala/pollux/core/model/schema/CredentialDefinition.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,143 @@ | ||
package io.iohk.atala.pollux.core.model.schema | ||
|
||
import io.iohk.atala.pollux.core.model.error.CredentialSchemaError | ||
import io.iohk.atala.pollux.core.model.error.CredentialSchemaError.* | ||
import zio.* | ||
import zio.json.* | ||
|
||
import java.time.OffsetDateTime | ||
import java.time.ZoneOffset | ||
import java.util.UUID | ||
|
||
type Definition = zio.json.ast.Json | ||
type CorrectnessProof = zio.json.ast.Json | ||
|
||
/** @param guid | ||
* Globally unique identifier of the CredentialDefinition object. It's calculated as a UUID from a string that | ||
* contains the following fields: author, id, and version. | ||
* @param id | ||
* Locally unique identifier of the CredentialDefinition. It is a UUID. When the version of the credential definition | ||
* changes, this `id` keeps the same value. | ||
* @param name | ||
* Human-readable name of the CredentialDefinition. | ||
* @param description | ||
* Human-readable description of the CredentialDefinition. | ||
* @param version | ||
* Version of the CredentialDefinition. | ||
* @param author | ||
* DID of the CredentialDefinition's author. | ||
* @param authored | ||
* Datetime stamp of the schema creation. | ||
* @param tags | ||
* Tags of the CredentialDefinition, used for convenient lookup. | ||
* @param schemaId | ||
* Schema ID that identifies the schema associated with this definition. | ||
* @param definition | ||
* Definition object that represents the actual definition of the credential. | ||
* @param keyCorrectnessProof | ||
* A proof that validates the correctness of the key within the context of the credential definition. | ||
* @param signatureType | ||
* Signature type used in the CredentialDefinition. | ||
* @param supportRevocation | ||
* Boolean flag indicating whether revocation is supported for this CredentialDefinition. | ||
*/ | ||
case class CredentialDefinition( | ||
guid: UUID, | ||
id: UUID, | ||
name: String, | ||
description: String, | ||
version: String, | ||
author: String, | ||
authored: OffsetDateTime, | ||
tag: String, | ||
schemaId: String, | ||
definitionJsonSchemaId: String, | ||
definition: Definition, | ||
keyCorrectnessProofJsonSchemaId: String, | ||
keyCorrectnessProof: CorrectnessProof, | ||
signatureType: String, | ||
supportRevocation: Boolean | ||
) { | ||
def longId = CredentialDefinition.makeLongId(author, id, version) | ||
} | ||
|
||
object CredentialDefinition { | ||
|
||
def makeLongId(author: String, id: UUID, version: String) = | ||
s"$author/${id.toString}?version=${version}" | ||
|
||
def makeGUID(author: String, id: UUID, version: String) = | ||
UUID.nameUUIDFromBytes(makeLongId(author, id, version).getBytes) | ||
|
||
def make( | ||
in: Input, | ||
definitionSchemaId: String, | ||
definition: Definition, | ||
proofSchemaId: String, | ||
proof: CorrectnessProof | ||
): ZIO[Any, Nothing, CredentialDefinition] = { | ||
for { | ||
id <- zio.Random.nextUUID | ||
cs <- make(id, in, definitionSchemaId, definition, proofSchemaId, proof) | ||
} yield cs | ||
} | ||
|
||
def make( | ||
id: UUID, | ||
in: Input, | ||
definitionSchemaId: String, | ||
definition: Definition, | ||
keyCorrectnessProofSchemaId: String, | ||
keyCorrectnessProof: CorrectnessProof | ||
): ZIO[Any, Nothing, CredentialDefinition] = { | ||
for { | ||
ts <- zio.Clock.currentDateTime.map( | ||
_.atZoneSameInstant(ZoneOffset.UTC).toOffsetDateTime | ||
) | ||
guid = makeGUID(in.author, id, in.version) | ||
} yield CredentialDefinition( | ||
guid = guid, | ||
id = id, | ||
name = in.name, | ||
description = in.description, | ||
version = in.version, | ||
schemaId = in.schemaId, | ||
author = in.author, | ||
authored = in.authored.map(_.atZoneSameInstant(ZoneOffset.UTC).toOffsetDateTime).getOrElse(ts), | ||
tag = in.tag, | ||
definitionJsonSchemaId = definitionSchemaId, | ||
definition = definition, | ||
keyCorrectnessProofJsonSchemaId = keyCorrectnessProofSchemaId, | ||
keyCorrectnessProof = keyCorrectnessProof, | ||
signatureType = in.signatureType, | ||
supportRevocation = in.supportRevocation | ||
) | ||
} | ||
|
||
val defaultAgentDid = "did:prism:agent" | ||
|
||
case class Input( | ||
name: String, | ||
description: String, | ||
version: String, | ||
authored: Option[OffsetDateTime], | ||
tag: String, | ||
author: String = defaultAgentDid, | ||
schemaId: String, | ||
signatureType: String, | ||
supportRevocation: Boolean | ||
) | ||
|
||
case class Filter( | ||
author: Option[String] = None, | ||
name: Option[String] = None, | ||
version: Option[String] = None, | ||
tag: Option[String] = None | ||
) | ||
|
||
case class FilteredEntries(entries: Seq[CredentialDefinition], count: Long, totalCount: Long) | ||
|
||
given JsonEncoder[CredentialDefinition] = DeriveJsonEncoder.gen[CredentialDefinition] | ||
|
||
given JsonDecoder[CredentialDefinition] = DeriveJsonDecoder.gen[CredentialDefinition] | ||
} |
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
22 changes: 22 additions & 0 deletions
22
.../src/main/scala/io/iohk/atala/pollux/core/repository/CredentialDefinitionRepository.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,22 @@ | ||
package io.iohk.atala.pollux.core.repository | ||
|
||
import io.iohk.atala.pollux.core.model.schema.CredentialDefinition | ||
import io.iohk.atala.pollux.core.repository.Repository.SearchCapability | ||
|
||
import java.util.UUID | ||
|
||
trait CredentialDefinitionRepository[F[_]] | ||
extends Repository[F, CredentialDefinition] | ||
with SearchCapability[F, CredentialDefinition.Filter, CredentialDefinition] { | ||
def create(cs: CredentialDefinition): F[CredentialDefinition] | ||
|
||
def getByGuid(guid: UUID): F[Option[CredentialDefinition]] | ||
|
||
def update(cs: CredentialDefinition): F[Option[CredentialDefinition]] | ||
|
||
def getAllVersions(id: UUID, author: String): F[Seq[String]] | ||
|
||
def delete(guid: UUID): F[Option[CredentialDefinition]] | ||
|
||
def deleteAll(): F[Long] | ||
} |
96 changes: 96 additions & 0 deletions
96
...n/scala/io/iohk/atala/pollux/core/repository/CredentialDefinitionRepositoryInMemory.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,96 @@ | ||
package io.iohk.atala.pollux.core.repository | ||
|
||
import io.iohk.atala.pollux.core.model.* | ||
import io.iohk.atala.pollux.core.model.error.CredentialRepositoryError.* | ||
import io.iohk.atala.pollux.core.model.schema.CredentialDefinition | ||
import zio.* | ||
|
||
import java.util.UUID | ||
|
||
class CredentialDefinitionRepositoryInMemory( | ||
storeRef: Ref[Map[UUID, CredentialDefinition]] | ||
) extends CredentialDefinitionRepository[Task] { | ||
override def create(record: CredentialDefinition): Task[CredentialDefinition] = { | ||
for { | ||
_ <- for { | ||
store <- storeRef.get | ||
maybeRecord = store.values.find(_.id == record.guid) | ||
_ <- maybeRecord match | ||
case None => ZIO.unit | ||
case Some(value) => ZIO.fail(UniqueConstraintViolation("Unique Constraint Violation on 'id'")) | ||
} yield () | ||
_ <- storeRef.update(r => r + (record.guid -> record)) | ||
} yield record | ||
} | ||
|
||
override def getByGuid(guid: UUID): Task[Option[CredentialDefinition]] = { | ||
for { | ||
store <- storeRef.get | ||
record = store.get(guid) | ||
} yield record | ||
} | ||
|
||
override def update(cs: CredentialDefinition): Task[Option[CredentialDefinition]] = { | ||
for { | ||
store <- storeRef.get | ||
maybeExisting = store.get(cs.id) | ||
_ <- maybeExisting match { | ||
case Some(existing) => | ||
val updatedStore = store.updated(cs.id, cs) | ||
storeRef.set(updatedStore) | ||
case None => ZIO.unit | ||
} | ||
} yield maybeExisting | ||
} | ||
|
||
override def getAllVersions(id: UUID, author: String): Task[Seq[String]] = { | ||
storeRef.get.map { store => | ||
store.values | ||
.filter(credDef => credDef.id == id && credDef.author == author) | ||
.map(_.version) | ||
.toSeq | ||
} | ||
} | ||
|
||
override def delete(guid: UUID): Task[Option[CredentialDefinition]] = { | ||
for { | ||
store <- storeRef.get | ||
maybeRecord = store.get(guid) | ||
_ <- maybeRecord match { | ||
case Some(record) => storeRef.update(r => r - record.id) | ||
case None => ZIO.unit | ||
} | ||
} yield maybeRecord | ||
} | ||
|
||
override def deleteAll(): Task[Long] = { | ||
for { | ||
store <- storeRef.get | ||
deleted = store.size | ||
_ <- storeRef.update(Map.empty) | ||
} yield deleted.toLong | ||
} | ||
|
||
override def search( | ||
query: Repository.SearchQuery[CredentialDefinition.Filter] | ||
): Task[Repository.SearchResult[CredentialDefinition]] = { | ||
storeRef.get.map { store => | ||
val filtered = store.values.filter { credDef => | ||
query.filter.author.forall(_ == credDef.author) && | ||
query.filter.name.forall(_ == credDef.name) && | ||
query.filter.version.forall(_ == credDef.version) && | ||
query.filter.tag.forall(tag => credDef.tag == tag) | ||
} | ||
val paginated = filtered.slice(query.skip, query.skip + query.limit) | ||
Repository.SearchResult(paginated.toSeq, paginated.size, filtered.size) | ||
} | ||
} | ||
} | ||
|
||
object CredentialDefinitionRepositoryInMemory { | ||
val layer: ULayer[CredentialDefinitionRepository[Task]] = ZLayer.fromZIO( | ||
Ref | ||
.make(Map.empty[UUID, CredentialDefinition]) | ||
.map(CredentialDefinitionRepositoryInMemory(_)) | ||
) | ||
} |
Oops, something went wrong.