-
Notifications
You must be signed in to change notification settings - Fork 545
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
[tutasdk] sdk should be able to make service calls #7708
Conversation
buildSrc/RustGenerator.js
Outdated
@@ -13,7 +13,7 @@ import { AssociationType, Type } from "../src/common/api/common/EntityConstants. | |||
*/ | |||
export function generateRustType({ type, modelName }) { | |||
let typeName = mapTypeName(type.name, modelName) | |||
let buf = `#[derive(uniffi::Record, Clone, Serialize, Deserialize, Debug)] | |||
let buf = `#[derive(uniffi::Record, Clone, Serialize, Deserialize, Debug, PartialEq)] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we discussed making PartialEq
cfg(test)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
mockall = { version = "0.13.0", optional = true } | ||
mockall_double = { version = "0.3.1", optional = true } | ||
|
||
# only used for the native rest client |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can we gate it behind arch, feature or somehow else? Would be nice to not compile these deps 4 times on Android build
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
not sure what you mean, are the tests run 4 times?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
isn't it in the list of normal dependencies? ahhh, it's top-level one, they are only referenced through the net feature?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Tried to play with mockall.
But now, they are referenced only through test. So they can stay in dev-dependencies now.
@@ -32,22 +33,24 @@ const BUCKET_KEY_FIELD: &str = "bucketKey"; | |||
|
|||
#[derive(uniffi::Object)] | |||
pub struct CryptoFacade { | |||
key_loader_facade: Arc<KeyLoaderFacade>, | |||
key_loader_facade: Option<Arc<KeyLoaderFacade>>, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am strongly opposed to making this a variable state. We tried really hard to make sure that certain parts can only be instantiated when we are logged in. I would like us to discuss the design for this again.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I also don't really like it. I think we can construct a proof that makes it impossible to call the methods requiring the KeyloaderFacade unless you successfully logged in 🤔
The current design makes it hard to do unauthenticated requests because the components that require a login are all over the rest stack
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is one thing to do unauthenticated requests (that is kinda hidden in headers provider) but another to request encrypted things. We have multiple EntityClient
s partially for this reason.
I really think you need two top-level ServiceExecutor
s, maybe they both delegate to the same thing under the hood though.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we had a long think about this and we came up with a few ideas to prevent mistakes (with forgotten session keys) at compile time, but nothing that we would implement now since it would require some more work.
We did a version that wraps a service executor that can resolve keys around a "normal" service executor though to not damage any invariants that were there before.
value_name: &str, | ||
model_value: &ModelValue, | ||
instance_value: &ElementValue, | ||
session_key: &Option<GenericAesKey>, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
my immediate reaction is that I am confused why encrypt_value
would be called without a key. If the entity does not have a session key at all we shouldn't try to encrypt it, if I understand it right.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
agreed. Will try to make it non-optional
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
changed the function name instead
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
but what is the motivation? In the other direction we just don't call decrypt
unless we need to
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ended up checking the encrypted flag in the service executor
|
||
pub struct ServiceExecutor { | ||
auth_headers_provider: Arc<HeadersProvider>, | ||
crypto_facade: Arc<CryptoFacade>, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this CryptoFacade
here is the reason why we don't have strong guarantees about logged in state.
I think we should have similar separation as with EntityClient
and have one without encryption support and one with encryption support.
"type {:?} does not exist", | ||
input_type_ref | ||
)))?; | ||
let encrypted_parsed_entity = self.entity_facade.encrypt_and_map_to_literal( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we should not call encrypt for entities that are not encrypted, like I mentioned before
})?; | ||
Ok(typed_entity) | ||
}, | ||
// `resolve_session_key()` only returns none if the entity is unencrypted, so |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should we match or just unwrap then?
use hyper_util::rt::TokioExecutor; | ||
use std::collections::HashMap; | ||
|
||
pub struct NativeRestClient { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I still think reqwest
impl is much shorter but if it works, it works
@@ -41,15 +62,238 @@ pub trait EntityFacade: Send + Sync { | |||
entity: ParsedEntity, | |||
resolved_session_key: ResolvedSessionKey, | |||
) -> Result<ParsedEntity, ApiCallError>; | |||
|
|||
fn encrypt_and_map_to_literal( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't know if the "literal" in the name makes sense anymore, that was kind of js-speak for "object" I guess
match (&association.cardinality, instance_association) { | ||
(Cardinality::ZeroOrOne, ElementValue::Null) => Ok(ElementValue::Null), | ||
(_, ElementValue::Null) => { | ||
panic!("Undefined attribute {}:{association_name}", type_model.name) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
when we can't find association it is Err
but here we panic()
. We should be consistent.
d5a1cff
to
6221be6
Compare
864fba4
to
d333f8c
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Had the opportunity to try out the new ServiceExecutor, and I have a request.
445135d
to
27d746a
Compare
2d8af74
to
742ee8d
Compare
742ee8d
to
ef4cea6
Compare
a80afda
to
9728869
Compare
* CompressedString is still not supported! * RustGenerator produces service files which are expanded into service trait implementations by a declarative macro * EntityFacade gained the ability to encrypt entities * limited CreateSession ( without offline login and 2FA ) for testing purposes Co-authored-by: sug <[email protected]> Co-authored-by: jhm <[email protected]> Co-authored-by: paw-hub <[email protected]> Co-authored-by: ivk <[email protected]> Co-authored-by: nig <[email protected]> Co-authored-by: map <[email protected]>
9728869
to
c481f16
Compare
hyper
to use in non-mobile ( desktop ) devicesTest Notes