Allow users of password auth to create identity proofs

This commit is contained in:
silverpill 2022-08-15 20:11:58 +00:00
parent a80c11b99c
commit 5f24af4dbf
4 changed files with 39 additions and 12 deletions

View file

@ -101,6 +101,14 @@ paths:
/api/v1/accounts/identity_proof:
get:
summary: Get unsigned data for identity proof.
parameters:
- name: did
in: query
description: Identifier (DID)
required: true
schema:
type: string
example: 'did:pkh:eip155:1:0xb9c5714089478a327f09197987f16f9e5d936e8a'
responses:
200:
description: Successful operation
@ -113,8 +121,8 @@ paths:
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
400:
description: Invalid request parameters
post:
summary: Submit identity proof.
requestBody:
@ -123,6 +131,10 @@ paths:
schema:
type: object
properties:
did:
description: Identifier (DID)
type: string
example: 'did:pkh:eip155:1:0xb9c5714089478a327f09197987f16f9e5d936e8a'
signature:
description: Signature value.
type: string
@ -135,9 +147,7 @@ paths:
schema:
$ref: '#/components/schemas/Account'
400:
description: Invalid signature.
403:
description: User's wallet address is not known
description: Invalid proof data.
/api/v1/accounts/authorize_subscription:
get:
summary: Get authorization for setting up paid subscription.

View file

@ -235,6 +235,11 @@ impl AccountUpdateData {
}
}
#[derive(Deserialize)]
pub struct IdentityClaimQueryParams {
pub did: String,
}
#[derive(Serialize)]
pub struct IdentityClaim {
pub claim: String,
@ -242,6 +247,7 @@ pub struct IdentityClaim {
#[derive(Deserialize)]
pub struct IdentityProofData {
pub did: String,
pub signature: String,
}

View file

@ -72,6 +72,7 @@ use super::types::{
FollowData,
FollowListQueryParams,
IdentityClaim,
IdentityClaimQueryParams,
IdentityProofData,
RelationshipQueryParams,
SearchDidQueryParams,
@ -224,13 +225,13 @@ async fn get_identity_claim(
auth: BearerAuth,
config: web::Data<Config>,
db_pool: web::Data<Pool>,
query_params: web::Query<IdentityClaimQueryParams>,
) -> 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_address(&config.default_currency(), wallet_address);
let did = query_params.did.parse::<DidPkh>()
.map_err(|_| ValidationError("invalid DID"))?;
let claim = create_identity_claim(&actor_id, &did)
.map_err(|_| HttpError::InternalError)?;
let response = IdentityClaim { claim };
@ -247,9 +248,18 @@ async fn create_identity_proof(
let db_client = &**get_database_client(&db_pool).await?;
let mut 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_address(&config.default_currency(), wallet_address);
let did = proof_data.did.parse::<DidPkh>()
.map_err(|_| ValidationError("invalid DID"))?;
if did.currency() != Some(config.default_currency()) {
return Err(ValidationError("unsupported chain ID").into());
};
let maybe_public_address =
current_user.public_wallet_address(&config.default_currency());
if let Some(address) = maybe_public_address {
if did.address != address {
return Err(ValidationError("DID doesn't match current identity").into());
};
};
verify_identity_proof(
&actor_id,
&did,

View file

@ -48,7 +48,8 @@ impl User {
/// Returns wallet address if it is verified
pub fn public_wallet_address(&self, currency: &Currency) -> Option<String> {
for proof in self.profile.identity_proofs.clone().into_inner() {
// Return first match (it's safe if user is local)
// Return the first matching address, because only
// one proof per currency is allowed.
if let Some(ref address_currency) = proof.issuer.currency() {
if address_currency == currency {
return Some(proof.issuer.address);