Page MenuHomePhabricator

D12575.diff
No OneTemporary

D12575.diff

diff --git a/services/identity/src/client_service.rs b/services/identity/src/client_service.rs
--- a/services/identity/src/client_service.rs
+++ b/services/identity/src/client_service.rs
@@ -35,7 +35,7 @@
use crate::grpc_utils::{
DeviceKeyUploadActions, RegistrationActions, SignedNonce
};
-use crate::nonce::generate_nonce_data;
+use crate::nonce::{generate_nonce_data, NonceVerification};
use crate::reserved_users::{
validate_account_ownership_message_and_get_user_id,
validate_add_reserved_usernames_message,
@@ -92,7 +92,7 @@
#[derive(derive_more::Constructor)]
pub struct ClientService {
- client: DatabaseClient,
+ pub client: DatabaseClient,
}
#[tonic::async_trait]
@@ -1064,37 +1064,6 @@
}
}
- async fn verify_and_remove_nonce(
- &self,
- nonce: &str,
- ) -> Result<(), tonic::Status> {
- match self
- .client
- .get_nonce_from_nonces_table(nonce)
- .await
- .map_err(handle_db_error)?
- {
- None => {
- return Err(tonic::Status::invalid_argument(
- tonic_status_messages::INVALID_NONCE,
- ))
- }
- Some(nonce) if nonce.is_expired() => {
- // we don't need to remove the nonce from the table here
- // because the DynamoDB TTL will take care of it
- return Err(tonic::Status::aborted(
- tonic_status_messages::NONCE_EXPIRED,
- ));
- }
- Some(nonce_data) => self
- .client
- .remove_nonce_from_nonces_table(&nonce_data.nonce)
- .await
- .map_err(handle_db_error)?,
- };
- Ok(())
- }
-
async fn get_keyserver_device_to_remove(
&self,
user_id: &str,
diff --git a/services/identity/src/grpc_services/authenticated.rs b/services/identity/src/grpc_services/authenticated.rs
--- a/services/identity/src/grpc_services/authenticated.rs
+++ b/services/identity/src/grpc_services/authenticated.rs
@@ -16,7 +16,7 @@
use tracing::{debug, error, trace, warn};
use super::protos::auth::{
- identity_client_service_server::IdentityClientService,
+ identity_client_service_server::IdentityClientService, AddWalletRequest,
DeletePasswordUserFinishRequest, DeletePasswordUserStartRequest,
DeletePasswordUserStartResponse, GetDeviceListRequest, GetDeviceListResponse,
InboundKeyInfo, InboundKeysForUserRequest, InboundKeysForUserResponse,
@@ -32,7 +32,7 @@
#[derive(derive_more::Constructor)]
pub struct AuthenticatedService {
- db_client: DatabaseClient,
+ pub db_client: DatabaseClient,
}
fn get_auth_info(req: &Request<()>) -> Option<(String, String, String)> {
@@ -824,6 +824,13 @@
Ok(Response::new(Empty {}))
}
+
+ async fn add_wallet(
+ &self,
+ _request: tonic::Request<AddWalletRequest>,
+ ) -> Result<Response<Empty>, tonic::Status> {
+ unimplemented!()
+ }
}
#[allow(dead_code)]
diff --git a/services/identity/src/grpc_services/shared.rs b/services/identity/src/grpc_services/shared.rs
--- a/services/identity/src/grpc_services/shared.rs
+++ b/services/identity/src/grpc_services/shared.rs
@@ -2,12 +2,16 @@
use tonic::{Request, Status};
use tracing::trace;
+use crate::client_service::ClientService;
use crate::constants::{
request_metadata, tonic_status_messages, MIN_SUPPORTED_NATIVE_VERSION,
};
+use crate::database::DatabaseClient;
pub use grpc_clients::identity::shared::PlatformMetadata;
+use super::authenticated::AuthenticatedService;
+
pub fn version_interceptor(req: Request<()>) -> Result<Request<()>, Status> {
trace!("Intercepting request to check version: {:?}", req);
@@ -61,3 +65,19 @@
let raw_value = req.metadata().get(key)?;
raw_value.to_str().ok().map(|s| s.to_string())
}
+
+pub trait HasClient {
+ fn client(&self) -> &DatabaseClient;
+}
+
+impl HasClient for ClientService {
+ fn client(&self) -> &DatabaseClient {
+ &self.client
+ }
+}
+
+impl HasClient for AuthenticatedService {
+ fn client(&self) -> &DatabaseClient {
+ &self.db_client
+ }
+}
diff --git a/services/identity/src/nonce.rs b/services/identity/src/nonce.rs
--- a/services/identity/src/nonce.rs
+++ b/services/identity/src/nonce.rs
@@ -4,8 +4,11 @@
CryptoRng, Rng,
};
-use crate::constants::NONCE_LENGTH;
-use crate::constants::NONCE_TTL_DURATION;
+use crate::{
+ client_service::handle_db_error,
+ constants::{tonic_status_messages, NONCE_TTL_DURATION},
+};
+use crate::{constants::NONCE_LENGTH, grpc_services::shared::HasClient};
pub fn generate_nonce_data(rng: &mut (impl Rng + CryptoRng)) -> NonceData {
let nonce = Alphanumeric.sample_string(rng, NONCE_LENGTH);
@@ -30,3 +33,45 @@
Utc::now() > self.expiration_time
}
}
+
+#[tonic::async_trait]
+pub trait NonceVerification {
+ async fn verify_and_remove_nonce(
+ &self,
+ nonce: &str,
+ ) -> Result<(), tonic::Status>;
+}
+
+#[tonic::async_trait]
+impl<T: HasClient + Sync> NonceVerification for T {
+ async fn verify_and_remove_nonce(
+ &self,
+ nonce: &str,
+ ) -> Result<(), tonic::Status> {
+ match self
+ .client()
+ .get_nonce_from_nonces_table(nonce)
+ .await
+ .map_err(handle_db_error)?
+ {
+ None => {
+ return Err(tonic::Status::invalid_argument(
+ tonic_status_messages::INVALID_NONCE,
+ ))
+ }
+ Some(nonce) if nonce.is_expired() => {
+ // we don't need to remove the nonce from the table here
+ // because the DynamoDB TTL will take care of it
+ return Err(tonic::Status::aborted(
+ tonic_status_messages::NONCE_EXPIRED,
+ ));
+ }
+ Some(nonce_data) => self
+ .client()
+ .remove_nonce_from_nonces_table(&nonce_data.nonce)
+ .await
+ .map_err(handle_db_error)?,
+ };
+ Ok(())
+ }
+}
diff --git a/shared/protos/identity_auth.proto b/shared/protos/identity_auth.proto
--- a/shared/protos/identity_auth.proto
+++ b/shared/protos/identity_auth.proto
@@ -90,6 +90,8 @@
// It doesn't require any input - all values are passed via request metadata.
rpc SyncPlatformDetails(identity.unauth.Empty) returns
(identity.unauth.Empty) {}
+
+ rpc AddWallet(AddWalletRequest) returns (identity.unauth.Empty) {}
}
// Helper types
@@ -298,3 +300,10 @@
message UserIdentitiesResponse {
map<string, Identity> identities = 1;
}
+
+// AddWallet
+
+message AddWalletRequest {
+ string siwe_message = 1;
+ string siwe_signature = 2;
+}
diff --git a/web/protobufs/identity-auth-client.cjs b/web/protobufs/identity-auth-client.cjs
--- a/web/protobufs/identity-auth-client.cjs
+++ b/web/protobufs/identity-auth-client.cjs
@@ -1237,5 +1237,65 @@
};
-module.exports = proto.identity.auth;
+/**
+ * @const
+ * @type {!grpc.web.MethodDescriptor<
+ * !proto.identity.auth.AddWalletRequest,
+ * !proto.identity.unauth.Empty>}
+ */
+const methodDescriptor_IdentityClientService_AddWallet = new grpc.web.MethodDescriptor(
+ '/identity.auth.IdentityClientService/AddWallet',
+ grpc.web.MethodType.UNARY,
+ proto.identity.auth.AddWalletRequest,
+ identity_unauth_pb.Empty,
+ /**
+ * @param {!proto.identity.auth.AddWalletRequest} request
+ * @return {!Uint8Array}
+ */
+ function(request) {
+ return request.serializeBinary();
+ },
+ identity_unauth_pb.Empty.deserializeBinary
+);
+
+/**
+ * @param {!proto.identity.auth.AddWalletRequest} request The
+ * request proto
+ * @param {?Object<string, string>} metadata User defined
+ * call metadata
+ * @param {function(?grpc.web.RpcError, ?proto.identity.unauth.Empty)}
+ * callback The callback function(error, response)
+ * @return {!grpc.web.ClientReadableStream<!proto.identity.unauth.Empty>|undefined}
+ * The XHR Node Readable Stream
+ */
+proto.identity.auth.IdentityClientServiceClient.prototype.addWallet =
+ function(request, metadata, callback) {
+ return this.client_.rpcCall(this.hostname_ +
+ '/identity.auth.IdentityClientService/AddWallet',
+ request,
+ metadata || {},
+ methodDescriptor_IdentityClientService_AddWallet,
+ callback);
+};
+
+
+/**
+ * @param {!proto.identity.auth.AddWalletRequest} request The
+ * request proto
+ * @param {?Object<string, string>=} metadata User defined
+ * call metadata
+ * @return {!Promise<!proto.identity.unauth.Empty>}
+ * Promise that resolves to the response
+ */
+proto.identity.auth.IdentityClientServicePromiseClient.prototype.addWallet =
+ function(request, metadata) {
+ return this.client_.unaryCall(this.hostname_ +
+ '/identity.auth.IdentityClientService/AddWallet',
+ request,
+ metadata || {},
+ methodDescriptor_IdentityClientService_AddWallet);
+};
+
+
+module.exports = proto.identity.auth;
diff --git a/web/protobufs/identity-auth-client.cjs.flow b/web/protobufs/identity-auth-client.cjs.flow
--- a/web/protobufs/identity-auth-client.cjs.flow
+++ b/web/protobufs/identity-auth-client.cjs.flow
@@ -143,6 +143,13 @@
callback: (err: grpcWeb.RpcError,
response: identityStructs.Empty) => void
): grpcWeb.ClientReadableStream<identityStructs.Empty>;
+
+ addWallet(
+ request: identityAuthStructs.AddWalletRequest,
+ metadata: grpcWeb.Metadata | void,
+ callback: (err: grpcWeb.RpcError,
+ response: identityStructs.Empty) => void
+ ): grpcWeb.ClientReadableStream<identityStructs.Empty>;
}
declare export class IdentityClientServicePromiseClient {
@@ -245,5 +252,9 @@
metadata?: grpcWeb.Metadata
): Promise<identityStructs.Empty>;
-}
+ addWallet(
+ request: identityAuthStructs.AddWalletRequest,
+ metadata?: grpcWeb.Metadata
+ ): Promise<identityStructs.Empty>;
+}
diff --git a/web/protobufs/identity-auth-structs.cjs b/web/protobufs/identity-auth-structs.cjs
--- a/web/protobufs/identity-auth-structs.cjs
+++ b/web/protobufs/identity-auth-structs.cjs
@@ -24,6 +24,7 @@
var identity_unauth_pb = require('./identity-unauth-structs.cjs');
goog.object.extend(proto, identity_unauth_pb);
+goog.exportSymbol('proto.identity.auth.AddWalletRequest', null, global);
goog.exportSymbol('proto.identity.auth.DeletePasswordUserFinishRequest', null, global);
goog.exportSymbol('proto.identity.auth.DeletePasswordUserStartRequest', null, global);
goog.exportSymbol('proto.identity.auth.DeletePasswordUserStartResponse', null, global);
@@ -618,6 +619,27 @@
*/
proto.identity.auth.UserIdentitiesResponse.displayName = 'proto.identity.auth.UserIdentitiesResponse';
}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.identity.auth.AddWalletRequest = function(opt_data) {
+ jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.identity.auth.AddWalletRequest, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+ /**
+ * @public
+ * @override
+ */
+ proto.identity.auth.AddWalletRequest.displayName = 'proto.identity.auth.AddWalletRequest';
+}
@@ -5682,4 +5704,164 @@
};
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ * net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ * JSPB instance for transitional soy proto support:
+ * http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.identity.auth.AddWalletRequest.prototype.toObject = function(opt_includeInstance) {
+ return proto.identity.auth.AddWalletRequest.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ * the JSPB instance for transitional soy proto support:
+ * http://goto/soy-param-migration
+ * @param {!proto.identity.auth.AddWalletRequest} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.identity.auth.AddWalletRequest.toObject = function(includeInstance, msg) {
+ var f, obj = {
+ siweMessage: jspb.Message.getFieldWithDefault(msg, 1, ""),
+ siweSignature: jspb.Message.getFieldWithDefault(msg, 2, "")
+ };
+
+ if (includeInstance) {
+ obj.$jspbMessageInstance = msg;
+ }
+ return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.identity.auth.AddWalletRequest}
+ */
+proto.identity.auth.AddWalletRequest.deserializeBinary = function(bytes) {
+ var reader = new jspb.BinaryReader(bytes);
+ var msg = new proto.identity.auth.AddWalletRequest;
+ return proto.identity.auth.AddWalletRequest.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.identity.auth.AddWalletRequest} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.identity.auth.AddWalletRequest}
+ */
+proto.identity.auth.AddWalletRequest.deserializeBinaryFromReader = function(msg, reader) {
+ while (reader.nextField()) {
+ if (reader.isEndGroup()) {
+ break;
+ }
+ var field = reader.getFieldNumber();
+ switch (field) {
+ case 1:
+ var value = /** @type {string} */ (reader.readString());
+ msg.setSiweMessage(value);
+ break;
+ case 2:
+ var value = /** @type {string} */ (reader.readString());
+ msg.setSiweSignature(value);
+ break;
+ default:
+ reader.skipField();
+ break;
+ }
+ }
+ return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.identity.auth.AddWalletRequest.prototype.serializeBinary = function() {
+ var writer = new jspb.BinaryWriter();
+ proto.identity.auth.AddWalletRequest.serializeBinaryToWriter(this, writer);
+ return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.identity.auth.AddWalletRequest} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.identity.auth.AddWalletRequest.serializeBinaryToWriter = function(message, writer) {
+ var f = undefined;
+ f = message.getSiweMessage();
+ if (f.length > 0) {
+ writer.writeString(
+ 1,
+ f
+ );
+ }
+ f = message.getSiweSignature();
+ if (f.length > 0) {
+ writer.writeString(
+ 2,
+ f
+ );
+ }
+};
+
+
+/**
+ * optional string siwe_message = 1;
+ * @return {string}
+ */
+proto.identity.auth.AddWalletRequest.prototype.getSiweMessage = function() {
+ return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 1, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.identity.auth.AddWalletRequest} returns this
+ */
+proto.identity.auth.AddWalletRequest.prototype.setSiweMessage = function(value) {
+ return jspb.Message.setProto3StringField(this, 1, value);
+};
+
+
+/**
+ * optional string siwe_signature = 2;
+ * @return {string}
+ */
+proto.identity.auth.AddWalletRequest.prototype.getSiweSignature = function() {
+ return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 2, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.identity.auth.AddWalletRequest} returns this
+ */
+proto.identity.auth.AddWalletRequest.prototype.setSiweSignature = function(value) {
+ return jspb.Message.setProto3StringField(this, 2, value);
+};
+
+
goog.object.extend(exports, proto.identity.auth);
diff --git a/web/protobufs/identity-auth-structs.cjs.flow b/web/protobufs/identity-auth-structs.cjs.flow
--- a/web/protobufs/identity-auth-structs.cjs.flow
+++ b/web/protobufs/identity-auth-structs.cjs.flow
@@ -616,3 +616,23 @@
export type UserIdentitiesResponseObject = {
identitiesMap: Array<[string, IdentityObject]>,
}
+
+declare export class AddWalletRequest extends Message {
+ getSiweMessage(): string;
+ setSiweMessage(value: string): AddWalletRequest;
+
+ getSiweSignature(): string;
+ setSiweSignature(value: string): AddWalletRequest;
+
+ serializeBinary(): Uint8Array;
+ toObject(includeInstance?: boolean): AddWalletRequestObject;
+ static toObject(includeInstance: boolean, msg: AddWalletRequest): AddWalletRequestObject;
+ static serializeBinaryToWriter(message: AddWalletRequest, writer: BinaryWriter): void;
+ static deserializeBinary(bytes: Uint8Array): AddWalletRequest;
+ static deserializeBinaryFromReader(message: AddWalletRequest, reader: BinaryReader): AddWalletRequest;
+}
+
+export type AddWalletRequestObject = {
+ siweMessage: string,
+ siweSignature: string,
+}

File Metadata

Mime Type
text/plain
Expires
Tue, Nov 5, 1:39 PM (17 h, 24 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
2425943
Default Alt Text
D12575.diff (16 KB)

Event Timeline