Ubuntu – Using Online Accounts to authenticate against the server

application-developmentoauthonline-accountsqmlubuntu-one

In my Ubuntu QML app I'm trying to use online accounts in order to authenticate against my server. I'm a little confused as to how I should go about doing this. Ultimately I want the user to be able to login with their facebook/google/ubuntu one accounts. After reading a bit about OpenID and OAuth I think I should be using one of them for this.
So far in my app I'm using the user's Ubuntu One account to authenticate like this:

import QtQuick 2.0
import Ubuntu.Components 1.1
import Ubuntu.Components.ListItems 1.0 as ListItem
import Ubuntu.OnlineAccounts 0.1
import Ubuntu.OnlineAccounts.Client 0.1
import "../common"

Page {
    id: root
    title: "Authenticate"

    AccountService {
        id: accountService
        onAuthenticated: {
            console.log("Reply: " + JSON.stringify(reply))
        }
    }

    AccountServiceModel {
        id: accountsModel
        provider: "ubuntuone"
    }

    function useFirstAccountToAutheticate() {
        accountService.objectHandle = accountsModel.get(0, "accountServiceHandle")
        accountService.authenticate({})
    }

    Button {
        anchors {
            left: parent.left
            right: parent.right
            bottom: parent.bottom
        }
        text: i18n.tr("Authenticate using Ubuntu One")

        onTriggered: {
            if (accountsModel.count > 0) {
                useFirstAccountToAutheticate()
            }
            else {
                setup.exec()
            }
        }
    }

    Setup {
        id: setup
        providerId: "ubuntuone"

        onFinished: {
            useFirstAccountToAutheticate()
        }
    }
}

Upon successful authentication I get:

Reply: {"Secret":"consumer_key=XXXX&consumer_secret=XXXX&created=DATE&name=NAME&token=XXXX&token_secret=XXXX&updated=DATE"}

(XXXX,DATE, and NAME aren't real values)
What I thought of doing is to send the token to the server and talk with the Ubuntu One API (if such a thing exists, I haven't been able to find it) to authenticate the user.
It'd be great if someone could tell me if I'm on the right track or if I should be doing something differently because I'm kind of stuck.

Also, I'm using the Setup component in my QML to create an ubuntu one account in case the user doesn't already have one. This seems to work for me on my Utopic desktop but doesn't work on my Ubuntu phone. I guess I need to set the applicationId, but for that I need to create an .application xml file and install it in a directory which I don't think I have access to as my app is confined.

Any help is appreciated

Best Answer

I can only answer to the second part of the question (about the .application file), because I'm not familiar with the services offered by the U1 account.

You are correct in that you need an .application file, and you actually also need a .service file as well. Fortunately, it's possible to ship them also with confined applications shipped in a click package. Your manifest.json file should contain something along these lines:

{
  ...
  "name": "com.example.package",
  "hooks": {
    "my-app": {
        "account-application": "my-app.application",
        "account-service": "my-app.service",
        "apparmor": "my-app.json",
        "desktop": "my-app.desktop"
    }
  },
  ...
}

When the click package gets installed, the .application and .service files get processed and installed under ~/.local/share/accounts/, and their names (and therefore IDs) are changed to <package-name>_<application-name>.{service,application}, which in the example above would result in com.example.package_my-app.{service,application}.

Just for completeness, I'm showing an example of what these files could look like:

my-app.application

<?xml version="1.0" encoding="UTF-8" ?>
<application>
  <service-types>
    <service-type id="com.example.package_my-app">
      <description>Login into XXX using your U1 account</description>
    </service-type>
  </services-types>
</application>

and

my-app.service

<?xml version="1.0" encoding="UTF-8"?>
<service>
  <type>com.example.package_my-app</type>
  <name>U1 for XXX</name>
  <provider>ubuntuone</provider>
</service>
Related Question