diff -pruN 3.44.0-1/debian/changelog 3.44.0-1ubuntu1/debian/changelog
--- 3.44.0-1/debian/changelog	2022-03-30 15:32:11.000000000 +0000
+++ 3.44.0-1ubuntu1/debian/changelog	2022-03-30 15:35:58.000000000 +0000
@@ -1,9 +1,59 @@
+gnome-online-accounts (3.44.0-1ubuntu1) jammy; urgency=medium
+
+  * Merge with Debian (LP: #1967155). Remaining changes:
+    + debian/rules:
+      - Make sure that gnome-online-accounts.pot is refreshed so the
+        strings from 0001-ubuntu-sso-provider.patch are included
+        (LP: #1759251).
+      - Build with --enable-ubuntu-sso
+      - disable the facebook provider since it's currently not working
+      - disable the last.fm provider since it's only used by GNOME Music
+        which isn't installed by default
+    + debian/control.*:
+      - Add b-d on libsnapd-glib-dev
+      - depends on python3 and python3-macaroonbakery for the ubuntu sso
+        provider.
+    + debian/gnome-online-accounts.install:
+      install usr/share/goa-1.0/scripts/lpa_helper.py
+    + debian/libgoa-backend-1.0-1.symbols:
+      Add goa_ubuntu_sso_provider_get_type
+    + Ubuntu-specific patches:
+      - debian/patches/0001-ubuntu-sso-provider.patch
+      - debian/patches/0002-livepatch-auth.patch
+
+ -- Jeremy Bicha <jbicha@ubuntu.com>  Wed, 30 Mar 2022 11:35:58 -0400
+
 gnome-online-accounts (3.44.0-1) unstable; urgency=medium
 
   * New upstream release
 
  -- Jeremy Bicha <jbicha@ubuntu.com>  Wed, 30 Mar 2022 11:32:11 -0400
 
+gnome-online-accounts (3.43.1-1ubuntu1) jammy; urgency=medium
+
+  * Merge with debian, remaining changes:
+    + debian/rules:
+      - Make sure that gnome-online-accounts.pot is refreshed so the
+        strings from 0001-ubuntu-sso-provider.patch are included (LP: #1759251).
+      - Build with --enable-ubuntu-sso
+      - disable the facebook provider since it's current not working
+    + debian/control.*:
+      - Add b-d on libsnapd-glib-dev
+      - depends on python3 and python3-macaroonbakery for the ubuntu sso
+        provider.
+    + debian/gnome-online-accounts.install:
+      install usr/share/goa-1.0/scripts/lpa_helper.py
+    + debian/libgoa-backend-1.0-1.symbols:
+      Add goa_ubuntu_sso_provider_get_type
+    + Ubuntu-specific patches:
+      - debian/patches/0001-ubuntu-sso-provider.patch
+      - debian/patches/0002-livepatch-auth.patch
+  * debian/rules: Disable last.fm provider
+    - Only used by GNOME Music which isn't installed by default
+    - This provider had been disabled until now
+
+ -- Jeremy Bicha <jbicha@ubuntu.com>  Mon, 28 Mar 2022 10:33:16 -0400
+
 gnome-online-accounts (3.43.1-1) unstable; urgency=medium
 
   * New upstream release
@@ -14,6 +64,34 @@ gnome-online-accounts (3.43.1-1) unstabl
 
  -- Jeremy Bicha <jbicha@ubuntu.com>  Mon, 28 Mar 2022 09:50:44 -0400
 
+gnome-online-accounts (3.40.1-2ubuntu2) jammy; urgency=medium
+
+  * No-change rebuild for ppc64el baseline bump.
+
+ -- Łukasz 'sil2100' Zemczak <lukasz.zemczak@ubuntu.com>  Wed, 23 Mar 2022 14:54:58 +0100
+
+gnome-online-accounts (3.40.1-2ubuntu1) jammy; urgency=medium
+
+  * Merge with debian, remaining changes:
+    + debian/rules:
+      - Make sure that gnome-online-accounts.pot is refreshed so the
+        strings from 0001-ubuntu-sso-provider.patch are included (LP: #1759251).
+      - Build with --enable-ubuntu-sso
+      - disable the facebook provider since it's current not working
+    + debian/control.*:
+      - Add b-d on libsnapd-glib-dev
+      - depends on python3 and python3-macaroonbakery for the ubuntu sso
+        provider.
+    + debian/gnome-online-accounts.install:
+      install usr/share/goa-1.0/scripts/lpa_helper.py
+    + debian/libgoa-backend-1.0-1.symbols:
+      Add goa_ubuntu_sso_provider_get_type
+    + Ubuntu-specific patches:
+      - debian/patches/0001-ubuntu-sso-provider.patch
+      - debian/patches/0002-livepatch-auth.patch
+
+ -- Sebastien Bacher <seb128@ubuntu.com>  Thu, 11 Nov 2021 16:37:25 +0100
+
 gnome-online-accounts (3.40.1-2) unstable; urgency=medium
 
   * Reenable the backend on sh4, webkit now builds on that architecture
@@ -37,6 +115,28 @@ gnome-online-accounts (3.40.0-2) unstabl
 
  -- Jeremy Bicha <jbicha@debian.org>  Sun, 22 Aug 2021 08:17:12 -0400
 
+gnome-online-accounts (3.40.0-1ubuntu1) impish; urgency=medium
+
+  * Merge with debian, remaining changes:
+    + debian/rules:
+      - Make sure that gnome-online-accounts.pot is refreshed so the
+        strings from 0001-ubuntu-sso-provider.patch are included (LP: #1759251).
+      - Build with --enable-ubuntu-sso
+      - disable the facebook provider since it's current not working
+    + debian/control.*:
+      - Add b-d on libsnapd-glib-dev
+      - depends on python3 and python3-macaroonbakery for the ubuntu sso
+        provider.
+    + debian/gnome-online-accounts.install:
+      install usr/share/goa-1.0/scripts/lpa_helper.py
+    + debian/libgoa-backend-1.0-1.symbols:
+      Add goa_ubuntu_sso_provider_get_type
+    + Ubuntu-specific patches:
+      - debian/patches/0001-ubuntu-sso-provider.patch
+      - debian/patches/0002-livepatch-auth.patch
+
+ -- Sebastien Bacher <seb128@ubuntu.com>  Fri, 28 May 2021 12:37:31 +0200
+
 gnome-online-accounts (3.40.0-1) experimental; urgency=medium
 
   * New upstream release
@@ -47,7 +147,7 @@ gnome-online-accounts (3.38.2-1) experim
 
   * New upstream release
 
- -- Sebastien Bacher <seb128@ubuntu.com>  Mon, 17 May 2021 16:32:13 +0200
+ -- Sebastien Bacher <seb128@ubuntu.com>  Mon, 17 May 2021 16:35:03 +0200
 
 gnome-online-accounts (3.38.1-2) unstable; urgency=medium
 
@@ -59,6 +159,14 @@ gnome-online-accounts (3.38.1-2) unstabl
 
  -- Laurent Bigonville <bigon@debian.org>  Mon, 10 May 2021 16:44:24 +0200
 
+gnome-online-accounts (3.38.1-1ubuntu2) impish; urgency=medium
+
+  * debian/rules:
+    - disable the facebook provider since it's current not working
+      (lp: #1926843)
+
+ -- Sebastien Bacher <seb128@ubuntu.com>  Fri, 07 May 2021 17:16:05 +0200
+
 gnome-online-accounts (3.38.1-1) unstable; urgency=medium
 
   * New upstream release
@@ -96,6 +204,27 @@ gnome-online-accounts (3.37.90-2) unstab
 
  -- Simon McVittie <smcv@debian.org>  Sun, 27 Sep 2020 19:11:21 +0100
 
+gnome-online-accounts (3.37.90-1ubuntu1) groovy; urgency=medium
+
+  * Merge with debian, remaining changes:
+    + debian/rules:
+      - Make sure that gnome-online-accounts.pot is refreshed so the
+        strings from 0001-ubuntu-sso-provider.patch are included (LP: #1759251).
+      - Build with --enable-ubuntu-sso
+    + debian/control.*:
+      - Add b-d on libsnapd-glib-dev
+      - depends on python3 and python3-macaroonbakery for the ubuntu sso
+        provider.
+    + debian/gnome-online-accounts.install:
+      install usr/share/goa-1.0/scripts/lpa_helper.py
+    + debian/libgoa-backend-1.0-1.symbols:
+      Add goa_ubuntu_sso_provider_get_type
+    + Ubuntu-specific patches:
+      - debian/patches/0001-ubuntu-sso-provider.patch
+      - debian/patches/0002-livepatch-auth.patch
+
+ -- Sebastien Bacher <seb128@ubuntu.com>  Thu, 13 Aug 2020 17:26:45 +0200
+
 gnome-online-accounts (3.37.90-1) experimental; urgency=medium
 
   * New upstream release
@@ -165,12 +294,49 @@ gnome-online-accounts (3.33.91-1) experi
 
  -- Marco Trevisan (Treviño) <marco@ubuntu.com>  Thu, 22 Aug 2019 00:55:51 +0200
 
+gnome-online-accounts (3.32.0-1ubuntu1) disco; urgency=medium
+
+  * Update to the stable version, based on the Debian update
+
+ -- Sebastien Bacher <seb128@ubuntu.com>  Wed, 03 Apr 2019 17:09:24 +0200
+
 gnome-online-accounts (3.32.0-1) experimental; urgency=medium
 
   * New upstream release
 
  -- Sebastien Bacher <seb128@ubuntu.com>  Wed, 03 Apr 2019 17:03:56 +0200
 
+gnome-online-accounts (3.31.90-1ubuntu1) disco; urgency=medium
+
+  * Resynchronize on Debian (LP: #1815317), remaining changes:
+    + debian/rules:
+      - Make sure that gnome-online-accounts.pot is refreshed so the
+        strings from 0001-ubuntu-sso-provider.patch are included (LP: #1759251).
+      - Build with --enable-ubuntu-sso
+    + debian/control.*:
+      - Add b-d on libsnapd-glib-dev
+      - depends on python3 and python3-macaroonbakery for the ubuntu sso
+        provider.
+    + debian/gnome-online-accounts.install:
+      install usr/share/goa-1.0/scripts/lpa_helper.py
+    + debian/libgoa-backend-1.0-1.symbols:
+      Add goa_ubuntu_sso_provider_get_type
+    + Ubuntu-specific patches:
+      - debian/patches/0001-ubuntu-sso-provider.patch
+      - debian/patches/0002-livepatch-auth.patch
+  * debian/patches/0001-ubuntu-sso-provider.patch:
+    - Move from binary icons to svg ones.
+  * debian/patches/0001-Add-Ubuntu-Single-Sign-on-icons.patch:
+    - Drop the patch because no longer required. The icons are now included in
+      the above d/p/0001-ubuntu-sso-provider.patch as svg (non binary) images.
+  * debian/patches/0002-livepatch-auth.patch:
+    - Refreshed using gbp pq rebase.
+  * debian/source/include-binaries:
+    - Drop as no longer required. Binary images have been removed from distro
+      patches.
+
+ -- Andrea Azzarone <andrea.azzarone@canonical.com>  Wed, 13 Feb 2019 16:25:24 +0000
+
 gnome-online-accounts (3.31.90-1) experimental; urgency=medium
 
   * New upstream development release
@@ -191,6 +357,37 @@ gnome-online-accounts (3.30.1-2) unstabl
 
  -- Jeremy Bicha <jbicha@debian.org>  Sat, 09 Feb 2019 16:55:02 -0500
 
+gnome-online-accounts (3.30.1-1ubuntu1) disco; urgency=medium
+
+  * Resynchronize on Debian, remaining changes:
+    + debian/rules:
+      - Make sure that gnome-online-accounts.pot is refreshed so the
+        strings from 0001-ubuntu-sso-provider.patch are included (LP: #1759251).
+      - Build with --enable-ubuntu-sso
+    + debian/control.*:
+      - Add b-d on libsnapd-glib-dev
+      - depends on python3 and python3-macaroonbakery for the ubuntu sso
+        provider.
+    + debian/gbp.conf:
+      - Set the upstream branch to upstream/latest.
+    + debian/gnome-online-accounts.install:
+      install usr/share/goa-1.0/scripts/lpa_helper.py
+    + debian/libgoa-backend-1.0-1.symbols:
+      Add goa_ubuntu_sso_provider_get_type
+    + debian/source/include-binaries:
+      Add debian/patches/0001-Add-Ubuntu-Single-Sign-on-icons.patch to properly
+      deal with new binary images.
+    + Ubuntu-specific patches:
+      - debian/patches/0001-Add-Ubuntu-Single-Sign-on-icons.patch
+      - debian/patches/0001-ubuntu-sso-provider.patch
+      - debian/patches/0002-livepatch-auth.patch
+  * debian/patches/0001-ubuntu-sso-provider.patch:
+  * debian/patches/0001-Add-Ubuntu-Single-Sign-on-icons.patch:
+    - Split the patch in order to separate the binary files from the non-binary
+      ones.
+
+ -- Sebastien Bacher <seb128@ubuntu.com>  Thu, 24 Jan 2019 11:20:10 +0100
+
 gnome-online-accounts (3.30.1-1) unstable; urgency=medium
 
   * New upstream release
@@ -212,6 +409,42 @@ gnome-online-accounts (3.30.0-1) unstabl
 
  -- Jeremy Bicha <jbicha@debian.org>  Sun, 02 Sep 2018 09:40:41 -0400
 
+gnome-online-accounts (3.29.91-1ubuntu2) cosmic; urgency=medium
+
+  * debian/control*:
+    - Bump libsnapd-glib-dev to (>= 1.43).
+  * debian/patches/0001-ubuntu-sso-provider.patch:
+    - Use SNAPD_ERROR_AUTH_CANCELLED instead of SNAPD_ERROR_PERMISSION_DENIED
+      to understand if Polkit dialog was dimissed by the user.
+
+ -- Andrea Azzarone <andrea.azzarone@canonical.com>  Fri, 24 Aug 2018 11:49:17 +0200
+
+gnome-online-accounts (3.29.91-1ubuntu1) cosmic; urgency=medium
+
+  * Merge from Debian experimental (LP: #1788130). Remaining changes:
+    + debian/rules:
+      - Make sure that gnome-online-accounts.pot is refreshed so the
+        strings from 0001-ubuntu-sso-provider.patch are included (LP: #1759251).
+      - Build with --enable-ubuntu-sso
+    + debian/control.*:
+      - Add b-d on libsnapd-glib-dev
+      - depends on python3 and python3-macaroonbakery for the ubuntu sso
+        provider.
+    + debian/gbp.conf:
+      - Set the upstream branch to upstream/latest.
+    + debian/gnome-online-accounts.install:
+      install usr/share/goa-1.0/scripts/lpa_helper.py
+    + debian/libgoa-backend-1.0-1.symbols:
+      Add goa_ubuntu_sso_provider_get_type
+    + debian/source/include-binaries:
+      Add debian/patches/0001-ubuntu-sso-provider.patch to properly deal with
+      new binary images.
+    + Ubuntu-specific patches:
+      - debian/patches/0001-ubuntu-sso-provider.patch
+      - debian/patches/0002-livepatch-auth
+
+ -- Andrea Azzarone <andrea.azzarone@canonical.com>  Wed, 22 Aug 2018 15:03:00 +0200
+
 gnome-online-accounts (3.29.91-1) experimental; urgency=medium
 
   * Team upload
@@ -226,11 +459,63 @@ gnome-online-accounts (3.29.91-1) experi
 
  -- Simon McVittie <smcv@debian.org>  Mon, 20 Aug 2018 16:56:41 +0100
 
-gnome-online-accounts (3.28.0-1) unstable; urgency=medium
+gnome-online-accounts (3.28.0-0ubuntu3) cosmic; urgency=medium
+
+  * debian/patches/0001-ubuntu-sso-provider.patch: Add a link to the
+    link to the privacy policy in U1 login dialog (LP: #1773213).
+  * debian/patches/0002-livepatch-auth: Refresh patch.
+
+ -- Andrea Azzarone <andrea.azzarone@canonical.com>  Fri, 25 May 2018 09:04:11 -0500
+
+gnome-online-accounts (3.28.0-0ubuntu2) bionic; urgency=medium
+
+  * debian/patches/0002-livepatch-auth: Don't show an error message if the
+    polkit authentication dialog is dimissed by the user (LP: #1764989).
+
+ -- Andrea Azzarone <andrea.azzarone@canonical.com>  Wed, 18 Apr 2018 16:52:39 +0200
+
+gnome-online-accounts (3.28.0-0ubuntu1) bionic; urgency=medium
 
   * New upstream release
 
- -- Tim Lunn <tim@feathertop.org>  Sun, 18 Mar 2018 18:41:25 +1100
+ -- Jeremy Bicha <jbicha@ubuntu.com>  Fri, 13 Apr 2018 14:33:07 -0400
+
+gnome-online-accounts (3.27.92-1ubuntu3) bionic; urgency=medium
+
+  * debian/rules:
+    Make sure that gnome-online-accounts.pot is refreshed so the
+    strings from 0001-ubuntu-sso-provider.patch are included
+    (LP: #1759251).
+
+ -- Gunnar Hjalmarsson <gunnarhj@ubuntu.com>  Tue, 27 Mar 2018 23:17:00 +0200
+
+gnome-online-accounts (3.27.92-1ubuntu2) bionic; urgency=medium
+
+  * debian/patches/0002-livepatch-auth:
+    clear the otp text entry when a second otp is required (LP: #1757444) 
+
+ -- Andrea Azzarone <andrea.azzarone@canonical.com>  Wed, 21 Mar 2018 15:19:11 +0100
+
+gnome-online-accounts (3.27.92-1ubuntu1) bionic; urgency=medium
+
+  * debian/control.in:
+    - Add b-d on libsnapd-glib-dev
+    - depends on python3-macaroonbakery for the ubuntu sso provide
+  * debian/gnome-online-accounts.install:
+    install usr/share/goa-1.0/scripts/lpa_helper.py
+  * debian/libgoa-backend-1.0-1.symbols:
+    Add goa_ubuntu_sso_provider_get_type
+  * debian/patches/0001-ubuntu-sso-provider.patch:
+    Add an Ubuntu Single Sing-On provider (lp: #1752472)
+  * debian/patches/0002-livepatch-auth:
+    Get the Canonical Livepatch authentication token.
+  * debian/rules:
+    Build with --enable-ubuntu-sso
+  * debian/source/include-binaries:
+    Add debian/patches/0001-ubuntu-sso-provider.patch to properly deal with
+    new binary images.
+
+ -- Andrea Azzarone <andrea.azzarone@canonical.com>  Tue, 06 Mar 2018 08:46:07 +0100
 
 gnome-online-accounts (3.27.92-1) unstable; urgency=medium
 
diff -pruN 3.44.0-1/debian/control 3.44.0-1ubuntu1/debian/control
--- 3.44.0-1/debian/control	2022-03-30 15:32:11.000000000 +0000
+++ 3.44.0-1ubuntu1/debian/control	2022-03-30 15:35:58.000000000 +0000
@@ -5,8 +5,9 @@
 Source: gnome-online-accounts
 Section: gnome
 Priority: optional
-Maintainer: Debian GNOME Maintainers <pkg-gnome-maintainers@lists.alioth.debian.org>
-Uploaders: Jeremy Bicha <jbicha@ubuntu.com>, Laurent Bigonville <bigon@debian.org>, Michael Biebl <biebl@debian.org>, Tim Lunn <tim@feathertop.org>
+Maintainer: Ubuntu Developers <ubuntu-devel-discuss@lists.ubuntu.com>
+XSBC-Original-Maintainer: Debian GNOME Maintainers <pkg-gnome-maintainers@lists.alioth.debian.org>
+Uploaders: Jeremy Bicha <jbicha@ubuntu.com>, Laurent Bigonville <bigon@debian.org>, Michael Biebl <biebl@debian.org>
 Build-Depends: debhelper-compat (= 13),
                autoconf-archive,
                dh-sequence-gir,
@@ -20,6 +21,7 @@ Build-Depends: debhelper-compat (= 13),
                libkrb5-dev,
                librest-dev [!ia64 !kfreebsd-amd64 !kfreebsd-i386],
                libsecret-1-dev [!ia64 !kfreebsd-amd64 !kfreebsd-i386],
+               libsnapd-glib-dev (>= 1.43),
                libsoup2.4-dev (>= 2.42) [!ia64 !kfreebsd-amd64 !kfreebsd-i386],
                libjavascriptcoregtk-4.0-dev [!ia64 !kfreebsd-amd64 !kfreebsd-i386],
                libwebkit2gtk-4.0-dev (>= 2.26) [!ia64 !kfreebsd-amd64 !kfreebsd-i386],
@@ -27,14 +29,18 @@ Build-Depends: debhelper-compat (= 13),
 Build-Depends-Indep: libglib2.0-doc <!nodoc>, libgtk-3-doc <!nodoc>
 Rules-Requires-Root: no
 Standards-Version: 4.5.1
-Vcs-Browser: https://salsa.debian.org/gnome-team/gnome-online-accounts
-Vcs-Git: https://salsa.debian.org/gnome-team/gnome-online-accounts.git
+XS-Debian-Vcs-Git: https://salsa.debian.org/gnome-team/gnome-online-accounts.git
+XS-Debian-Vcs-Browser: https://salsa.debian.org/gnome-team/gnome-online-accounts
+Vcs-Git: https://salsa.debian.org/gnome-team/gnome-online-accounts.git -b ubuntu/master
+Vcs-Browser: https://salsa.debian.org/gnome-team/gnome-online-accounts/tree/ubuntu/master
 Homepage: https://wiki.gnome.org/Projects/GnomeOnlineAccounts
 
 Package: gnome-online-accounts
 Architecture: alpha amd64 arm64 armel armhf hppa hurd-i386 i386 m68k mips64el mipsel powerpc ppc64 ppc64el riscv64 s390x sh4 sparc64 x32
 Depends: libgoa-1.0-0b (= ${binary:Version}),
          libgoa-backend-1.0-1 (= ${binary:Version}),
+         python3,
+         python3-macaroonbakery,
          ${misc:Depends},
          ${shlibs:Depends}
 Recommends: gnome-control-center (>= 3.6.1)
diff -pruN 3.44.0-1/debian/control.in 3.44.0-1ubuntu1/debian/control.in
--- 3.44.0-1/debian/control.in	2022-03-30 15:32:11.000000000 +0000
+++ 3.44.0-1ubuntu1/debian/control.in	2022-03-30 15:35:58.000000000 +0000
@@ -1,7 +1,8 @@
 Source: gnome-online-accounts
 Section: gnome
 Priority: optional
-Maintainer: Debian GNOME Maintainers <pkg-gnome-maintainers@lists.alioth.debian.org>
+Maintainer: Ubuntu Developers <ubuntu-devel-discuss@lists.ubuntu.com>
+XSBC-Original-Maintainer: Debian GNOME Maintainers <pkg-gnome-maintainers@lists.alioth.debian.org>
 Uploaders: @GNOME_TEAM@
 Build-Depends: debhelper-compat (= 13),
                autoconf-archive,
@@ -16,6 +17,7 @@ Build-Depends: debhelper-compat (= 13),
                libkrb5-dev,
                librest-dev [!ia64 !kfreebsd-amd64 !kfreebsd-i386],
                libsecret-1-dev [!ia64 !kfreebsd-amd64 !kfreebsd-i386],
+               libsnapd-glib-dev (>= 1.43),
                libsoup2.4-dev (>= 2.42) [!ia64 !kfreebsd-amd64 !kfreebsd-i386],
                libjavascriptcoregtk-4.0-dev [!ia64 !kfreebsd-amd64 !kfreebsd-i386],
                libwebkit2gtk-4.0-dev (>= 2.26) [!ia64 !kfreebsd-amd64 !kfreebsd-i386],
@@ -23,14 +25,18 @@ Build-Depends: debhelper-compat (= 13),
 Build-Depends-Indep: libglib2.0-doc <!nodoc>, libgtk-3-doc <!nodoc>
 Rules-Requires-Root: no
 Standards-Version: 4.5.1
-Vcs-Browser: https://salsa.debian.org/gnome-team/gnome-online-accounts
-Vcs-Git: https://salsa.debian.org/gnome-team/gnome-online-accounts.git
+XS-Debian-Vcs-Git: https://salsa.debian.org/gnome-team/gnome-online-accounts.git
+XS-Debian-Vcs-Browser: https://salsa.debian.org/gnome-team/gnome-online-accounts
+Vcs-Git: https://salsa.debian.org/gnome-team/gnome-online-accounts.git -b ubuntu/master
+Vcs-Browser: https://salsa.debian.org/gnome-team/gnome-online-accounts/tree/ubuntu/master
 Homepage: https://wiki.gnome.org/Projects/GnomeOnlineAccounts
 
 Package: gnome-online-accounts
 Architecture: alpha amd64 arm64 armel armhf hppa hurd-i386 i386 m68k mips64el mipsel powerpc ppc64 ppc64el riscv64 s390x sh4 sparc64 x32
 Depends: libgoa-1.0-0b (= ${binary:Version}),
          libgoa-backend-1.0-1 (= ${binary:Version}),
+         python3,
+         python3-macaroonbakery,
          ${misc:Depends},
          ${shlibs:Depends}
 Recommends: gnome-control-center (>= 3.6.1)
diff -pruN 3.44.0-1/debian/gbp.conf 3.44.0-1ubuntu1/debian/gbp.conf
--- 3.44.0-1/debian/gbp.conf	2022-03-30 15:32:11.000000000 +0000
+++ 3.44.0-1ubuntu1/debian/gbp.conf	2022-03-30 15:35:58.000000000 +0000
@@ -1,7 +1,8 @@
 [DEFAULT]
 pristine-tar = True
-debian-branch = debian/master
+debian-branch = ubuntu/master
 upstream-branch = upstream/latest
+debian-tag=ubuntu/%(version)s
 
 [buildpackage]
 sign-tags = True
diff -pruN 3.44.0-1/debian/gnome-online-accounts.install 3.44.0-1ubuntu1/debian/gnome-online-accounts.install
--- 3.44.0-1/debian/gnome-online-accounts.install	2022-03-30 15:32:11.000000000 +0000
+++ 3.44.0-1ubuntu1/debian/gnome-online-accounts.install	2022-03-30 15:35:58.000000000 +0000
@@ -3,5 +3,6 @@ usr/libexec/goa-daemon
 usr/libexec/goa-identity-service
 usr/share/dbus-1/services/org.gnome.Identity.service
 usr/share/dbus-1/services/org.gnome.OnlineAccounts.service
+usr/share/goa-1.0/scripts/lpa_helper.py
 usr/share/icons
 usr/share/man
diff -pruN 3.44.0-1/debian/libgoa-backend-1.0-1.symbols 3.44.0-1ubuntu1/debian/libgoa-backend-1.0-1.symbols
--- 3.44.0-1/debian/libgoa-backend-1.0-1.symbols	2022-03-30 15:32:11.000000000 +0000
+++ 3.44.0-1ubuntu1/debian/libgoa-backend-1.0-1.symbols	2022-03-30 15:35:58.000000000 +0000
@@ -214,6 +214,7 @@ libgoa-backend-1.0.so.1 libgoa-backend-1
  goa_smtp_auth_new@Base 3.11.90
  goa_soup_logger_get_type@Base 3.25.90
  goa_soup_logger_new@Base 3.25.90
+ goa_ubuntu_sso_provider_get_type@Base 3.27.3-1ubuntu1
  goa_util_account_notify_property_cb@Base 3.10.0
  goa_util_add_row_switch_from_keyfile_with_blurb@Base 3.10.0
  goa_util_add_row_widget@Base 3.10.0
diff -pruN 3.44.0-1/debian/patches/0001-ubuntu-sso-provider.patch 3.44.0-1ubuntu1/debian/patches/0001-ubuntu-sso-provider.patch
--- 3.44.0-1/debian/patches/0001-ubuntu-sso-provider.patch	1970-01-01 00:00:00.000000000 +0000
+++ 3.44.0-1ubuntu1/debian/patches/0001-ubuntu-sso-provider.patch	2022-03-30 15:35:58.000000000 +0000
@@ -0,0 +1,1294 @@
+From: Andrea Azzarone <azzaronea@gmail.com>
+Date: Mon, 3 Sep 2018 10:45:50 +0200
+Subject: Implement an Ubuntu Single Sign-On provider. This talks with the
+ on-system snapd in order to authenticate the user. At the moment the
+ credentials can be used to install and remove snaps from gnome-software.
+
+https://bugzilla.gnome.org/show_bug.cgi?id=793755
+---
+ configure.ac                                       |  17 +
+ data/icons/scalable/Makefile.am                    |   1 +
+ data/icons/scalable/goa-account-ubuntusso.svg      | 109 +++
+ data/icons/symbolic/Makefile.am                    |   1 +
+ .../symbolic/goa-account-ubuntusso-symbolic.svg    |  31 +
+ po/POTFILES.in                                     |   1 +
+ src/goabackend/Makefile.am                         |   3 +
+ src/goabackend/goaprovider.c                       |   4 +
+ src/goabackend/goaubuntussoprovider.c              | 943 +++++++++++++++++++++
+ src/goabackend/goaubuntussoprovider.h              |  39 +
+ 10 files changed, 1149 insertions(+)
+ create mode 100644 data/icons/scalable/goa-account-ubuntusso.svg
+ create mode 100644 data/icons/symbolic/goa-account-ubuntusso-symbolic.svg
+ create mode 100644 src/goabackend/goaubuntussoprovider.c
+ create mode 100644 src/goabackend/goaubuntussoprovider.h
+
+Index: gnome-online-accounts-3.35.90/configure.ac
+===================================================================
+--- gnome-online-accounts-3.35.90.orig/configure.ac
++++ gnome-online-accounts-3.35.90/configure.ac
+@@ -140,6 +140,12 @@ if test "$enable_backend" != "no"; then
+   PKG_CHECK_MODULES(LIBXML, [libxml-2.0])
+   AC_SUBST(LIBXML_CFLAGS)
+   AC_SUBST(LIBXML_LIBS)
++
++  if test "$enable_ubuntu_sso" != "no"; then
++    PKG_CHECK_MODULES(SNAPD_GLIB, [snapd-glib >= 1.43])
++    AC_SUBST(SNAPD_GLIB_CFLAGS)
++    AC_SUBST(SNAPD_GLIB_LIBS)
++  fi
+ fi
+ 
+ AC_ARG_ENABLE([inspector],
+@@ -343,6 +349,16 @@ if test "$enable_windows_live" != "no";
+   AC_DEFINE(GOA_WINDOWS_LIVE_ENABLED, 1, [Enable Windows Live data provider])
+ fi
+ 
++# Ubuntu SSO
++AC_DEFINE(GOA_UBUNTU_SSO_NAME, ["ubuntusso"], [ProviderType and extension point name])
++AC_ARG_ENABLE([ubuntu-sso],
++              [AS_HELP_STRING([--enable-ubuntu-sso], [Enable Ubuntu SSO provider])],
++              [],
++              [enable_ubuntu_sso=no])
++if test "$enable_ubuntu_sso" != "no"; then
++  AC_DEFINE(GOA_UBUNTU_SSO_ENABLED, 1, [Enable Ubuntu SSO data provider])
++fi
++
+ # Kerberos
+ AC_DEFINE(GOA_KERBEROS_NAME, ["kerberos"], [ProviderType and extension point name])
+ AC_ARG_ENABLE([kerberos],
+@@ -577,6 +593,7 @@ echo "
+ 	Facebook provider:              ${enable_facebook} (OAuth 2.0, id:${with_facebook_client_id})
+ 	Windows Live provider:          ${enable_windows_live} (OAuth 2.0, id:${with_windows_live_client_id})
+ 	Last.fm provider:               ${enable_lastfm} (id:${with_lastfm_client_id} secret:${with_lastfm_client_secret})
++        Ubuntu SSO provider:            ${enable_ubuntu_sso}
+ 
+ 	Maintainer mode:                ${USE_MAINTAINER_MODE}
+ 	Building api docs:              ${enable_gtk_doc}
+Index: gnome-online-accounts-3.35.90/data/icons/scalable/Makefile.am
+===================================================================
+--- gnome-online-accounts-3.35.90.orig/data/icons/scalable/Makefile.am
++++ gnome-online-accounts-3.35.90/data/icons/scalable/Makefile.am
+@@ -12,6 +12,7 @@ icon_DATA =				\
+ 	goa-account-msn.svg		\
+ 	goa-account-owncloud.svg	\
+ 	goa-account-foursquare.svg	\
++	goa-account-ubuntusso.svg	\
+ 	$(NULL)
+ 
+ EXTRA_DIST = \
+Index: gnome-online-accounts-3.35.90/data/icons/scalable/goa-account-ubuntusso.svg
+===================================================================
+--- /dev/null
++++ gnome-online-accounts-3.35.90/data/icons/scalable/goa-account-ubuntusso.svg
+@@ -0,0 +1,109 @@
++<?xml version="1.0" encoding="UTF-8" standalone="no"?>
++<svg
++   xmlns:dc="http://purl.org/dc/elements/1.1/"
++   xmlns:cc="http://creativecommons.org/ns#"
++   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
++   xmlns:svg="http://www.w3.org/2000/svg"
++   xmlns="http://www.w3.org/2000/svg"
++   viewBox="0 0 128 128"
++   style="display:inline;enable-background:new"
++   version="1.0"
++   id="svg11300"
++   height="128"
++   width="128">
++  <title
++     id="title4162">Ubuntu One Icon</title>
++  <defs
++     id="defs3" />
++  <metadata
++     id="metadata4">
++    <rdf:RDF>
++      <cc:Work
++         rdf:about="">
++        <dc:format>image/svg+xml</dc:format>
++        <dc:type
++           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
++        <dc:creator>
++          <cc:Agent>
++            <dc:title>Andrea Azzarone</dc:title>
++          </cc:Agent>
++        </dc:creator>
++        <dc:source />
++        <cc:license
++           rdf:resource="http://creativecommons.org/licenses/by-sa/4.0/" />
++        <dc:title>Ubuntu One Icon</dc:title>
++        <dc:subject>
++          <rdf:Bag />
++        </dc:subject>
++        <dc:date />
++        <dc:rights>
++          <cc:Agent>
++            <dc:title />
++          </cc:Agent>
++        </dc:rights>
++        <dc:publisher>
++          <cc:Agent>
++            <dc:title />
++          </cc:Agent>
++        </dc:publisher>
++        <dc:identifier />
++        <dc:relation />
++        <dc:language />
++        <dc:coverage />
++        <dc:description />
++        <dc:contributor>
++          <cc:Agent>
++            <dc:title />
++          </cc:Agent>
++        </dc:contributor>
++      </cc:Work>
++      <cc:License
++         rdf:about="http://creativecommons.org/licenses/by-sa/4.0/">
++        <cc:permits
++           rdf:resource="http://creativecommons.org/ns#Reproduction" />
++        <cc:permits
++           rdf:resource="http://creativecommons.org/ns#Distribution" />
++        <cc:requires
++           rdf:resource="http://creativecommons.org/ns#Notice" />
++        <cc:requires
++           rdf:resource="http://creativecommons.org/ns#Attribution" />
++        <cc:permits
++           rdf:resource="http://creativecommons.org/ns#DerivativeWorks" />
++        <cc:requires
++           rdf:resource="http://creativecommons.org/ns#ShareAlike" />
++      </cc:License>
++    </rdf:RDF>
++  </metadata>
++  <g
++     transform="translate(0,-172)"
++     style="display:inline"
++     id="layer1">
++    <g
++       style="display:inline"
++       id="layer9">
++      <g
++         id="g3900"
++         style="display:inline;enable-background:new"
++         transform="translate(-3e-5,-159.99988)">
++        <g
++           transform="translate(368.00003,159.99976)"
++           id="g1747"
++           style="display:inline;enable-background:new">
++          <rect
++             style="display:inline;opacity:1;vector-effect:none;fill:#E95420;fill-opacity:1;stroke:none;stroke-width:0.24999999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:normal;enable-background:new"
++             id="rect1745"
++             width="104"
++             height="104.00024"
++             x="-356"
++             y="184"
++             rx="7.9999986"
++             ry="8" />
++        </g>
++        <path
++           style="fill:#ffffff;fill-opacity:1;stroke-width:0.33180749"
++           d="m 46.310338,361.96552 c -3.251491,0.0493 -6.606439,0.0979 -7.455439,0.10827 l -1.543638,0.0184 -0.002,4.45838 c -0.0052,11.65145 0.279497,41.15819 0.407257,42.20373 0.143526,1.17358 0.180967,1.3707 0.647672,3.4192 1.294356,5.68091 5.519652,11.60519 10.048093,14.08914 3.61014,1.98012 6.489188,2.99214 10.327918,3.63039 3.739544,0.62149 14.27011,0.0721 20.873269,-1.08912 0.614168,-0.10827 1.67829,-0.29197 2.364717,-0.40896 2.88726,-0.49109 4.901867,-0.891 7.159848,-1.42132 0.289024,-0.0677 0.75671,-0.16157 1.039165,-0.20816 l 0.513669,-0.0848 -0.09361,-32.25719 c -0.07189,-24.81606 -0.130059,-32.28066 -0.25092,-32.35977 -0.08639,-0.0563 -4.029547,-0.0882 -8.762273,-0.0707 l -8.60496,0.0322 -0.03319,25.17575 -0.03319,25.17574 -8.177665,-0.0345 -8.177667,-0.0345 -0.06569,-16.62672 -0.06569,-16.62673 -3.493875,-0.0671 -3.494203,-0.0671 1.772227,-3.68738 c 0.97479,-2.02806 2.798253,-5.78717 4.05254,-8.35325 1.253959,-2.56608 2.279985,-4.75337 2.279985,-4.86064 0,-0.21755 -0.31858,-0.21889 -11.232424,-0.0533"
++           id="path4060-7" />
++      </g>
++    </g>
++  </g>
++</svg>
+Index: gnome-online-accounts-3.35.90/data/icons/symbolic/Makefile.am
+===================================================================
+--- gnome-online-accounts-3.35.90.orig/data/icons/symbolic/Makefile.am
++++ gnome-online-accounts-3.35.90/data/icons/symbolic/Makefile.am
+@@ -11,6 +11,7 @@ icon_DATA =					\
+ 	goa-account-msn-symbolic.svg		\
+ 	goa-account-owncloud-symbolic.svg	\
+ 	goa-account-foursquare-symbolic.svg	\
++	goa-account-ubuntusso-symbolic.svg	\
+ 	$(NULL)
+ 
+ EXTRA_DIST = \
+Index: gnome-online-accounts-3.35.90/data/icons/symbolic/goa-account-ubuntusso-symbolic.svg
+===================================================================
+--- /dev/null
++++ gnome-online-accounts-3.35.90/data/icons/symbolic/goa-account-ubuntusso-symbolic.svg
+@@ -0,0 +1,31 @@
++<?xml version="1.0" encoding="UTF-8" standalone="no"?>
++<svg
++   xmlns:dc="http://purl.org/dc/elements/1.1/"
++   xmlns:cc="http://creativecommons.org/ns#"
++   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
++   xmlns:svg="http://www.w3.org/2000/svg"
++   xmlns="http://www.w3.org/2000/svg"
++   width="16"
++   height="16"
++   viewBox="0 0 16 16"
++   version="1.1"
++   id="svg4043">
++  <defs
++     id="defs4037" />
++  <metadata
++     id="metadata4040">
++    <rdf:RDF>
++      <cc:Work
++         rdf:about="">
++        <dc:format>image/svg+xml</dc:format>
++        <dc:type
++           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
++        <dc:title></dc:title>
++      </cc:Work>
++    </rdf:RDF>
++  </metadata>
++  <path
++     id="path4060-7"
++     d="m 5.0932841,2.4075749 c -0.5342753,0.00813 -1.0855491,0.016086 -1.2250546,0.017792 l -0.2536459,0.00301 -3.279e-4,0.7325869 c -8.547e-4,1.9145293 0.045926,6.762984 0.066917,6.9347842 0.023581,0.192838 0.029733,0.225229 0.1064234,0.561832 0.2126841,0.933469 0.9069714,1.906928 1.6510707,2.315083 0.5932069,0.325367 1.0662826,0.491659 1.6970502,0.596534 0.61447,0.102122 2.3448198,0.01184 3.42983,-0.17896 0.100919,-0.01779 0.275772,-0.04798 0.388564,-0.0672 0.474425,-0.0807 0.805458,-0.146406 1.176483,-0.233546 0.04749,-0.01113 0.12434,-0.02655 0.170752,-0.03421 l 0.08441,-0.01394 -0.01538,-5.3004009 c -0.01182,-4.0776962 -0.02137,-5.3042552 -0.04123,-5.3172542 -0.01419,-0.00925 -0.662122,-0.014495 -1.439789,-0.011614 l -1.4139402,0.0053 -0.0055,4.1367996 -0.0055,4.1367984 L 8.1206869,10.68527 6.7769585,10.67957 6.7662066,7.947609 6.7554146,5.215557 6.1813124,5.2045352 5.6071554,5.1935134 5.898362,4.5876142 C 6.0585366,4.2543702 6.358162,3.6366846 6.5642631,3.2150348 6.7703095,2.7933849 6.9389029,2.4339759 6.9389029,2.4163499 c 0,-0.035743 -0.052351,-0.035964 -1.8456763,-0.00875"
++     style="display:inline;fill:#241f31;fill-opacity:1;stroke-width:0.05452156;enable-background:new" />
++</svg>
+Index: gnome-online-accounts-3.35.90/po/POTFILES.in
+===================================================================
+--- gnome-online-accounts-3.35.90.orig/po/POTFILES.in
++++ gnome-online-accounts-3.35.90/po/POTFILES.in
+@@ -17,6 +17,7 @@ src/goabackend/goamediaserverprovider.c
+ src/goabackend/goaoauth2provider.c
+ src/goabackend/goaoauthprovider.c
+ src/goabackend/goaowncloudprovider.c
++src/goabackend/goaubuntussoprovider.c
+ src/goabackend/goaprovider.c
+ src/goabackend/goasmtpauth.c
+ src/goabackend/goautils.c
+Index: gnome-online-accounts-3.35.90/src/goabackend/Makefile.am
+===================================================================
+--- gnome-online-accounts-3.35.90.orig/src/goabackend/Makefile.am
++++ gnome-online-accounts-3.35.90/src/goabackend/Makefile.am
+@@ -93,6 +93,7 @@ libgoa_backend_1_0_la_SOURCES =						\
+ 	goafoursquareprovider.h		goafoursquareprovider.c		\
+ 	goawindowsliveprovider.h	goawindowsliveprovider.c	\
+ 	goalastfmprovider.h		goalastfmprovider.c		\
++	goaubuntussoprovider.h		goaubuntussoprovider.c		\
+ 	goaobjectskeletonutils.h	goaobjectskeletonutils.c	\
+ 	goautils.h			goautils.c			\
+ 	goawebview.h			goawebview.c			\
+@@ -124,6 +125,7 @@ libgoa_backend_1_0_la_CFLAGS =					\
+ 	$(LIBXML_CFLAGS)					\
+ 	$(TP_CFLAGS)						\
+ 	$(TPAW_CFLAGS)						\
++	$(SNAPD_GLIB_CFLAGS)					\
+ 	$(NULL)
+ 
+ libgoa_backend_1_0_la_LIBADD = 					\
+@@ -140,6 +142,7 @@ libgoa_backend_1_0_la_LIBADD = 					\
+ 	$(LIBXML_LIBS)						\
+ 	$(TP_LIBS)						\
+ 	$(TPAW_LIBS)						\
++	$(SNAPD_GLIB_LIBS)					\
+ 	$(NULL)
+ 
+ libgoa_backend_1_0_la_LDFLAGS = 				\
+Index: gnome-online-accounts-3.35.90/src/goabackend/goaprovider.c
+===================================================================
+--- gnome-online-accounts-3.35.90.orig/src/goabackend/goaprovider.c
++++ gnome-online-accounts-3.35.90/src/goabackend/goaprovider.c
+@@ -32,6 +32,7 @@
+ #include "goawindowsliveprovider.h"
+ #include "goamediaserverprovider.h"
+ #include "goalastfmprovider.h"
++#include "goaubuntussoprovider.h"
+ 
+ #ifdef GOA_FEDORA_ENABLED
+ #include "goafedoraprovider.h"
+@@ -935,6 +936,9 @@ static struct
+    * important because it affects the order in which they are
+    * returned by goa_provider_get_all.
+    */
++#ifdef GOA_UBUNTU_SSO_ENABLED
++  { GOA_UBUNTU_SSO_NAME, goa_ubuntu_sso_provider_get_type },
++#endif
+ #ifdef GOA_GOOGLE_ENABLED
+   { GOA_GOOGLE_NAME, goa_google_provider_get_type },
+ #endif
+Index: gnome-online-accounts-3.35.90/src/goabackend/goaubuntussoprovider.c
+===================================================================
+--- /dev/null
++++ gnome-online-accounts-3.35.90/src/goabackend/goaubuntussoprovider.c
+@@ -0,0 +1,943 @@
++/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
++/*
++ * Copyright © 2018 Canonical Ltd
++ *
++ * Authors: Andrea Azzarone <andrea.azzarone@canonical.com>
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Lesser General Public
++ * License as published by the Free Software Foundation; either
++ * version 2 of the License, or (at your option) any later version.
++ *
++ * This library is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++ * Lesser General Public License for more details.
++ *
++ * You should have received a copy of the GNU Lesser General
++ * Public License along with this library; if not, see <http://www.gnu.org/licenses/>.
++ */
++
++#include "config.h"
++
++#include <glib/gi18n-lib.h>
++#include <snapd-glib/snapd-glib.h>
++
++#include "goaprovider.h"
++#include "goaubuntussoprovider.h"
++#include "goaobjectskeletonutils.h"
++#include "goautils.h"
++
++/* ---------------------------------------------------------------------------------------------------- */
++
++struct _GoaUbuntuSSOProvider
++{
++  GoaProvider parent_instance;
++};
++
++G_DEFINE_TYPE_WITH_CODE (GoaUbuntuSSOProvider, goa_ubuntu_sso_provider, GOA_TYPE_PROVIDER,
++                         goa_provider_ensure_extension_points_registered ();
++                         g_io_extension_point_implement (GOA_PROVIDER_EXTENSION_POINT_NAME,
++                         g_define_type_id,
++                         GOA_UBUNTU_SSO_NAME,
++                         0));
++
++/* ---------------------------------------------------------------------------------------------------- */
++
++typedef struct
++{
++  GCancellable *cancellable;
++
++  GtkDialog *dialog;
++  GMainLoop *loop;
++
++  GtkWidget *cluebar;
++  GtkWidget *cluebar_label;
++  GtkWidget *connect_button;
++  GtkWidget *progress_grid;
++
++  GtkWidget *stack;
++
++  GtkWidget *username_entry;
++  GtkWidget *password_entry;
++  GtkWidget *otp_entry;
++  GtkWidget *login_radio;
++  GtkWidget *register_radio;
++  GtkWidget *reset_radio;
++
++  SnapdClient *snapd_client;
++
++  gchar  *macaroon;
++  gchar **discharges;
++  gchar  *account_object_path;
++
++  GError *error;
++} AddAccountData;
++
++static void
++add_account_data_init (AddAccountData *data)
++{
++  memset (data, 0, sizeof (AddAccountData));
++  data->cancellable = g_cancellable_new ();
++  data->loop = g_main_loop_new (NULL, FALSE);
++  data->snapd_client = snapd_client_new ();
++}
++
++static void
++add_account_data_clear (AddAccountData *data)
++{
++  g_clear_object (&data->cancellable);
++  g_clear_pointer (&data->loop, (GDestroyNotify) g_main_loop_unref);
++  g_clear_object (&data->snapd_client);
++  g_free (data->macaroon);
++  g_strfreev (data->discharges);
++  g_free (data->account_object_path);
++  g_clear_error (&data->error);
++}
++
++G_DEFINE_AUTO_CLEANUP_CLEAR_FUNC(AddAccountData, add_account_data_clear)
++
++/* ---------------------------------------------------------------------------------------------------- */
++
++static const gchar *
++get_provider_type (GoaProvider *provider)
++{
++  return GOA_UBUNTU_SSO_NAME;
++}
++
++static gchar *
++get_provider_name (GoaProvider *provider, GoaObject *object)
++{
++  return g_strdup(_("Ubuntu Single Sign-On"));
++}
++
++static GoaProviderGroup
++get_provider_group (GoaProvider *provider)
++{
++  return GOA_PROVIDER_GROUP_BRANDED;
++}
++
++static GoaProviderFeatures
++get_provider_features (GoaProvider *provider)
++{
++  return GOA_PROVIDER_FEATURE_BRANDED |
++         GOA_PROVIDER_FEATURE_TICKETING;
++}
++
++/* ---------------------------------------------------------------------------------------------------- */
++
++static gboolean on_handle_get_password (GoaPasswordBased      *interface,
++                                        GDBusMethodInvocation *invocation,
++                                        const gchar           *id,
++                                        gpointer               user_data);
++
++static gboolean
++build_object (GoaProvider         *provider,
++              GoaObjectSkeleton   *object,
++              GKeyFile            *key_file,
++              const gchar         *group,
++              GDBusConnection     *connection,
++              gboolean             just_added,
++              GError             **error)
++{
++  GoaPasswordBased *password_based = NULL;
++  gboolean ret = FALSE;
++
++  // Chain up
++  if (!GOA_PROVIDER_CLASS (goa_ubuntu_sso_provider_parent_class)->build_object (provider,
++                                                                                object,
++                                                                                key_file,
++                                                                                group,
++                                                                                connection,
++                                                                                just_added,
++                                                                                error))
++    goto out;
++
++  password_based = goa_object_get_password_based (GOA_OBJECT (object));
++  if (password_based == NULL)
++    {
++      password_based = goa_password_based_skeleton_new ();
++      // Ensure D-Bus method invocations run in their own thread
++      g_dbus_interface_skeleton_set_flags (G_DBUS_INTERFACE_SKELETON (password_based),
++                                           G_DBUS_INTERFACE_SKELETON_FLAGS_HANDLE_METHOD_INVOCATIONS_IN_THREAD);
++      goa_object_skeleton_set_password_based (object, password_based);
++      g_signal_connect (password_based,
++                        "handle-get-password",
++                        G_CALLBACK (on_handle_get_password),
++                        NULL);
++    }
++
++  ret = TRUE;
++
++ out:
++  g_clear_object (&password_based);
++  return ret;
++}
++
++/* ---------------------------------------------------------------------------------------------------- */
++
++static gboolean
++ensure_credentials_sync (GoaProvider   *provider,
++                         GoaObject     *object,
++                         gint          *out_expires_in,
++                         GCancellable  *cancellable,
++                         GError       **error)
++{
++  g_autofree gchar *macaroon = NULL;
++  g_autofree gchar *discharges_str = NULL;
++  g_autoptr(GVariant) discharges_var = NULL;
++  g_autofree const gchar **discharges = NULL;
++  g_autoptr(SnapdClient) snapd_client = NULL;
++  g_autoptr(SnapdAuthData) auth_data = NULL;
++
++  if (!goa_utils_get_credentials (provider, object, "macaroon", NULL, &macaroon, cancellable, error))
++    goto edit_error_and_return;
++
++  if (!goa_utils_get_credentials (provider, object, "discharges", NULL, &discharges_str, cancellable, error))
++    goto edit_error_and_return;
++
++  if (discharges_str)
++    discharges_var = g_variant_parse (G_VARIANT_TYPE ("as"), discharges_str, NULL, NULL, NULL);
++  if (discharges_var)
++    discharges = g_variant_get_strv (discharges_var, NULL);
++
++  snapd_client = snapd_client_new ();
++  auth_data = snapd_auth_data_new (macaroon, (gchar **) discharges);
++  snapd_client_set_auth_data (snapd_client, auth_data);
++  snapd_client_check_buy_sync (snapd_client, cancellable, error);
++
++  if (error != NULL)
++    {
++      if (g_error_matches (*error, SNAPD_ERROR, SNAPD_ERROR_AUTH_DATA_REQUIRED))
++        goto edit_error_and_return;
++      else
++        g_clear_error (error);
++    }
++
++  if (out_expires_in != NULL)
++    *out_expires_in = 0;
++
++  return TRUE;
++
++edit_error_and_return:
++  if (error != NULL)
++    {
++      (*error)->domain = GOA_ERROR;
++      (*error)->code = GOA_ERROR_NOT_AUTHORIZED;
++    }
++  return FALSE;
++}
++
++/* ---------------------------------------------------------------------------------------------------- */
++
++static void
++add_entry (GtkWidget     *grid,
++           gint           row,
++           const gchar   *text,
++           GtkWidget    **out_entry)
++{
++  GtkWidget *label;
++  GtkWidget *entry;
++
++  label = gtk_label_new_with_mnemonic (text);
++  gtk_widget_set_halign (label, GTK_ALIGN_END);
++  gtk_widget_set_hexpand (label, FALSE);
++  gtk_grid_attach (GTK_GRID (grid), label, 0, row, 1, 1);
++
++  entry = gtk_entry_new ();
++  gtk_widget_set_hexpand (entry, TRUE);
++  gtk_widget_set_size_request (entry, 250, -1);
++  gtk_entry_set_activates_default (GTK_ENTRY (entry), TRUE);
++  gtk_grid_attach (GTK_GRID (grid), entry, 1, row, 2, 1);
++
++  gtk_label_set_mnemonic_widget (GTK_LABEL (label), entry);
++
++  if (out_entry != NULL)
++    *out_entry = entry;
++}
++
++static void
++add_radio (GtkWidget      *grid,
++           gint            row,
++           const gchar    *text,
++           GtkRadioButton *group_source,
++           GtkWidget     **out_radio)
++{
++  GtkWidget *radio;
++
++  radio = gtk_radio_button_new_with_mnemonic_from_widget (group_source, text);
++  gtk_widget_set_hexpand (radio, FALSE);
++  gtk_widget_set_halign (radio, GTK_ALIGN_START);
++  gtk_grid_attach (GTK_GRID (grid), radio, 0, row, 3, 1);
++
++  if (out_radio != NULL)
++    *out_radio = radio;
++}
++
++static void
++update_widgets (AddAccountData *data)
++{
++  gboolean can_add = TRUE;
++  const gchar *visible_page;
++
++  visible_page = gtk_stack_get_visible_child_name (GTK_STACK (data->stack));
++  if (g_strcmp0 (visible_page, "login") == 0)
++    {
++      if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (data->login_radio)))
++        {
++          can_add =  gtk_entry_get_text_length (GTK_ENTRY (data->username_entry)) > 0
++                     && gtk_entry_get_text_length (GTK_ENTRY (data->password_entry)) > 0;
++          gtk_widget_set_sensitive (data->password_entry, TRUE);
++        }
++      else
++        {
++          gtk_widget_set_sensitive (data->password_entry, FALSE);
++        }
++    }
++  else if (g_strcmp0 (visible_page, "otp") == 0)
++    {
++      can_add = gtk_entry_get_text_length (GTK_ENTRY (data->otp_entry)) > 0;
++    }
++
++  gtk_dialog_set_response_sensitive (data->dialog, GTK_RESPONSE_OK, can_add);
++}
++
++static void
++on_username_or_password_changed (GtkEditable *editable,
++                                 gpointer user_data)
++{
++  AddAccountData *data = user_data;
++  update_widgets (data);
++}
++
++static void
++on_otp_changed (GtkEditable *editable,
++                gpointer user_data)
++{
++  AddAccountData *data = user_data;
++  update_widgets (data);
++}
++
++static void
++on_radio_button_toggled_cb (GtkToggleButton *togglebutton,
++                            gpointer         user_data)
++{
++  AddAccountData *data = user_data;
++  update_widgets (data);
++}
++
++static void
++show_progress_ui (GtkContainer *container,
++                  gboolean progress)
++{
++  g_autoptr(GList) children = gtk_container_get_children (container);
++  for (GList *l = children; l != NULL; l = l->next)
++    {
++      GtkWidget *widget = GTK_WIDGET (l->data);
++      gdouble opacity;
++
++      opacity = progress ? 1.0 : 0.0;
++      gtk_widget_set_opacity (widget, opacity);
++    }
++}
++
++static char *
++get_item (const char *buffer, const char *name)
++{
++  char *label, *start, *end, *result;
++  char end_char;
++
++  result = NULL;
++  start = NULL;
++  end = NULL;
++  label = g_strconcat (name, "=", NULL);
++  if ((start = strstr (buffer, label)) != NULL)
++    {
++      start += strlen (label);
++      end_char = '\n';
++      if (*start == '"')
++        {
++          start++;
++          end_char = '"';
++        }
++
++      end = strchr (start, end_char);
++    }
++
++    if (start != NULL && end != NULL)
++      {
++        result = g_strndup (start, end - start);
++      }
++
++  g_free (label);
++
++  return result;
++}
++
++static void
++create_account_details_ui (GoaProvider    *provider,
++                           GtkDialog      *dialog,
++                           GtkBox         *vbox,
++                           gboolean        new_account,
++                           const gchar    *existing_identity,
++                           AddAccountData *data)
++{
++  GtkWidget *grid0;
++  GtkWidget *grid1;
++  GtkWidget *grid2;
++  GtkWidget *label;
++  GtkWidget *footer_box;
++  GtkWidget *privacy_button;
++  GObject *revealer;
++  GtkWidget *spinner;
++  gint row;
++  gint width;
++  g_autofree gchar *buffer = NULL;
++  g_autofree gchar* privacy_policy = NULL;
++
++  goa_utils_set_dialog_title (provider, dialog, new_account);
++
++  grid0 = gtk_grid_new ();
++  gtk_container_set_border_width (GTK_CONTAINER (grid0), 12);
++  gtk_widget_set_margin_bottom (grid0, 0);
++  gtk_orientable_set_orientation (GTK_ORIENTABLE (grid0), GTK_ORIENTATION_VERTICAL);
++  gtk_grid_set_row_spacing (GTK_GRID (grid0), 12);
++  gtk_container_add (GTK_CONTAINER (vbox), grid0);
++
++  data->cluebar = gtk_info_bar_new ();
++  gtk_info_bar_set_message_type (GTK_INFO_BAR (data->cluebar), GTK_MESSAGE_ERROR);
++  gtk_widget_set_hexpand (data->cluebar, TRUE);
++  gtk_widget_set_no_show_all (data->cluebar, TRUE);
++  gtk_container_add (GTK_CONTAINER (grid0), data->cluebar);
++
++  // GtkInfoBar fails to show after gtk_widget_hide has been called. Apply
++  // a workaround as suggested in https://bugzilla.gnome.org/show_bug.cgi?id=710888
++  revealer = gtk_widget_get_template_child (GTK_WIDGET (data->cluebar), GTK_TYPE_INFO_BAR, "revealer");
++  if (revealer)
++    {
++      gtk_revealer_set_transition_type (GTK_REVEALER (revealer), GTK_REVEALER_TRANSITION_TYPE_NONE);
++      gtk_revealer_set_transition_duration (GTK_REVEALER (revealer), 0);
++    }
++
++  data->cluebar_label = gtk_label_new ("");
++  gtk_widget_set_hexpand (data->cluebar_label, TRUE);
++  gtk_label_set_line_wrap (GTK_LABEL (data->cluebar_label), TRUE);
++  gtk_label_set_max_width_chars (GTK_LABEL (data->cluebar_label), 50);
++  gtk_container_add (GTK_CONTAINER (gtk_info_bar_get_content_area (GTK_INFO_BAR (data->cluebar))),
++                     data->cluebar_label);
++
++  data->stack = gtk_stack_new ();
++  gtk_container_add (GTK_CONTAINER (grid0), data->stack);
++
++  grid1 = gtk_grid_new ();
++  gtk_grid_set_column_spacing (GTK_GRID (grid1), 12);
++  gtk_grid_set_row_spacing (GTK_GRID (grid1), 12);
++  gtk_stack_add_named (GTK_STACK (data->stack), grid1, "login");
++
++  row = 0;
++  add_entry (grid1, row++, _("_Email address:"), &data->username_entry);
++  add_radio (grid1, row++, _("I have an Ubuntu Single Sign-On account"), NULL, &data->login_radio);
++  add_entry (grid1, row++, _("_Password:"), &data->password_entry);
++  add_radio (grid1, row++, _("I want to register for an account now"), GTK_RADIO_BUTTON (data->login_radio), &data->register_radio);
++  add_radio (grid1, row++, _("I've forgotten my password"), GTK_RADIO_BUTTON (data->login_radio), &data->reset_radio);
++  gtk_entry_set_visibility (GTK_ENTRY (data->password_entry), FALSE);
++
++  if (new_account)
++    {
++      gtk_widget_grab_focus (data->username_entry);
++    }
++  else
++    {
++      gtk_widget_set_sensitive (data->username_entry, FALSE);
++      gtk_entry_set_text (GTK_ENTRY (data->username_entry), existing_identity);
++      gtk_widget_set_sensitive (data->register_radio, FALSE);
++      gtk_widget_grab_focus (data->password_entry);
++    }
++
++  g_signal_connect (data->username_entry, "changed", G_CALLBACK (on_username_or_password_changed), data);
++  g_signal_connect (data->password_entry, "changed", G_CALLBACK (on_username_or_password_changed), data);
++  g_signal_connect (data->login_radio, "toggled", G_CALLBACK (on_radio_button_toggled_cb), data);
++  g_signal_connect (data->register_radio, "toggled", G_CALLBACK (on_radio_button_toggled_cb), data);
++  g_signal_connect (data->reset_radio, "toggled", G_CALLBACK (on_radio_button_toggled_cb), data);
++
++  grid2 = gtk_grid_new ();
++  gtk_grid_set_column_spacing (GTK_GRID (grid2), 12);
++  gtk_grid_set_row_spacing (GTK_GRID (grid2), 12);
++  gtk_stack_add_named (GTK_STACK (data->stack), grid2, "otp");
++
++  row = 0;
++  add_entry (grid2, row++, _("Passc_ode:"), &data->otp_entry);
++
++  g_signal_connect (data->otp_entry, "changed", G_CALLBACK (on_otp_changed), data);
++
++  gtk_dialog_add_button (data->dialog, _("_Cancel"), GTK_RESPONSE_CANCEL);
++  data->connect_button = gtk_dialog_add_button (data->dialog, _("C_onnect"), GTK_RESPONSE_OK);
++  gtk_dialog_set_default_response (data->dialog, GTK_RESPONSE_OK);
++  gtk_dialog_set_response_sensitive (data->dialog, GTK_RESPONSE_OK, FALSE);
++
++  footer_box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 3);
++  gtk_widget_show (footer_box);
++  gtk_container_add (GTK_CONTAINER (grid0), footer_box);
++
++  data->progress_grid = gtk_grid_new ();
++  gtk_orientable_set_orientation (GTK_ORIENTABLE (data->progress_grid), GTK_ORIENTATION_HORIZONTAL);
++  gtk_grid_set_column_spacing (GTK_GRID (data->progress_grid), 3);
++  gtk_box_pack_start (GTK_CONTAINER (footer_box), data->progress_grid, TRUE, TRUE, 0);
++
++  spinner = gtk_spinner_new ();
++  gtk_widget_set_opacity (spinner, 0.0);
++  gtk_widget_set_size_request (spinner, 20, 20);
++  gtk_spinner_start (GTK_SPINNER (spinner));
++  gtk_container_add (GTK_CONTAINER (data->progress_grid), spinner);
++
++  label = gtk_label_new (_("Connecting…"));
++  gtk_widget_set_opacity (label, 0.0);
++  gtk_container_add (GTK_CONTAINER (data->progress_grid), label);
++
++  if (g_file_get_contents ("/etc/os-release", &buffer, NULL, NULL))
++    {
++      privacy_policy = get_item (buffer, "PRIVACY_POLICY_URL");
++
++      if (privacy_policy)
++        {
++          privacy_button = gtk_link_button_new_with_label (privacy_policy,
++                                                           _("Privacy Policy"));
++          gtk_widget_show (privacy_button);
++          gtk_box_pack_end (GTK_BOX (footer_box), privacy_button, FALSE, FALSE, 0);
++        }
++    }
++
++  if (new_account)
++   {
++     gtk_window_get_size (GTK_WINDOW (data->dialog), &width, NULL);
++     gtk_window_set_default_size (GTK_WINDOW (data->dialog), width, -1);
++   }
++  else
++    {
++      GtkWindow *parent;
++
++      /* Keep in sync with GoaPanelAddAccountDialog in
++       * gnome-control-center.
++       */
++      parent = gtk_window_get_transient_for (GTK_WINDOW (data->dialog));
++      if (parent != NULL)
++        {
++          gtk_window_get_size (parent, &width, NULL);
++          gtk_window_set_default_size (GTK_WINDOW (data->dialog), (gint) (0.5 * width), -1);
++        }
++    }
++}
++
++/* ---------------------------------------------------------------------------------------------------- */
++
++static const gchar*
++get_snapd_error_message (GError *error)
++{
++  g_return_val_if_fail (error != NULL, NULL);
++
++  g_debug ("Error logging in snapd: %s (%s, %d)",
++           error->message, g_quark_to_string (error->domain), error->code);
++
++  if (g_error_matches (error, SNAPD_ERROR, SNAPD_ERROR_AUTH_DATA_REQUIRED))
++    return _("Provided email/password is not correct");
++  else if (g_error_matches (error, SNAPD_ERROR, SNAPD_ERROR_TWO_FACTOR_INVALID))
++    return _("The provided 2-factor key is not recognised");
++  else
++    return _("Something went wrong, please try again");
++}
++
++static void
++dialog_response_cb (GtkDialog *dialog,
++                    gint response_id,
++                    gpointer user_data)
++{
++  AddAccountData *data = user_data;
++
++  if (response_id == GTK_RESPONSE_CANCEL || response_id == GTK_RESPONSE_DELETE_EVENT)
++    g_cancellable_cancel (data->cancellable);
++}
++
++static void
++snapd_login_ready_cb (GObject *object,
++                      GAsyncResult *result,
++                      gpointer user_data)
++{
++  AddAccountData *data = user_data;
++  g_autoptr(SnapdUserInformation) user_information = NULL;
++  SnapdAuthData *auth_data;
++
++  user_information = snapd_client_login2_finish (data->snapd_client, result, &data->error);
++  if (user_information != NULL)
++    {
++      auth_data = snapd_user_information_get_auth_data (user_information);
++      data->macaroon = g_strdup (snapd_auth_data_get_macaroon (auth_data));
++      data->discharges = g_strdupv (snapd_auth_data_get_discharges (auth_data));
++    }
++
++  update_widgets (data);
++  show_progress_ui (GTK_CONTAINER (data->progress_grid), FALSE);
++  g_main_loop_quit (data->loop);
++}
++
++static void
++add_account_cb (GoaManager *manager,
++                GAsyncResult *res,
++                gpointer user_data)
++{
++  AddAccountData *data = user_data;
++  goa_manager_call_add_account_finish (manager,
++                                       &data->account_object_path,
++                                       res,
++                                       &data->error);
++  g_main_loop_quit (data->loop);
++}
++
++static void
++add_credentials_key_values (GVariantBuilder *builder,
++                            AddAccountData *data)
++{
++  g_autofree gchar *discharges_str = NULL;
++  g_autoptr(GVariant) discharges_var = NULL;
++
++  g_variant_builder_add (builder, "{sv}", "macaroon", g_variant_new_string (data->macaroon));
++  discharges_var = g_variant_new_strv ((const gchar * const*) data->discharges, -1);
++  discharges_str = g_variant_print (discharges_var, FALSE);
++  g_variant_builder_add (builder, "{sv}", "discharges", g_variant_new_string (discharges_str));
++}
++
++static gboolean
++get_tokens_and_identity (GoaProvider    *provider,
++                         gboolean        add_account,
++                         const gchar    *existing_identity,
++                         GtkDialog      *dialog,
++                         GtkBox         *vbox,
++                         AddAccountData *data)
++{
++  gboolean ret = FALSE;
++  const gchar *password;
++  const gchar *username;
++  const gchar *otp;
++  gint response;
++
++  g_return_val_if_fail (GOA_IS_UBUNTU_SSO_PROVIDER (provider), FALSE);
++  g_return_val_if_fail ((!add_account && existing_identity != NULL && existing_identity[0] != '\0')
++                        || (add_account && existing_identity == NULL), FALSE);
++  g_return_val_if_fail (GTK_IS_DIALOG (dialog), FALSE);
++  g_return_val_if_fail (GTK_IS_BOX (vbox), FALSE);
++  g_return_val_if_fail (data != NULL, FALSE);
++
++  data->dialog = dialog;
++
++  create_account_details_ui (provider, dialog, vbox, add_account, existing_identity, data);
++  gtk_widget_show_all (GTK_WIDGET (vbox));
++  g_signal_connect (dialog, "response", G_CALLBACK (dialog_response_cb), data);
++
++ login_again:
++  response = gtk_dialog_run (dialog);
++  if (response != GTK_RESPONSE_OK)
++    {
++      g_set_error (&data->error,
++                   GOA_ERROR,
++                   GOA_ERROR_DIALOG_DISMISSED,
++                   _("Dialog was dismissed"));
++      goto out;
++    }
++
++  gtk_widget_set_no_show_all (data->cluebar, TRUE);
++  gtk_widget_hide (data->cluebar);
++
++  if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (data->register_radio)))
++    {
++      g_app_info_launch_default_for_uri ("https://login.ubuntu.com/+new_account", NULL, NULL);
++      goto login_again;
++    }
++  else if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (data->reset_radio)))
++    {
++      g_app_info_launch_default_for_uri ("https://login.ubuntu.com/+forgot_password", NULL, NULL);
++      goto login_again;
++    }
++
++  username = gtk_entry_get_text (GTK_ENTRY (data->username_entry));
++  password = gtk_entry_get_text (GTK_ENTRY (data->password_entry));
++  otp = gtk_entry_get_text (GTK_ENTRY (data->otp_entry));
++  otp = otp && strlen (otp) > 0 ? otp : NULL;
++
++  g_clear_object (&data->cancellable);
++  data->cancellable = g_cancellable_new ();
++
++  snapd_client_login2_async (data->snapd_client,
++                             username, password, otp,
++                             data->cancellable, snapd_login_ready_cb, data);
++
++  gtk_widget_set_sensitive (data->connect_button, FALSE);
++  show_progress_ui (GTK_CONTAINER (data->progress_grid), TRUE);
++  g_main_loop_run (data->loop);
++
++  if (g_cancellable_is_cancelled (data->cancellable))
++    {
++      g_prefix_error (&data->error,
++                      _("Dialog was dismissed (%s, %d): "),
++                      g_quark_to_string (data->error->domain),
++                      data->error->code);
++      data->error->domain = GOA_ERROR;
++      data->error->code = GOA_ERROR_DIALOG_DISMISSED;
++      goto out;
++    }
++  else if (data->error != NULL)
++    {
++      if (data->error->code == SNAPD_ERROR_TWO_FACTOR_REQUIRED)
++        {
++          g_autofree gchar *markup = NULL;
++
++          g_clear_error (&data->error);
++          gtk_button_set_label (GTK_BUTTON (data->connect_button), _("C_onnect"));
++          gtk_stack_set_visible_child_name (GTK_STACK (data->stack), "otp");
++          gtk_widget_set_sensitive (data->connect_button, FALSE);
++
++          markup = g_strdup_printf ("<b>%s</b>", _("Please enter a passcode from your authentication device or app"));
++          gtk_label_set_markup (GTK_LABEL (data->cluebar_label), markup);
++          gtk_info_bar_set_message_type (GTK_INFO_BAR (data->cluebar), GTK_MESSAGE_INFO);
++          gtk_widget_set_no_show_all (data->cluebar, FALSE);
++          gtk_widget_show_all (data->cluebar);
++        }
++      else if (data->error->code == SNAPD_ERROR_AUTH_CANCELLED)
++        {
++          g_clear_error (&data->error);
++        }
++      else
++        {
++          g_autofree gchar *markup = NULL;
++
++          gtk_button_set_label (GTK_BUTTON (data->connect_button), _("_Try Again"));
++          markup = g_strdup_printf ("<b>%s:</b>\n%s",
++                                    _("Error connecting to Ubuntu Single Sign-On server"),
++                                    get_snapd_error_message (data->error));
++          g_clear_error (&data->error);
++          gtk_label_set_markup (GTK_LABEL (data->cluebar_label), markup);
++          gtk_info_bar_set_message_type (GTK_INFO_BAR (data->cluebar), GTK_MESSAGE_ERROR);
++          gtk_widget_set_no_show_all (data->cluebar, FALSE);
++          gtk_widget_show_all (data->cluebar);
++        }
++
++      goto login_again;
++    }
++
++  gtk_widget_hide (GTK_WIDGET (dialog));
++
++  ret = TRUE;
++
++ out:
++  g_signal_handlers_disconnect_by_func (dialog, dialog_response_cb, data);
++
++  return ret;
++}
++
++static GoaObject *
++add_account (GoaProvider *provider,
++             GoaClient   *client,
++             GtkDialog   *dialog,
++             GtkBox      *vbox,
++             GError     **error)
++{
++  g_auto(AddAccountData) data;
++  GVariantBuilder credentials;
++  GVariantBuilder details;
++  GoaObject *ret = NULL;
++  const gchar *username;
++
++  g_return_val_if_fail (GOA_IS_UBUNTU_SSO_PROVIDER (provider), NULL);
++  g_return_val_if_fail (GOA_IS_CLIENT (client), NULL);
++  g_return_val_if_fail (GTK_IS_DIALOG (dialog), NULL);
++  g_return_val_if_fail (GTK_IS_BOX (vbox), NULL);
++  g_return_val_if_fail (error == NULL || *error == NULL, NULL);
++
++  add_account_data_init (&data);
++  if (!get_tokens_and_identity (provider, TRUE, NULL, dialog, vbox, &data))
++    goto out;
++
++  username = gtk_entry_get_text (GTK_ENTRY (data.username_entry));
++
++  /* OK, got the identity... see if there's already an account
++   * of this type with the given identity
++   */
++  if (!goa_utils_check_duplicate (client,
++                                  username,
++                                  username,
++                                  goa_provider_get_provider_type (provider),
++                                  (GoaPeekInterfaceFunc) goa_object_peek_password_based,
++                                  &data.error))
++    goto out;
++
++  g_variant_builder_init (&credentials, G_VARIANT_TYPE_VARDICT);
++  add_credentials_key_values (&credentials, &data);
++  g_variant_builder_init (&details, G_VARIANT_TYPE ("a{ss}"));
++
++  /* OK, everything is dandy, add the account */
++  /* we want the GoaClient to update before this method returns (so it
++   * can create a proxy for the new object) so run the mainloop while
++   * waiting for this to complete
++   */
++  goa_manager_call_add_account (goa_client_get_manager (client),
++                                goa_provider_get_provider_type (provider),
++                                username,
++                                username,
++                                g_variant_builder_end (&credentials),
++                                g_variant_builder_end (&details),
++                                NULL, // GCancellable*
++                                (GAsyncReadyCallback) add_account_cb,
++                                &data);
++  g_main_loop_run (data.loop);
++  if (data.error != NULL)
++    goto out;
++
++  ret = GOA_OBJECT (g_dbus_object_manager_get_object (goa_client_get_object_manager (client),
++                                                      data.account_object_path));
++
++ out:
++  /* We might have an object even when data.error is set.
++   * eg., if we failed to store the credentials in the keyring.
++   */
++  if (data.error != NULL)
++    {
++      g_propagate_error (error, data.error);
++      data.error = NULL;
++    }
++  else
++    g_assert (ret != NULL);
++
++  return ret;
++}
++
++/* ---------------------------------------------------------------------------------------------------- */
++
++static gboolean
++refresh_account (GoaProvider  *provider,
++                 GoaClient    *client,
++                 GoaObject    *object,
++                 GtkWindow    *parent,
++                 GError      **error)
++{
++  g_auto(AddAccountData) data;
++  GoaAccount *account;
++  GtkWidget *dialog;
++  const gchar *existing_presentation_identity;
++  GVariantBuilder builder;
++  gboolean ret = FALSE;
++
++  g_return_val_if_fail (GOA_IS_UBUNTU_SSO_PROVIDER (provider), FALSE);
++  g_return_val_if_fail (GOA_IS_CLIENT (client), FALSE);
++  g_return_val_if_fail (GOA_IS_OBJECT (object), FALSE);
++  g_return_val_if_fail (parent == NULL || GTK_IS_WINDOW (parent), FALSE);
++  g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
++
++  dialog = gtk_dialog_new_with_buttons (NULL,
++                                        parent,
++                                        GTK_DIALOG_MODAL
++                                        | GTK_DIALOG_DESTROY_WITH_PARENT
++                                        | GTK_DIALOG_USE_HEADER_BAR,
++                                        NULL,
++                                        NULL);
++  gtk_container_set_border_width (GTK_CONTAINER (dialog), 12);
++  gtk_window_set_resizable (GTK_WINDOW (dialog), FALSE);
++  gtk_widget_show_all (dialog);
++
++  account = goa_object_peek_account (object);
++
++  existing_presentation_identity = goa_account_get_presentation_identity (account);
++  add_account_data_init (&data);
++  if (!get_tokens_and_identity (provider,
++                                FALSE,
++                                existing_presentation_identity,
++                                GTK_DIALOG (dialog),
++                                GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (dialog))),
++                                &data))
++    {
++      goto out;
++    }
++
++  g_variant_builder_init (&builder, G_VARIANT_TYPE_VARDICT);
++  add_credentials_key_values (&builder, &data);
++
++  if (!goa_utils_store_credentials_for_object_sync (GOA_PROVIDER (provider),
++                                                    object,
++                                                    g_variant_builder_end (&builder),
++                                                    NULL, /* GCancellable */
++                                                    error))
++    goto out;
++
++  goa_account_call_ensure_credentials (goa_object_peek_account (object),
++                                       NULL, /* GCancellable */
++                                       NULL, NULL); /* callback, user_data */
++
++  ret = TRUE;
++
++ out:
++  if (data.error != NULL)
++    {
++      g_propagate_error (error, data.error);
++      data.error = NULL;
++    }
++
++  gtk_widget_destroy (dialog);
++  return ret;
++}
++
++/* ---------------------------------------------------------------------------------------------------- */
++
++static void
++goa_ubuntu_sso_provider_init (GoaUbuntuSSOProvider *self)
++{
++}
++
++static void
++goa_ubuntu_sso_provider_class_init (GoaUbuntuSSOProviderClass *klass)
++{
++  GoaProviderClass *provider_class = GOA_PROVIDER_CLASS (klass);
++
++  provider_class->get_provider_type       = get_provider_type;
++  provider_class->get_provider_name       = get_provider_name;
++  provider_class->get_provider_group      = get_provider_group;
++  provider_class->get_provider_features   = get_provider_features;
++  provider_class->add_account             = add_account;
++  provider_class->refresh_account         = refresh_account;
++  provider_class->build_object            = build_object;
++  provider_class->ensure_credentials_sync = ensure_credentials_sync;
++}
++
++/* ---------------------------------------------------------------------------------------------------- */
++
++static gboolean
++on_handle_get_password (GoaPasswordBased      *interface,
++                        GDBusMethodInvocation *invocation,
++                        const gchar           *id,
++                        gpointer               user_data)
++{
++  GoaObject *object;
++  GoaAccount *account;
++  g_autoptr(GoaProvider) provider = NULL;
++  GError *error;
++  const gchar *account_id;
++  const gchar *method_name;
++  const gchar *provider_type;
++  g_autofree gchar *password = NULL;
++
++  object = GOA_OBJECT (g_dbus_interface_get_object (G_DBUS_INTERFACE (interface)));
++  account = goa_object_peek_account (object);
++  account_id = goa_account_get_id (account);
++  provider_type = goa_account_get_provider_type (account);
++  method_name = g_dbus_method_invocation_get_method_name (invocation);
++  g_debug ("Handling %s for account (%s, %s)", method_name, provider_type, account_id);
++
++  provider = goa_provider_get_for_provider_type (provider_type);
++
++  error = NULL;
++  if (!goa_utils_get_credentials (provider, object, id, NULL, &password, NULL, &error))
++    {
++      g_dbus_method_invocation_take_error (invocation, error);
++      return TRUE; // invocation was handled
++    }
++
++  goa_password_based_complete_get_password (interface, invocation, password);
++
++  return TRUE; // invocation was handled
++}
+Index: gnome-online-accounts-3.35.90/src/goabackend/goaubuntussoprovider.h
+===================================================================
+--- /dev/null
++++ gnome-online-accounts-3.35.90/src/goabackend/goaubuntussoprovider.h
+@@ -0,0 +1,39 @@
++/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
++/*
++ * Copyright © 2018 Canonical Ltd
++ *
++ * Authors: Andrea Azzarone <andrea.azzarone@canonical.com> 
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Lesser General Public
++ * License as published by the Free Software Foundation; either
++ * version 2 of the License, or (at your option) any later version.
++ *
++ * This library is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARCULAR PURPOSE.  See the GNU
++ * Lesser General Public License for more details.
++ *
++ * You should have received a copy of the GNU Lesser General
++ * Public License along with this library; if not, see <http://www.gnu.org/licenses/>.
++ */
++
++#if !defined (__GOA_BACKEND_INSIDE_GOA_BACKEND_H__) && !defined (GOA_BACKEND_COMPILATION)
++#error "Only <goabackend/goabackend.h> can be included directly."
++#endif
++
++#ifndef __GOA_UBUNTU_SSO_PROVIDER_H__
++#define __GOA_UBUNTU_SSO_PROVIDER_H__
++
++#include <glib-object.h>
++
++#include "goaprovider-priv.h"
++
++G_BEGIN_DECLS
++
++#define GOA_TYPE_UBUNTU_SSO_PROVIDER (goa_ubuntu_sso_provider_get_type ())
++G_DECLARE_FINAL_TYPE (GoaUbuntuSSOProvider, goa_ubuntu_sso_provider, GOA, UBUNTU_SSO_PROVIDER, GoaProvider);
++
++G_END_DECLS
++
++#endif /* __GOA_UBUNTU_SSO_PROVIDER_H__ */
diff -pruN 3.44.0-1/debian/patches/0002-livepatch-auth.patch 3.44.0-1ubuntu1/debian/patches/0002-livepatch-auth.patch
--- 3.44.0-1/debian/patches/0002-livepatch-auth.patch	1970-01-01 00:00:00.000000000 +0000
+++ 3.44.0-1ubuntu1/debian/patches/0002-livepatch-auth.patch	2022-03-30 15:35:58.000000000 +0000
@@ -0,0 +1,522 @@
+From: Andrea Azzarone <andrea.azzarone@canonical.com>
+Date: Wed, 28 Feb 2018 08:53:38 +0000
+Subject: Get livepatch authentication token.
+
+Forwarded: not-needed
+Bug: https://bugzilla.gnome.org/show_bug.cgi?id=793755
+Bug-Ubuntu: https://bugs.launchpad.net/bugs/1752472
+---
+ configure.ac                          |   1 +
+ data/Makefile.am                      |   3 +-
+ data/scripts/Makefile.am              |  14 +++
+ data/scripts/lpa_helper.py            | 139 ++++++++++++++++++++++
+ src/goabackend/Makefile.am            |   1 +
+ src/goabackend/goaubuntussoprovider.c | 209 +++++++++++++++++++++++++++++++++-
+ 6 files changed, 362 insertions(+), 5 deletions(-)
+ create mode 100644 data/scripts/Makefile.am
+ create mode 100644 data/scripts/lpa_helper.py
+
+Index: gnome-online-accounts-3.35.90/configure.ac
+===================================================================
+--- gnome-online-accounts-3.35.90.orig/configure.ac
++++ gnome-online-accounts-3.35.90/configure.ac
+@@ -545,6 +545,7 @@ data/Makefile
+ data/icons/Makefile
+ data/icons/scalable/Makefile
+ data/icons/symbolic/Makefile
++data/scripts/Makefile
+ src/Makefile
+ src/goa/Makefile
+ src/goa/goa-1.0.pc
+Index: gnome-online-accounts-3.35.90/data/Makefile.am
+===================================================================
+--- gnome-online-accounts-3.35.90.orig/data/Makefile.am
++++ gnome-online-accounts-3.35.90/data/Makefile.am
+@@ -1,7 +1,7 @@
+ 
+ NULL =
+ 
+-SUBDIRS = icons
++SUBDIRS = icons scripts
+ 
+ gsettings_schema_files = org.gnome.online-accounts.gschema.xml
+ 
+@@ -37,3 +37,4 @@ clean-local :
+ 	rm -f *~
+ 
+ -include $(top_srcdir)/git.mk
++
+Index: gnome-online-accounts-3.35.90/data/scripts/Makefile.am
+===================================================================
+--- /dev/null
++++ gnome-online-accounts-3.35.90/data/scripts/Makefile.am
+@@ -0,0 +1,14 @@
++NULL =
++
++scriptdir = $(datadir)/goa-1.0/scripts/
++script_SCRIPTS =   	\
++	lpa_helper.py		\
++	$(NULL)
++
++EXTRA_DIST = \
++	$(script_SCRIPTS)
++
++clean-local :
++	rm -f *~
++
++-include $(top_srcdir)/git.mk
+\ No newline at end of file
+Index: gnome-online-accounts-3.35.90/data/scripts/lpa_helper.py
+===================================================================
+--- /dev/null
++++ gnome-online-accounts-3.35.90/data/scripts/lpa_helper.py
+@@ -0,0 +1,139 @@
++#!/usr/bin/env python3
++import json
++import os
++import sys
++
++from urllib.parse import urlencode
++import requests  # fades
++import macaroonbakery  # fades
++import pymacaroons  # fades
++from macaroonbakery import httpbakery  # fades
++
++
++LIVEPATCH_AUTH_ROOT_URL = os.environ.get(
++    'LIVEPATCH_AUTH_ROOT_URL', 'https://auth.livepatch.canonical.com')
++UBUNTU_SSO_ROOT_URL = os.environ.get(
++    'UBUNTU_SSO_ROOT_URL', 'https://login.ubuntu.com')
++
++generic_error = "GENERIC_ERROR"
++
++
++class AuthenticationFailed(Exception):
++    def __init__(self, code, msg):
++        super(AuthenticationFailed, self).__init__(msg)
++        self.code = code
++
++class USSOMacaroonInteractor(httpbakery.LegacyInteractor):
++
++    def __init__(self, session):
++        self.session = requests.Session()
++
++    def kind(self):
++        return "interactive"
++
++    def legacy_interact(self, client, location, visit_url):
++        # get usso_macaroon
++        usso_url = self.get_usso_macaroon_url(visit_url)
++        usso_macaroon = self.get_usso_macaroon(usso_url)
++
++        def callback(discharges):
++            self.complete_usso_macaroon_discharge(usso_url, discharges)
++        discharges = self.discharge_usso_macaroon(usso_macaroon, callback)
++
++
++    def get_usso_macaroon_url(self, url):
++        # find interaction methods for discharge
++        response = self.session.get(
++            url, headers={'Accept': 'application/json'})
++        if not response.ok:
++            raise AuthenticationFailed(generic_error, 'can not find interaction methods')
++
++        data = response.json()
++
++        # expect usso_macaroon interaction method
++        if 'usso_macaroon' not in data:
++            raise AuthenticationFailed(generic_error, 'missing usso_macaroon interaction method')
++        return data['usso_macaroon']
++
++    def get_usso_macaroon(self, url):
++        response = self.session.get(url)
++        if not response.ok:
++            raise AuthenticationFailed(generic_error, 'can not get usso macaroon')
++        usso_macaroon = response.json()['macaroon']
++        return usso_macaroon
++
++    def discharge_usso_macaroon(self, macaroon, callback):
++        usso_caveats = [
++            cav['cid'] for cav in macaroon.get('caveats', [])
++            if cav.get('cl') == UBUNTU_SSO_ROOT_URL]
++        if len(usso_caveats) <= 0:
++            raise AuthenticationFailed(generic_error, 'no valid usso caveat found')
++
++        data = {'caveat_id': usso_caveats[0]}
++        data.update(get_usso_credentials())
++
++        def _discharge_macaroon(data):
++            response = self.session.post(
++                '{}/api/v2/tokens/discharge'.format(UBUNTU_SSO_ROOT_URL),
++                data=json.dumps(data),
++                headers={'Content-Type': 'application/json'})
++            return response
++
++        response = _discharge_macaroon(data)
++        if not response.ok:
++            if response.status_code in (400, 401, 403):
++                raise AuthenticationFailed(response.json().get('code'), response.json().get('message'))
++            else:
++                raise AuthenticationFailed(generic_error, 'authentication issue')
++
++        root_m = macaroonbakery.bakery.Macaroon.deserialize_json(
++            json.dumps(macaroon)).macaroon
++        discharge_m = pymacaroons.Macaroon.deserialize(
++            response.json()['discharge_macaroon'])
++        bound_discharge = root_m.prepare_for_request(discharge_m)
++
++        callback([root_m.serialize(), bound_discharge.serialize()])
++
++    def complete_usso_macaroon_discharge(self, url, discharges):
++        data = {'macaroons': discharges}
++        response = self.session.post(
++            url, data=json.dumps(data),
++            headers={'Content-Type': 'application/json'})
++        if not response.ok:
++            raise AuthenticationFailed(generic_error, 'can not complete usso macaroon discharge')
++
++
++def get_usso_credentials():
++    email = input('Email: ')
++    password = input('Password: ')
++    ret = {'email': email, 'password': password}
++    otp = input('Two-factor code: ')
++    if otp and len(otp) > 0:
++        ret.update({'otp': otp})
++    return ret
++
++def get_lpa_token(session):
++    url = '{}/api/v1/tokens?{}'.format(
++        LIVEPATCH_AUTH_ROOT_URL, urlencode({'token_type': 'user'}))
++    return session.get(url, timeout=10)
++
++if __name__ == '__main__':
++    cookies = requests.cookies.RequestsCookieJar()
++    session = requests.Session()
++
++    client = httpbakery.Client(
++        interaction_methods=[USSOMacaroonInteractor(session)], cookies=cookies)
++
++    session.auth = client.auth()
++    session.cookies = cookies
++
++    try:
++        response = get_lpa_token(session)
++        if response.ok:
++            print(response.json()['token'], file=sys.stderr)
++    except AuthenticationFailed as af:
++        print(af.code, af, file=sys.stderr)
++        sys.exit(1)
++    except Exception as e:
++        print(generic_error, e, file=sys.stderr)
++        sys.exit(1)
+Index: gnome-online-accounts-3.35.90/src/goabackend/Makefile.am
+===================================================================
+--- gnome-online-accounts-3.35.90.orig/src/goabackend/Makefile.am
++++ gnome-online-accounts-3.35.90/src/goabackend/Makefile.am
+@@ -12,6 +12,7 @@ AM_CPPFLAGS = 							\
+ 	-DG_LOG_DOMAIN=\"GoaBackend\"				\
+ 	-DGOA_BACKEND_COMPILATION				\
+ 	-DGOA_API_IS_SUBJECT_TO_CHANGE				\
++	-DDATADIR=\""$(datadir)"\"				\
+ 	-DPACKAGE_LIBEXEC_DIR=\""$(libexecdir)"\" 		\
+ 	-DPACKAGE_SYSCONF_DIR=\""$(sysconfdir)"\" 		\
+ 	-DPACKAGE_DATA_DIR=\""$(pkgdatadir)"\" 			\
+Index: gnome-online-accounts-3.35.90/src/goabackend/goaubuntussoprovider.c
+===================================================================
+--- gnome-online-accounts-3.35.90.orig/src/goabackend/goaubuntussoprovider.c
++++ gnome-online-accounts-3.35.90/src/goabackend/goaubuntussoprovider.c
+@@ -20,6 +20,7 @@
+ 
+ #include "config.h"
+ 
++#include <gio/gio.h>
+ #include <glib/gi18n-lib.h>
+ #include <snapd-glib/snapd-glib.h>
+ 
+@@ -69,6 +70,7 @@ typedef struct
+ 
+   gchar  *macaroon;
+   gchar **discharges;
++  gchar  *livepatch_token;
+   gchar  *account_object_path;
+ 
+   GError *error;
+@@ -91,6 +93,7 @@ add_account_data_clear (AddAccountData *
+   g_clear_object (&data->snapd_client);
+   g_free (data->macaroon);
+   g_strfreev (data->discharges);
++  g_free (data->livepatch_token);
+   g_free (data->account_object_path);
+   g_clear_error (&data->error);
+ }
+@@ -196,6 +199,9 @@ ensure_credentials_sync (GoaProvider   *
+   if (!goa_utils_get_credentials (provider, object, "discharges", NULL, &discharges_str, cancellable, error))
+     goto edit_error_and_return;
+ 
++  if (!goa_utils_get_credentials (provider, object, "livepatch", NULL, &discharges_str, cancellable, error))
++    goto edit_error_and_return;
++
+   if (discharges_str)
+     discharges_var = g_variant_parse (G_VARIANT_TYPE ("as"), discharges_str, NULL, NULL, NULL);
+   if (discharges_var)
+@@ -467,7 +473,6 @@ create_account_details_ui (GoaProvider
+ 
+   row = 0;
+   add_entry (grid2, row++, _("Passc_ode:"), &data->otp_entry);
+-
+   g_signal_connect (data->otp_entry, "changed", G_CALLBACK (on_otp_changed), data);
+ 
+   gtk_dialog_add_button (data->dialog, _("_Cancel"), GTK_RESPONSE_CANCEL);
+@@ -535,8 +540,8 @@ get_snapd_error_message (GError *error)
+ {
+   g_return_val_if_fail (error != NULL, NULL);
+ 
+-  g_debug ("Error logging in snapd: %s (%s, %d)",
+-           error->message, g_quark_to_string (error->domain), error->code);
++  g_warning ("Error logging in snapd: %s (%s, %d)",
++             error->message, g_quark_to_string (error->domain), error->code);
+ 
+   if (g_error_matches (error, SNAPD_ERROR, SNAPD_ERROR_AUTH_DATA_REQUIRED))
+     return _("Provided email/password is not correct");
+@@ -546,6 +551,31 @@ get_snapd_error_message (GError *error)
+     return _("Something went wrong, please try again");
+ }
+ 
++static GError*
++get_error_from_livepatch_message (const gchar *message)
++{
++  gint code;
++  g_auto(GStrv) v = NULL;
++
++  g_return_val_if_fail (message != NULL, NULL);
++
++  v = g_strsplit (message, " ", 2);
++
++  if (!g_strcmp0 (v[0], "INVALID_CREDENTIALS"))
++    code = SNAPD_ERROR_AUTH_DATA_REQUIRED;
++  else if (!g_strcmp0 (v[0], "TWOFACTOR_REQUIRED"))
++    code = SNAPD_ERROR_TWO_FACTOR_REQUIRED;
++  else if (!g_strcmp0 (v[0], "TWOFACTOR_FAILURE"))
++    code = SNAPD_ERROR_TWO_FACTOR_INVALID;
++  else
++    code = SNAPD_ERROR_FAILED;
++
++  if (g_strv_length (v) <= 1)
++    return g_error_new (SNAPD_ERROR, code, "%s", v[0]);
++  else
++    return g_error_new (SNAPD_ERROR, code, "%s", v[1]);
++}
++
+ static void
+ dialog_response_cb (GtkDialog *dialog,
+                     gint response_id,
+@@ -580,6 +610,120 @@ snapd_login_ready_cb (GObject *object,
+ }
+ 
+ static void
++subprocess_wait_cb (GObject      *object,
++                    GAsyncResult *res,
++                    gpointer      user_data)
++{
++  GSubprocess *subprocess = (GSubprocess *)object;
++  g_autoptr(GTask) task = user_data;
++  gint exit_status;
++  g_autoptr(GDataInputStream) data_input = NULL;
++  GInputStream *istream = NULL;
++  g_autofree gchar *message = NULL;
++  GError *error = NULL;
++
++  g_return_if_fail (G_IS_SUBPROCESS (subprocess));
++  g_return_if_fail (G_IS_TASK (task));
++
++  if (!g_subprocess_wait_finish (subprocess, res, &error))
++    {
++      g_task_return_error (task, error);
++      return;
++    }
++
++  exit_status = g_subprocess_get_exit_status (subprocess);
++  istream = g_subprocess_get_stderr_pipe (subprocess);
++  data_input = g_data_input_stream_new (istream);
++  message = g_data_input_stream_read_line (data_input,
++                                           NULL, g_task_get_cancellable (task),
++                                           &error);
++
++  if (message == NULL)
++    g_task_return_error (task, error);
++  else if (exit_status == 0)
++    g_task_return_pointer (task, g_strdup (message), g_free);
++  else if (exit_status == 1)
++    // Use snapd-glib errors in order to simplify the login logic
++    g_task_return_error (task, get_error_from_livepatch_message (message));
++}
++
++static void
++livepatch_login_async (const gchar *email,
++                       const gchar *password,
++                       const gchar *otp,
++                       GCancellable *cancellable,
++                       GAsyncReadyCallback callback,
++                       gpointer user_data)
++{
++  AddAccountData *data = user_data;
++  g_autoptr(GSubprocess) process = NULL;
++  g_autoptr(GTask) task = NULL;
++  GSubprocessFlags flags;
++  GError *error = NULL;
++
++  g_return_if_fail (email != NULL && password != NULL);
++  g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
++
++  task = g_task_new (NULL, cancellable, callback, data);
++
++  flags = G_SUBPROCESS_FLAGS_STDOUT_SILENCE |
++          G_SUBPROCESS_FLAGS_STDIN_PIPE |
++          G_SUBPROCESS_FLAGS_STDERR_PIPE;
++
++    process = g_subprocess_new (flags, &error, DATADIR"/goa-1.0/scripts/lpa_helper.py" , NULL);
++
++  if (process)
++    {
++      GOutputStream *ostream = g_subprocess_get_stdin_pipe (process);
++
++      g_output_stream_printf (ostream, NULL, cancellable, &error,
++                              "%s\n%s\n", email, password);
++
++      if (error)
++        goto out;
++
++      if (otp)
++        g_output_stream_printf (ostream, NULL, cancellable, &error,
++                                "%s\n", otp);
++      else
++        g_output_stream_printf (ostream, NULL, cancellable, &error,
++                                "\n");
++
++      if (error)
++        goto out;
++
++      g_subprocess_wait_async (process,
++                               cancellable,
++                               subprocess_wait_cb,
++                               g_object_ref (task));
++    }
++
++out:
++  if (error)
++    {
++      g_task_return_error (task, error);
++      g_subprocess_force_exit (process);
++    }
++}
++
++static void
++livepatch_login_ready_cb (GObject *object,
++                          GAsyncResult *result,
++                          gpointer user_data)
++{
++  AddAccountData *data = user_data;
++  g_autofree gchar *token = NULL;
++
++  token = g_task_propagate_pointer (G_TASK (result), &data->error);
++  if (token != NULL)
++    data->livepatch_token = g_strdup (token);
++
++  update_widgets (data);
++  show_progress_ui (GTK_CONTAINER (data->progress_grid), FALSE);
++  g_main_loop_quit (data->loop);
++}
++
++static void
+ add_account_cb (GoaManager *manager,
+                 GAsyncResult *res,
+                 gpointer user_data)
+@@ -603,8 +747,8 @@ add_credentials_key_values (GVariantBuil
+   discharges_var = g_variant_new_strv ((const gchar * const*) data->discharges, -1);
+   discharges_str = g_variant_print (discharges_var, FALSE);
+   g_variant_builder_add (builder, "{sv}", "discharges", g_variant_new_string (discharges_str));
++  g_variant_builder_add (builder, "{sv}", "livepatch", g_variant_new_string (data->livepatch_token));
+ }
+-
+ static gboolean
+ get_tokens_and_identity (GoaProvider    *provider,
+                          gboolean        add_account,
+@@ -618,6 +762,7 @@ get_tokens_and_identity (GoaProvider
+   const gchar *username;
+   const gchar *otp;
+   gint response;
++  gboolean first_lp_attemp = TRUE;
+ 
+   g_return_val_if_fail (GOA_IS_UBUNTU_SSO_PROVIDER (provider), FALSE);
+   g_return_val_if_fail ((!add_account && existing_identity != NULL && existing_identity[0] != '\0')
+@@ -662,6 +807,9 @@ get_tokens_and_identity (GoaProvider
+   otp = gtk_entry_get_text (GTK_ENTRY (data->otp_entry));
+   otp = otp && strlen (otp) > 0 ? otp : NULL;
+ 
++  if (data->macaroon != NULL)
++    goto livepath_login;
++
+   g_clear_object (&data->cancellable);
+   data->cancellable = g_cancellable_new ();
+ 
+@@ -722,6 +870,59 @@ get_tokens_and_identity (GoaProvider
+       goto login_again;
+     }
+ 
++  // Try to get the livepatch authentication token.
++ livepath_login:
++  g_clear_object (&data->cancellable);
++  data->cancellable = g_cancellable_new ();
++
++  gtk_widget_set_sensitive (data->connect_button, FALSE);
++  show_progress_ui (GTK_CONTAINER (data->progress_grid), TRUE);
++  livepatch_login_async (username, password, otp,
++                         data->cancellable, livepatch_login_ready_cb, data);
++  g_main_loop_run (data->loop);
++
++  if (g_cancellable_is_cancelled (data->cancellable))
++    {
++      g_prefix_error (&data->error,
++                      _("Dialog was dismissed (%s, %d): "),
++                      g_quark_to_string (data->error->domain),
++                      data->error->code);
++      data->error->domain = GOA_ERROR;
++      data->error->code = GOA_ERROR_DIALOG_DISMISSED;
++      goto out;
++    }
++  else if (data->error != NULL)
++    {
++      g_autofree gchar *markup = NULL;
++      if (first_lp_attemp == TRUE && data->error->code == SNAPD_ERROR_TWO_FACTOR_INVALID)
++        {
++          markup = g_strdup_printf ("<b>%s</b>", _("This account requires a second passcode from your authentication device or app"));
++          gtk_label_set_markup (GTK_LABEL (data->cluebar_label), markup);
++          gtk_info_bar_set_message_type (GTK_INFO_BAR (data->cluebar), GTK_MESSAGE_INFO);
++          gtk_widget_set_no_show_all (data->cluebar, FALSE);
++          gtk_widget_show_all (data->cluebar);
++          gtk_button_set_label (GTK_BUTTON (data->connect_button), _("C_onnect"));
++          gtk_entry_set_text (GTK_ENTRY (data->otp_entry), "");
++          gtk_widget_grab_focus (data->otp_entry);
++        }
++      else
++        {
++          markup = g_strdup_printf ("<b>%s:</b>\n%s",
++                                    _("Error connecting to Ubuntu Single Sign-On server"),
++                                    get_snapd_error_message (data->error));
++          gtk_info_bar_set_message_type (GTK_INFO_BAR (data->cluebar), GTK_MESSAGE_ERROR);
++          gtk_button_set_label (GTK_BUTTON (data->connect_button), _("_Try Again"));
++        }
++
++      g_clear_error (&data->error);
++      gtk_label_set_markup (GTK_LABEL (data->cluebar_label), markup);
++      gtk_widget_set_no_show_all (data->cluebar, FALSE);
++      gtk_widget_show_all (data->cluebar);
++
++      first_lp_attemp = FALSE;
++      goto login_again;
++    }
++
+   gtk_widget_hide (GTK_WIDGET (dialog));
+ 
+   ret = TRUE;
diff -pruN 3.44.0-1/debian/patches/series 3.44.0-1ubuntu1/debian/patches/series
--- 3.44.0-1/debian/patches/series	2022-03-30 15:32:11.000000000 +0000
+++ 3.44.0-1ubuntu1/debian/patches/series	2022-03-30 15:35:58.000000000 +0000
@@ -0,0 +1,2 @@
+0001-ubuntu-sso-provider.patch
+0002-livepatch-auth.patch
diff -pruN 3.44.0-1/debian/rules 3.44.0-1ubuntu1/debian/rules
--- 3.44.0-1/debian/rules	2022-03-30 15:32:11.000000000 +0000
+++ 3.44.0-1ubuntu1/debian/rules	2022-03-30 15:35:58.000000000 +0000
@@ -25,15 +25,17 @@ override_dh_auto_configure:
 		--enable-gtk-doc \
 		--enable-kerberos \
 		--disable-media-server \
-		--enable-facebook \
+		--disable-facebook \
 		--enable-flickr \
 		--disable-fedora \
+		--disable-lastfm \
 		--enable-windows-live \
 		--enable-google \
 		--enable-owncloud \
 		--enable-imap-smtp \
 		--enable-exchange \
 		--enable-foursquare \
+		--enable-ubuntu-sso \
 		$(DISABLE_BACKEND)
 
 execute_before_dh_install:
@@ -43,6 +45,16 @@ execute_before_dh_install:
 override_dh_makeshlibs:
 	dh_makeshlibs -- -c4
 
+override_dh_translations:
+	mv po/gnome-online-accounts.pot po/gnome-online-accounts.pot.bak
+	dh_translations
+
+override_dh_clean:
+	if [ -f po/gnome-online-accounts.pot.bak ]; then \
+		mv po/gnome-online-accounts.pot.bak po/gnome-online-accounts.pot; \
+	fi
+	dh_clean
+
 override_dh_builddeb:
 	dh_builddeb ${skip_packages}
 
