Skip to content
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

Provide way for Flatpak to retrieve credentials #209

Open
marbetschar opened this issue Aug 23, 2021 · 10 comments
Open

Provide way for Flatpak to retrieve credentials #209

marbetschar opened this issue Aug 23, 2021 · 10 comments

Comments

@marbetschar
Copy link
Member

Problem

Flatpacked apps using EDS are not able to retrieve credentials from the host system. Thats why we did not Flatpack Mail till now (elementary/mail#591) and also ran into problems with Tasks for certain operations (elementary/tasks#263).

Proposal

Ideally we should re-use an existing way to retrieve the credentials from the host system.

Prior Art

@Marukesu found a way to escape the sandbox and retrieve the credentials from the host system: elementary/tasks#263 (comment)

@marbetschar
Copy link
Member Author

marbetschar commented Aug 23, 2021

@Marukesu I created a topic over at the GNOME forum just to double check if we miss something here: https://discourse.gnome.org/t/flatpack-retrieve-credentials-from-host-eds/7359

Meanwhile: Any chance you can add such a DBus service to this Online Accounts plug as custom branch? We'll most likely need to put it elsewhere before shipping - but this way we can do a quick proof of concept and try to access it from the Tasks app.

If this works, we should ultimately be able to package Mail as Flatpack as well 🥳

@Marukesu
Copy link

I created the dbus-daemon branch implementing the password lookup part on the host.

@marbetschar
Copy link
Member Author

@Marukesu I created the online-accounts-dbus companion branch in Tasks - but I keep getting a GDBus.Error:org.freedekstop.DBus.Error.ServiceUnknown error. Any idea why?

I compiled and ran your dbus-daemon manually in Terminal with /usr/libexec/online-accounts-daemon and it claims 'io.elementary.switchboard.online-accounts' aquired.

@marbetschar
Copy link
Member Author

marbetschar commented Aug 25, 2021

I also came across the --talk-name=org.gnome.OnlineAccounts DBus interface which seems to already exist and serve a similar purpose - and there is the goa-1.0 package on valadoc.org

Wondering if we really need to roll our own DBus service for this - or if we can simply configure the accounts through the goa lib, grant access to the goa DBus for our Flatpacked, EDS using apps (Calendar, Tasks & Mail) and they pick up the accounts and credentials configured in goa automagically... @tintou?

@Marukesu
Copy link

I created the online-accounts-dbus companion branch in Tasks - but I keep getting a GDBus.Error:org.freedekstop.DBus.Error.ServiceUnknown error. Any idea why?

You need to add --talk-name=io.elementary.switchboard.online-accounts to the manifest.

I compiled and ran your dbus-daemon manually in Terminal with /usr/libexec/online-accounts-daemon and it claims 'io.elementary.switchboard.online-accounts' aquired.

That happens when the daemon successfully register itself to the session bus.

@marbetschar
Copy link
Member Author

marbetschar commented Aug 25, 2021

Ok; retrieving the credentials works now and I'm again able to modify the task lists color for example. So this is definitely an improvement.

However, do we really roll our own DBus service to handle this? If so, we will probably need to handle OAuth2 tokens with it as well further down the road (e.g. for Google) - and I feel like this stuff was probably already solved somehow/somewhere. Maybe goa-1.0 is really worth a try as commented above..?

UPDATE: We don't want GNOME Online Accounts. We will need our own credential portal indeed but that requires a lot of thought.

@marbetschar
Copy link
Member Author

marbetschar commented Aug 27, 2021

What we really want for this is a Flatpak Portal. Here's the corresponding discussion from Slack:

You need an authorization flow that would be like this:

  • Have an "Add account…" on the app (that sends some settings to the portal like supported auth type (ex: password), account types (ex: imap+smtp or pop3+smtp for password)
  • Then the portal process the querry,
    • if you already have an account configured that is not yet allowed, show a dialog with a list of available accounts and a "Add new account…", clicking on an account would return it to the app, clicking on the "Add new account…" would go next case
    • if you don't have an account configured (or you clicked "Add new account…"), then the online account plug is opened at the "Add account" page

So basically, that's not just a credential portal, we don't want to mimic libsecret on D-Bus which isn't exposed for reasons - because we need a way to tell if the credentials requesting app is authorized. Otherwise a malicious app could request any credentials and/or spoof another app's id to do so. So a simple DBus handing over whatever credentials are requested is a serious security hole. That's why it's a portal, you always know the origin of the request that way.

We should be able to start out with a minimal proof of concept: A portal supporting the full flow for CalDAV accounts only (since this is essentially only three properties uri, username and password) - and then build from there for IMAP/SMTP, OAuth, ... Also remember that for OAuth, each app will need to provide a different Client Secret, only elementary official apps can use the elementary one.

@Marukesu
Copy link

Marukesu commented Oct 1, 2021

So, my proposal for the portal API:

LookupAccount (in  s     window_handle,
               in  s     account_type,
               in  a{sv} options,
               out o     request)

GetCredential (in  s     account_uid,
               in  s     auth_type,
               out a{sv} credential)

The LookupAccount method would show the Dialog for the user showing account_type accounts and a link to the plug, in the options dict we would have a auth_types (as) key with the supported authentication types. In the request response signal will would return the selected account UID and any other non-sensible information needed.

GetCredential would return the credentials of the account, for the specified auth_type, if the app has permission to it.

in the PermissionStore, we can store the permission like this:

table resource_id premission data
online-account-access account UID account_type display name

Some observations:

  • EDS Configuration should be done in the sandbox

The portal is a host process, and we can't use the host EDS to remove/add accounts on the sandboxed EDS, so, we should provide a EDS Module and do the configuration there. The plug should have they own backend, that would serve as the portal backend too.

It's means that apps don't depend on host having EDS, and alls the --talk-name=org.gnome.evolution.dataserver.* can (should) be removed, also they can use functions of new versions (so elementary/tasks#169, elementary/tasks#192 and elementary/tasks#205 can be fixed/merged), and it's also means that developers do not need to use EDS to integrate with the online accounts plug, what i think is a good thing.

  • the portal is elementary/pantheon specific

So apps using it would end unusable in others distros, we can provide a API either in a new library or in granite that would handle the account creation internally in the sandbox when the portal isn't available, or at least warning the developers to provide a fallback by themselves.

@marbetschar
Copy link
Member Author

Started to work on the portal in elementary/portals#20

@Marukesu
Copy link

@marbetschar @tintou throughts about the proposal? specially the part about removing EDS from the plugin.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Development

No branches or pull requests

2 participants