-
Notifications
You must be signed in to change notification settings - Fork 12
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
server: Add service method Lock and Unlock implementation #150
base: main
Are you sure you want to change the base?
Conversation
Service method Lock should emit |
server/src/service.rs
Outdated
) -> Result<(Vec<OwnedObjectPath>, ObjectPath), ServiceError> { | ||
todo!() | ||
let mut locked: Vec<OwnedObjectPath> = Vec::new(); | ||
let prompt = ObjectPath::default(); |
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.
Use Prompt::default() so we can remove the Default impl later and track all the mis-usages left.
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.
Yeah I agree. But, a prompt isn't required here, like at all. So, returning an empty objectpath: '/' is enough. And we don't have to worry about cleaning up later :)
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.
Where did you got this information from ?
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.
Based on three things:
- There is nothing on the spec about keeping track of the objects that are locked with a prompt and a way to return them. This can be consider as a hint there is nothing related to actually prompting a system promt here.
- gnome-keyring also returns an empty object path as the prompt: https://gitlab.gnome.org/GNOME/gnome-keyring/-/blob/master/daemon/dbus/gkd-secret-service.c#L609
- I have tested this call many time. And never found any use case involving a prompt.
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.
gnome-keyring-daemon is the least respectful for the secrets spec, i wouldn't follow it "blindly"
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.
There is nothing on the spec about keeping track of the objects that are locked with a prompt and a way to return them. This can be consider as a hint there is nothing related to actually prompting a system prompt here.
There is, the prompt has a details return variable that is a zvariant::Value, it can contain anything, even a list of object paths ;)
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.
yes, there is no way to pass a list of items to unlock into prompt & then get the result of what got locked and what wasn't. But there should definitely be a prompt used here otherwise the spec is wrong which I don't think it is...
That is normal, because you have to make use of the auto-generated method called |
Understood, thanks! |
f3de5f6
to
acc5c86
Compare
b414c91
to
ef6929c
Compare
ef6929c
to
cd2a4cb
Compare
0f2313a
to
13e500c
Compare
374bd6d
to
0d7b53b
Compare
a7d8efc
to
4dc75dd
Compare
4dc75dd
to
748d0c4
Compare
748d0c4
to
73676bd
Compare
Can you add the unlock implementation as well? Without the prompt bits obviously. Given that it will just be calling the same functions added here |
Yeah, of course. Will do. |
73676bd
to
ab88be5
Compare
server/src/service.rs
Outdated
) -> Result<(Vec<OwnedObjectPath>, ObjectPath), ServiceError> { | ||
todo!() | ||
let mut locked = Vec::new(); |
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 the exact same implementation, with only difference being the state of locked, put the common code in a function.
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.
Yeah I have thought about this. But, will this function get messy when adding the Prompt related things during Unlock?
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 I still follow this and move this to a new function?
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.
yes
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.
basically share what is common between both :)
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.
will do, thanks!
server/src/service.rs
Outdated
for object in &objects { | ||
for collection in collections.iter() { | ||
if object == collection.path() { | ||
collection.set_locked(true).await?; |
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.
Why is this not doing the same check as unlock? See above for fixing that
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.
For unlock we need a way to identify when to issue a Prompt. But, for Lock we don't need a prompt at all. This I'm sure :)
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.
For unlock we need a way to identify when to issue a Prompt. But, for Lock we #150 (comment) need a prompt at all. This I'm sure :)
The spec disagree with you.
The current implementations don't use a prompt here, we might not need it if we agree with both the KDE/GNOME implementors, then it can easily be disabled. But for now, let us assume it is required to be fully compatible with the published specification.
But anyways, the lock/unlock DBus functions would call the "inner" one, so the Unlock
could grow some functionality around it and the Lock
one won't.
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.
Understood, thanks!
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.
hey, sorry for the delay.
I just realized that my implementation is wrong :) I think we shouldn't do the actual Lock/Unlock (calling collection.set_locked()
and item.set_locked()
) here. The Lock implementation used to be correct. But, since now both calls should have a prompt, the actual Lock/Unlock should happen inside Prompt. Specifically inside prompt_ready()
call. Not inside the service methods. The purpose of service methods (Lock & Unlock) are to filter the objects locked/unlocked without prompt and send them out or send out a prompt without the objects.
question: how do we filter out which objects that we lock/unlock without a prompt?
Unlock:
- if the objects are already unlocked, then thses object are unlocked without a prompt. So, we return the unlocked objecpaths here and no prompt.
- if the objects are locked we return a prompt here and no unlocked objecpaths.
Lock:
- Shoud we do the same for lock?
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.
Thanks for the reply.
Yeah it's incomplete. But,
The purpose of service methods (Lock & Unlock) are to filter the objects locked/unlocked without prompt and send them out or send out a prompt without the objects.
And currently we're setting the locked status inside service methods. We shouldn't do this here. All we need to do this return objectspaths (locked/unlocked objects list or a prompt).
Since I can't get a feel of Lock with a prompt, I'm not sure when to issue a prompt and when to return locked objectpaths.
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.
Who is supposed to modify the collection/item state then? It is supposed to be done once the prompt is finished successfully but still part of the code in Lock/Unlock.
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.
Who is supposed to modify the collection/item state then?
org.gnome.keyring.internal.Prompter.Callback PromptReady
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.
That will execute a task, the task will be created inside Lock and Unlock.
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.
Updated the implementation.
Signed-off-by: Dhanuka Warusadura <dhanuka@gnome.org>
ab88be5
to
baa3d25
Compare
@@ -205,6 +205,34 @@ impl Collection { | |||
None | |||
} | |||
|
|||
#[allow(unused)] |
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.
what is this for?
@@ -28,6 +29,7 @@ pub struct Service { | |||
collections: Arc<Mutex<Vec<Collection>>>, | |||
// Other attributes | |||
manager: Arc<Mutex<ServiceManager>>, | |||
prompt_index: Arc<RwLock<u32>>, |
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.
Would put this in the ServiceManager instead and would pass that to newly created prompts as well
pub async fn set_locked( | ||
&self, | ||
locked: bool, | ||
objects: &Vec<OwnedObjectPath>, |
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.
objects: &Vec<OwnedObjectPath>, | |
objects: &[OwnedObjectPath], |
for object in objects { | ||
for collection in collections.iter() { | ||
if object == collection.path() { | ||
if !collection.is_locked().await { |
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.
shouldn't this compare it to the value of locked passed to it?
} | ||
break; | ||
} else if let Some(item) = collection.item_from_path(object).await { | ||
if !item.is_locked().await { |
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.
Same here
} | ||
break; | ||
} | ||
tracing::info!("Object: {} does not exist.", object); |
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.
Maybe warn here instead
#[zbus(object_server)] object_server: &zbus::ObjectServer, | ||
) -> Result<(Vec<OwnedObjectPath>, OwnedObjectPath), ServiceError> { | ||
let unlocked = self.set_locked(false, &objects).await?; | ||
if unlocked.is_empty() { |
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.
The condition here seems wrong, you would use a prompt only if there are items which don't have the expected state.
let n_prompt = *self.prompt_index.read().await + 1; | ||
let prompt = Prompt::new(n_prompt); | ||
*self.prompt_index.write().await = n_prompt; |
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.
If you pass the service manager when creating the prompt, you could deal with incrementing the prompt index there
This change adds Secret Service method Lock and Unlock implementation.