Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(cat-gateway): cardano/rbac/registrations endpoint API definition. #1936

Open
wants to merge 81 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 10 commits
Commits
Show all changes
81 commits
Select commit Hold shift + click to select a range
ba09b4d
move RBAC API definition under its own mod
Mr-Leshiy Feb 26, 2025
8659dec
wip
Mr-Leshiy Feb 26, 2025
4a2522a
add RbacRegistrations type
Mr-Leshiy Feb 27, 2025
2c7f2bb
Merge branch 'main' into feat/rbac-api
Mr-Leshiy Feb 27, 2025
26f3a12
add TxnId type
Mr-Leshiy Feb 27, 2025
bccbb00
wip
Mr-Leshiy Feb 27, 2025
500a014
Merge branch 'main' into feat/rbac-api
Mr-Leshiy Feb 27, 2025
34b788b
wip
Mr-Leshiy Feb 28, 2025
9b3ddaf
add NoneOrApiKey security schema
Mr-Leshiy Feb 28, 2025
cb6d7ba
add detailed flag
Mr-Leshiy Feb 28, 2025
ccad343
Update catalyst-gateway/bin/src/service/api/cardano/rbac/mod.rs
Mr-Leshiy Feb 28, 2025
de03f6f
Merge branch 'main' into feat/rbac-api
Mr-Leshiy Mar 4, 2025
a511001
wip
Mr-Leshiy Mar 4, 2025
583f163
add CatIdOrStake
Mr-Leshiy Mar 4, 2025
8f95f28
wip
Mr-Leshiy Mar 4, 2025
8629e14
wip
Mr-Leshiy Mar 4, 2025
a917f56
wip
Mr-Leshiy Mar 4, 2025
d85d6e2
wip
Mr-Leshiy Mar 4, 2025
a912785
wip
Mr-Leshiy Mar 4, 2025
a69581d
wip
Mr-Leshiy Mar 4, 2025
a7958a5
wip
Mr-Leshiy Mar 4, 2025
e0d0da6
wip
Mr-Leshiy Mar 5, 2025
63a2cde
Merge branch 'main' into feat/rbac-api
Mr-Leshiy Mar 5, 2025
2e9cfe3
fix spelling
Mr-Leshiy Mar 5, 2025
5809404
fix fmt
Mr-Leshiy Mar 5, 2025
8aa10a2
fix spelling
Mr-Leshiy Mar 5, 2025
2f10ba9
wip
Mr-Leshiy Mar 5, 2025
f49011a
add sorting
Mr-Leshiy Mar 5, 2025
2d0036c
fix
Mr-Leshiy Mar 5, 2025
92cc29f
wip
Mr-Leshiy Mar 5, 2025
fd72f75
Merge branch 'main' into feat/rbac-api
Mr-Leshiy Mar 5, 2025
4cbf98e
wip
Mr-Leshiy Mar 5, 2025
f29b93c
cleanup
Mr-Leshiy Mar 5, 2025
80d595c
Merge branch 'main' into feat/rbac-api
Mr-Leshiy Mar 6, 2025
85c9946
Update catalyst-gateway/bin/src/service/common/types/cardano/transact…
Mr-Leshiy Mar 12, 2025
75b8f78
Update catalyst-gateway/bin/src/service/common/types/cardano/catalyst…
Mr-Leshiy Mar 12, 2025
2339d27
wip
Mr-Leshiy Mar 12, 2025
1bef923
wip
Mr-Leshiy Mar 12, 2025
c78ef2f
feat(cat-gateway): RBAC registrations endpoint business logic impleme…
stanislav-tkach Mar 12, 2025
c1dbf49
Merge branch 'main' into feat/rbac-api
stanislav-tkach Mar 17, 2025
aeb1710
Merge branch 'main' into feat/rbac-api
stanislav-tkach Mar 17, 2025
9b296c4
wip
stanislav-tkach Mar 17, 2025
9e541fe
Merge branch 'main' into feat/rbac-api
stanislav-tkach Mar 17, 2025
db392b8
Merge branch 'main' into feat/rbac-api
stanislav-tkach Mar 18, 2025
5b233a6
Merge branch 'main' into feat/rbac-api
stanislav-tkach Mar 18, 2025
3ac3032
wip
stanislav-tkach Mar 18, 2025
fcb247a
wip
stanislav-tkach Mar 20, 2025
482cbe9
Merge branch 'main' into feat/rbac-api
stanislav-tkach Mar 20, 2025
3af5f68
wip
stanislav-tkach Mar 20, 2025
1f02ec0
Merge branch 'main' into feat/rbac-api
stanislav-tkach Mar 20, 2025
ab78ad4
wip
stanislav-tkach Mar 20, 2025
b981906
Merge branch 'main' into feat/rbac-api
stanislav-tkach Mar 21, 2025
086041c
wip
stanislav-tkach Mar 23, 2025
f86242b
Merge branch 'main' into feat/rbac-api
stanislav-tkach Mar 23, 2025
a686647
wip
stanislav-tkach Mar 23, 2025
173ad9e
wip
stanislav-tkach Mar 23, 2025
681464b
Encode certificates and keys
stanislav-tkach Mar 24, 2025
7c788aa
clippy
stanislav-tkach Mar 24, 2025
4e3e894
Merge branch 'main' into feat/rbac-api
stanislav-tkach Mar 24, 2025
f81d733
revert is_all check
stanislav-tkach Mar 24, 2025
967257b
Merge branch 'main' into feat/rbac-api
stanislav-tkach Mar 25, 2025
01c370a
Fix comment
stanislav-tkach Mar 25, 2025
f0bd185
Merge branch 'main' into feat/rbac-api
stanislav-tkach Mar 25, 2025
b434b84
Fix documentation warnings
stanislav-tkach Mar 25, 2025
b3d344f
Add example attribute
stanislav-tkach Mar 25, 2025
649e14e
Merge branch 'main' into feat/rbac-api
stanislav-tkach Mar 25, 2025
0584e0b
Remove the default attribute for BooleanFlag
stanislav-tkach Mar 25, 2025
1467a8f
Hex encode certificates
stanislav-tkach Mar 25, 2025
460cde5
Add HexEncodedBinaryData type
stanislav-tkach Mar 25, 2025
2c93561
Key data list type
stanislav-tkach Mar 25, 2025
016685b
Extended data
stanislav-tkach Mar 25, 2025
3b20873
Payment data list
stanislav-tkach Mar 25, 2025
fe64c15
Role map
stanislav-tkach Mar 25, 2025
bc3e91c
Remove unneeded minicbor features
stanislav-tkach Mar 26, 2025
25f1786
Join registration queries
stanislav-tkach Mar 26, 2025
0a9b3db
Merge branch 'main' into feat/rbac-api
stanislav-tkach Mar 26, 2025
cebdb89
Merge branch 'main' into feat/rbac-api
stanislav-tkach Mar 26, 2025
0ea9481
Merge branch 'main' into feat/rbac-api
saibatizoku Mar 26, 2025
679917d
Merge branch 'main' into feat/rbac-api
stanislav-tkach Mar 27, 2025
c982fc3
Apply review comments
stanislav-tkach Mar 27, 2025
ebc44eb
Merge branch 'main' into feat/rbac-api
stanislav-tkach Mar 27, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions catalyst-gateway/bin/src/db/index/queries/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ pub(crate) enum PreparedSelectQuery {
/// Get Catalyst ID by stake address.
CatalystIdByStakeAddress,
/// Get RBAC registrations by Catalyst ID.
#[allow(dead_code)]
RbacRegistrationsByCatalystId,
/// Get invalid RBAC registrations by Catalyst ID.
RbacInvalidRegistrationsByCatalystId,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ const QUERY: &str = include_str!("../cql/get_rbac_registrations_catalyst_id.cql"

/// Get registrations by Catalyst ID query params.
#[derive(SerializeRow)]
#[allow(dead_code)]
pub(crate) struct QueryParams {
/// A Catalyst ID.
pub catalyst_id: DbCatalystId,
Expand Down Expand Up @@ -53,6 +54,7 @@ impl Query {
}

/// Executes a get registrations by Catalyst ID query.
#[allow(dead_code)]
pub(crate) async fn execute(
session: &CassandraSession, params: QueryParams,
) -> anyhow::Result<TypedRowStream<Query>> {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
//! Implementation of the GET `/cardano/cip36` endpoint

use poem::http::HeaderMap;
use tracing::error;

use self::cardano::query::stake_or_voter::StakeAddressOrPublicKey;
Expand All @@ -21,7 +20,7 @@ use crate::{
pub(crate) async fn cip36_registrations(
lookup: Option<cardano::query::stake_or_voter::StakeOrVoter>, asat: Option<SlotNo>,
_page: common::types::generic::query::pagination::Page,
_limit: common::types::generic::query::pagination::Limit, _headers: &HeaderMap,
_limit: common::types::generic::query::pagination::Limit,
) -> AllRegistration {
let Some(session) = CassandraSession::get(true) else {
error!("Failed to acquire db session");
Expand Down
23 changes: 13 additions & 10 deletions catalyst-gateway/bin/src/service/api/cardano/cip36/filter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,18 +15,21 @@ use super::{
AllRegistration, Cip36Details, Cip36Registration, Cip36RegistrationList,
Cip36RegistrationsForVotingPublicKey,
},
Ed25519HexEncodedPublicKey, SlotNo,
SlotNo,
};
use crate::db::index::{
queries::registrations::{
get_all_invalids::{GetAllInvalidRegistrationsParams, GetAllInvalidRegistrationsQuery},
get_all_registrations::{GetAllRegistrationsParams, GetAllRegistrationsQuery},
get_from_stake_addr::{GetRegistrationParams, GetRegistrationQuery},
get_from_stake_address::{GetStakeAddrParams, GetStakeAddrQuery},
get_from_vote_key::{GetStakeAddrFromVoteKeyParams, GetStakeAddrFromVoteKeyQuery},
get_invalid::{GetInvalidRegistrationParams, GetInvalidRegistrationQuery},
use crate::{
db::index::{
queries::registrations::{
get_all_invalids::{GetAllInvalidRegistrationsParams, GetAllInvalidRegistrationsQuery},
get_all_registrations::{GetAllRegistrationsParams, GetAllRegistrationsQuery},
get_from_stake_addr::{GetRegistrationParams, GetRegistrationQuery},
get_from_stake_address::{GetStakeAddrParams, GetStakeAddrQuery},
get_from_vote_key::{GetStakeAddrFromVoteKeyParams, GetStakeAddrFromVoteKeyQuery},
get_invalid::{GetInvalidRegistrationParams, GetInvalidRegistrationQuery},
},
session::CassandraSession,
},
session::CassandraSession,
service::common::types::generic::ed25519_public_key::Ed25519HexEncodedPublicKey,
};

/// Get registration given a stake key hash, it can be time specific based on asat param,
Expand Down
13 changes: 4 additions & 9 deletions catalyst-gateway/bin/src/service/api/cardano/cip36/mod.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
//! CIP36 Registration Endpoints

use poem::http::HeaderMap;
use poem_openapi::{param::Query, payload::Json, OpenApi};
use response::Cip36RegistrationUnprocessableContent;

use self::{cardano::slot_no::SlotNo, common::auth::none::NoAuthorization};
use super::Ed25519HexEncodedPublicKey;
use self::cardano::slot_no::SlotNo;
use crate::service::common::{
self,
auth::none_or_api_key::NoneOrApiKey,
tags::ApiTags,
types::cardano::{self},
};
Expand Down Expand Up @@ -48,16 +47,13 @@ impl Api {
asat: Query<Option<cardano::query::AsAt>>,
page: Query<Option<common::types::generic::query::pagination::Page>>,
limit: Query<Option<common::types::generic::query::pagination::Limit>>,
/// Headers, used if the query is requesting ALL to determine if the secret API
/// Key is also defined.
headers: &HeaderMap,
_auth: NoAuthorization,
api_key: NoneOrApiKey,
) -> response::AllRegistration {
// Special validation for the `lookup` parameter.
// If the parameter is ALL, BUT we do not have a valid API Key, just report the parameter
// is invalid.
if let Some(lookup) = lookup.0.clone() {
if lookup.is_all(headers).is_err() {
if lookup.is_all() && matches!(api_key, NoneOrApiKey::None(_)) {
return response::Cip36Registration::UnprocessableContent(Json(
Cip36RegistrationUnprocessableContent::new(
"Invalid Stake Address or Voter key",
Expand All @@ -72,7 +68,6 @@ impl Api {
SlotNo::into_option(asat.0),
page.0.unwrap_or_default(),
limit.0.unwrap_or_default(),
headers,
)
.await
}
Expand Down
80 changes: 3 additions & 77 deletions catalyst-gateway/bin/src/service/api/cardano/mod.rs
Original file line number Diff line number Diff line change
@@ -1,83 +1,9 @@
//! Cardano API endpoints
use poem_openapi::{param::Path, OpenApi};

use crate::service::common::{
auth::none_or_rbac::NoneOrRBAC,
objects::cardano::hash::Hash128,
tags::ApiTags,
types::{
cardano::{catalyst_id::CatalystId, cip19_stake_address::Cip19StakeAddress},
generic::ed25519_public_key::Ed25519HexEncodedPublicKey,
},
};

pub(crate) mod cip36;
mod rbac;
pub(crate) mod rbac;
// mod registration_get;
pub(crate) mod staking;

/// Cardano Follower API Endpoints
pub(crate) struct Api;

#[OpenApi(tag = "ApiTags::Cardano")]
impl Api {
// TODO: "Chain root" was replaced by "Catalyst ID", so this endpoint needs to be updated
// or removed.
#[oai(
path = "/draft/rbac/chain_root/:stake_address",
method = "get",
operation_id = "rbacChainRootGet"
)]
/// Get RBAC chain root
///
/// This endpoint returns the RBAC certificate chain root for a given stake address.
async fn rbac_chain_root_get(
&self,
/// Stake address to get the chain root for.
Path(stake_address): Path<Cip19StakeAddress>,
/// No Authorization required, but Token permitted.
_auth: NoneOrRBAC,
) -> rbac::chain_root_get::AllResponses {
rbac::chain_root_get::endpoint(stake_address).await
}

#[oai(
path = "/draft/rbac/registrations/:catalyst_id",
method = "get",
operation_id = "rbacRegistrations"
)]
/// Get registrations by Catalyst short ID.
///
/// This endpoint returns RBAC registrations for the given Catalyst short identifier.
async fn rbac_registrations_get(
&self,
/// A Catalyst short ID to get the registrations for.
Path(catalyst_id): Path<CatalystId>,
/// No Authorization required, but Token permitted.
_auth: NoneOrRBAC,
) -> rbac::registrations_get::AllResponses {
rbac::registrations_get::endpoint(catalyst_id.into()).await
}

// TODO: "Chain root" was replaced by "Catalyst ID", so this endpoint needs to be updated
// or removed.
#[oai(
path = "/draft/rbac/role0_chain_root/:role0_key",
method = "get",
operation_id = "rbacRole0KeyChainRoot"
)]
/// Get RBAC chain root for a given role0 key.
///
/// This endpoint returns the RBAC certificate chain root for a given role 0 key.
async fn rbac_role0_key_chain_root(
&self, /// Role0 key to get the chain root for.
Path(role0_key): Path<Hash128>,
/// No Authorization required, but Token permitted.
_auth: NoneOrRBAC,
) -> rbac::role0_chain_root_get::AllResponses {
rbac::role0_chain_root_get::endpoint(role0_key.to_string()).await
}
}

/// Cardano API Endpoints
pub(crate) type CardanoApi = (Api, staking::Api, cip36::Api);
/// All Cardano API Endpoints
pub(crate) type CardanoApi = (rbac::Api, staking::Api, cip36::Api);

This file was deleted.

57 changes: 54 additions & 3 deletions catalyst-gateway/bin/src/service/api/cardano/rbac/mod.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,56 @@
//! RBAC endpoints.

pub(crate) mod chain_root_get;
pub(crate) mod registrations_get;
pub(crate) mod role0_chain_root_get;
use poem_openapi::{param::Query, payload::Json, OpenApi};

use crate::service::common::{
auth::{none_or_api_key::NoneOrApiKey, none_or_rbac::NoneOrRBAC},
tags::ApiTags,
types::cardano::query::stake_or_voter::StakeOrVoter,
};

mod rbac_registration;
mod registrations_get;
mod unprocessable_content;

/// Cardano RBAC API Endpoints
pub(crate) struct Api;

#[OpenApi(tag = "ApiTags::Cardano")]
impl Api {
#[oai(
path = "/draft/rbac/registrations/:catalyst_id",
method = "get",
operation_id = "rbacRegistrations"
)]
/// Get RBAC registrations
///
/// This endpoint returns RBAC registrations by provided auth Catalyst Id credentials
/// or by the `lookup` argument if provided.
async fn rbac_registrations_get(
&self,
/// Stake address to get the RBACE registration for.
Query(lookup): Query<Option<StakeOrVoter>>,
/// A flag which enalbes returning all corresponded Cip509 registrations
Query(detailed): Query<Option<bool>>,
/// No Authorization required, but Token permitted.
_auth: NoneOrRBAC,
/// No Authorization required, but Api Key permitted.
api_key: NoneOrApiKey,
) -> registrations_get::AllResponses {
// Special validation for the `lookup` parameter.
// If the parameter is ALL, BUT we do not have a valid API Key, just report the parameter
// is invalid.
if let Some(lookup) = lookup.clone() {
if lookup.is_all() && matches!(api_key, NoneOrApiKey::None(_)) {
return registrations_get::Responses::UnprocessableContent(Json(
unprocessable_content::RbacUnprocessableContent::new(
"Invalid Stake Address or Voter key",
),
))
.into();
}
}
let detailed = detailed.unwrap_or_default();
registrations_get::endpoint(lookup, detailed).await
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
//! Bad Rbac registration response object.

use poem_openapi::{types::Example, Object};

use crate::service::common::types::cardano::catalyst_id::CatalystId;

/// RBAC Registrations, contains a latest valid and invalid registration data.
#[derive(Object)]
#[oai(example = true)]
pub(crate) struct RbacRegistrations {
/// User's catalyst id
catalyst_id: CatalystId,
/// Latest valid RBAC registration
#[oai(skip_serializing_if_is_none)]
finalised: Option<RbacRegistration>,
/// Latest invalid RBAC registration
#[oai(skip_serializing_if_is_none)]
volatile: Option<RbacRegistration>,
}

impl Example for RbacRegistrations {
fn example() -> Self {
Self {
catalyst_id: CatalystId::example(),
finalised: Some(RbacRegistration::example()),
volatile: Some(RbacRegistration::example()),
}
}
}

/// Single RBAC Registrations.
#[derive(Object)]
#[oai(example = true)]
pub(crate) struct RbacRegistration {
/// Registration chain
chain: serde_json::Value,
/// All Cip509 registrations which formed a current registration chain
#[oai(skip_serializing_if_is_empty)]
details: Vec<serde_json::Value>,
}

impl Example for RbacRegistration {
fn example() -> Self {
Self {
chain: serde_json::Value::Null,
details: vec![],
}
}
}
Loading