Add views for generating address ownership proof

This commit is contained in:
silverpill 2022-04-22 10:10:54 +00:00
parent e697461e70
commit 356592bc71
3 changed files with 100 additions and 0 deletions

View file

@ -8,6 +8,7 @@ paths:
/oauth/token:
post:
summary: Returns an access token, to be used during API calls that are not public.
description: EIP-4361 auth doesn't require blockchain integration.
requestBody:
content:
application/json:
@ -102,6 +103,46 @@ paths:
$ref: '#/components/schemas/Account'
400:
description: Invalid user data
/api/v1/accounts/identity_proof:
get:
summary: Get unsigned data for identity proof.
responses:
200:
description: Successful operation
content:
application/json:
schema:
type: object
properties:
claim:
description: Identity claim serialized as compact JSON.
type: string
example: '{"id":"https://example.com/users/1","ownerOf":"did:pkh:eip155:1:0xb9c5714089478a327f09197987f16f9e5d936e8a"}'
403:
description: User's wallet address is not known
post:
summary: Submit identity proof.
requestBody:
content:
application/json:
schema:
type: object
properties:
signature:
description: Signature value.
type: string
example: '3312dacd...'
responses:
200:
description: Successful operation
content:
application/json:
schema:
$ref: '#/components/schemas/Account'
400:
description: Invalid signature.
403:
description: User's wallet address is not known
/api/v1/accounts/authorize_subscription:
get:
summary: Get authorization for setting up paid subscription.

View file

@ -185,6 +185,16 @@ impl AccountUpdateData {
}
}
#[derive(Serialize)]
pub struct IdentityClaim {
pub claim: String,
}
#[derive(Deserialize)]
pub struct IdentityProofData {
pub signature: String,
}
// TODO: actix currently doesn't support parameter arrays
// https://github.com/actix/actix-web/issues/2044
#[derive(Deserialize)]

View file

@ -14,6 +14,11 @@ use crate::database::{Pool, get_database_client};
use crate::errors::{DatabaseError, HttpError, ValidationError};
use crate::ethereum::eip4361::verify_eip4361_signature;
use crate::ethereum::gate::is_allowed_user;
use crate::ethereum::identity::{
DidPkh,
create_identity_claim,
verify_identity_proof,
};
use crate::ethereum::subscriptions::create_subscription_signature;
use crate::mastodon_api::oauth::auth::get_current_user;
use crate::models::posts::helpers::{
@ -57,6 +62,8 @@ use super::types::{
AccountUpdateData,
FollowData,
FollowListQueryParams,
IdentityClaim,
IdentityProofData,
RelationshipQueryParams,
StatusListQueryParams,
};
@ -213,6 +220,46 @@ async fn update_credentials(
Ok(HttpResponse::Ok().json(account))
}
#[get("/identity_proof")]
async fn get_identity_claim(
auth: BearerAuth,
config: web::Data<Config>,
db_pool: web::Data<Pool>,
) -> Result<HttpResponse, HttpError> {
let db_client = &**get_database_client(&db_pool).await?;
let current_user = get_current_user(db_client, auth.token()).await?;
let actor_id = current_user.profile.actor_id(&config.instance_url());
let wallet_address = current_user.wallet_address.as_ref()
.ok_or(HttpError::PermissionError)?;
let did = DidPkh::from_ethereum_address(wallet_address);
let claim = create_identity_claim(&actor_id, &did)
.map_err(|_| HttpError::InternalError)?;
let response = IdentityClaim { claim };
Ok(HttpResponse::Ok().json(response))
}
#[post("/identity_proof")]
async fn create_identity_proof(
auth: BearerAuth,
config: web::Data<Config>,
db_pool: web::Data<Pool>,
proof_data: web::Json<IdentityProofData>,
) -> Result<HttpResponse, HttpError> {
let db_client = &**get_database_client(&db_pool).await?;
let current_user = get_current_user(db_client, auth.token()).await?;
let actor_id = current_user.profile.actor_id(&config.instance_url());
let wallet_address = current_user.wallet_address.as_ref()
.ok_or(HttpError::PermissionError)?;
let did = DidPkh::from_ethereum_address(wallet_address);
verify_identity_proof(
&actor_id,
&did,
&proof_data.signature,
)?;
let account = Account::from_user(current_user, &config.instance_url());
Ok(HttpResponse::Ok().json(account))
}
#[get("/authorize_subscription")]
async fn authorize_subscription(
auth: BearerAuth,
@ -455,6 +502,8 @@ pub fn account_api_scope() -> Scope {
.service(get_relationships_view)
.service(verify_credentials)
.service(update_credentials)
.service(get_identity_claim)
.service(create_identity_proof)
.service(authorize_subscription)
// Routes with account ID
.service(get_account)