Merge lp:~dobey/ubuntuone-credentials/update-13-10 into lp:ubuntuone-credentials/stable-13-10
- update-13-10
- Merge into stable-13-10
| Status: | Merged |
|---|---|
| Approved by: | dobey on 2013-08-28 |
| Approved revision: | no longer in the source branch. |
| Merged at revision: | 29 |
| Proposed branch: | lp:~dobey/ubuntuone-credentials/update-13-10 |
| Merge into: | lp:ubuntuone-credentials/stable-13-10 |
| Diff against target: |
2484 lines (+1661/-146) 46 files modified
.bzrignore (+1/-0) CMakeLists.txt (+19/-0) data/CMakeLists.txt (+7/-0) data/ubuntuone.provider (+14/-0) data/ubuntuone.service (+8/-0) data/ubuntuone.service-type (+7/-0) libubuntuoneauth/CMakeLists.txt (+2/-4) libubuntuoneauth/identityprovider.cpp (+11/-4) libubuntuoneauth/identityprovider.h (+1/-0) libubuntuoneauth/keyring.cpp (+147/-87) libubuntuoneauth/keyring.h (+12/-0) libubuntuoneauth/libubuntuoneauth.symbols (+9/-0) libubuntuoneauth/logging.cpp (+17/-1) libubuntuoneauth/network.cpp (+20/-12) libubuntuoneauth/network.h (+0/-2) libubuntuoneauth/requests.cpp (+24/-1) libubuntuoneauth/requests.h (+16/-4) libubuntuoneauth/ssoservice.cpp (+21/-10) libubuntuoneauth/ssoservice.h (+5/-3) libubuntuoneauth/token.h (+1/-1) music-login/CMakeLists.txt (+2/-2) music-login/loginform.cpp (+15/-4) music-login/registerform.cpp (+2/-1) music-login/ssowizard.cpp (+12/-3) music-login/ssowizard.h (+2/-1) music-login/tests/CMakeLists.txt (+2/-2) music-login/tests/testloginform.cpp (+26/-2) music-login/tests/testloginform.h (+4/-2) online-accounts-provider/CMakeLists.txt (+6/-0) online-accounts-provider/ExistingAccount.qml (+95/-0) online-accounts-provider/LoginForm.qml (+100/-0) online-accounts-provider/Main.qml (+50/-0) online-accounts-provider/NewAccount.qml (+257/-0) online-accounts-provider/RegisterForm.qml (+97/-0) qml-credentials-service/CMakeLists.txt (+25/-0) qml-credentials-service/README (+31/-0) qml-credentials-service/examples/embeddingMain.qml (+129/-0) qml-credentials-service/qmldir.template (+3/-0) qml-credentials-service/ubuntuone_credentials_plugin.cpp (+11/-0) qml-credentials-service/ubuntuone_credentials_plugin.h (+16/-0) qml-credentials-service/ubuntuone_credentials_service.cpp (+157/-0) qml-credentials-service/ubuntuone_credentials_service.h (+62/-0) signon-plugin/CMakeLists.txt (+37/-0) signon-plugin/ubuntuone-plugin.cpp (+80/-0) signon-plugin/ubuntuone-plugin.h (+56/-0) signon-plugin/ubuntuonedata.h (+42/-0) |
| To merge this branch: | bzr merge lp:~dobey/ubuntuone-credentials/update-13-10 |
| Related bugs: |
| Reviewer | Review Type | Date Requested | Status |
|---|---|---|---|
| Roberto Alsina (community) | 2013-08-27 | Approve on 2013-08-28 | |
|
Review via email:
|
|||
Commit Message
Rodney Dawes <email address hidden>
Switch from using using the keyring, to storing tokens in online-accounts.
Add necessary data files for online-accounts storage.
Add the beginnings of a signon plugin for u1.
Always print critical/fatal messages to stderr.
When debug is enabled, also print debug messages to stderr.
Add ctors for network requests to use the SSO_AUTH_BASE_URL value.
Change usage of SSO_*_BASE_URL values to not require ending /.
Restructure API URL constants to separate path from base URL.
Only export the UbuntuOne namespace symbols in the shared library.
Michael McCracken <email address hidden>
Add UOA provider plug-in to house login/register UI.
Ensure initial value of _state variable is IDLE.
Set signon plugin name to 'ubuntuoneplugin' as required by the signond plugin loader.
Add cmake rule to generate qmltypes file for qtcreator integration.
Validate input and show error messages for invalid email, short password, etc…
Fix credential deletion and expose it via QML plugin.
Improve UI, better support embedding into external QML, and add embedding example code.
Add error signal for failure cases in Network class - covers connection failures.
Add support for two-factor auth to the ssoservice and QML plugin (LP: #1197081)
Add QML plugin that wraps login/register and signUrl functionality of libubuntuoneauth.
Diego Sarmentero <email address hidden>
Fix UI flow requested by design for Returning Customers.
Description of the Change
| Ubuntu One Auto Pilot (otto-pilot) wrote : | # |
The attempt to merge lp:~dobey/ubuntuone-credentials/update-13-10 into lp:ubuntuone-credentials/stable-13-10 failed. Below is the output from the failed tests.
-- The C compiler identification is GNU 4.8.1
-- The CXX compiler identification is GNU 4.8.1
-- Check for working C compiler: /usr/bin/cc
-- Check for working C compiler: /usr/bin/cc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working CXX compiler: /usr/bin/c++
-- Check for working CXX compiler: /usr/bin/c++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Found PkgConfig: /usr/bin/pkg-config (found version "0.26")
-- checking for modules 'libsignon-
-- package 'libsignon-qt5' not found
-- package 'accounts-qt5' not found
-- Configuring incomplete, errors occurred!
CMake Error at /usr/share/
A required package was not found
Call Stack (most recent call first):
/usr/
CMakeLists.txt:28 (pkg_check_modules)
CMake Error at libubuntuoneaut
By not providing "FindQt5Core.cmake" in CMAKE_MODULE_PATH this project has
asked CMake to find a package configuration file provided by "Qt5Core", but
CMake did not find one.
Could not find a package configuration file provided by "Qt5Core" with any
of the following names:
Qt5CoreConf
qt5core-
Add the installation prefix of "Qt5Core" to CMAKE_PREFIX_PATH or set
"Qt5Core_DIR" to a directory containing one of the above files. If
"Qt5Core" provides a separate development package or SDK, be sure it has
been installed.
- 29. By Mike McCracken on 2013-08-28
-
Rodney Dawes <email address hidden>
Switch from using using the keyring, to storing tokens in online-accounts.
Add necessary data files for online-accounts storage.
Add the beginnings of a signon plugin for u1.
Always print critical/fatal messages to stderr.
When debug is enabled, also print debug messages to stderr.
Add ctors for network requests to use the SSO_AUTH_BASE_URL value.
Change usage of SSO_*_BASE_URL values to not require ending /.
Restructure API URL constants to separate path from base URL.
Only export the UbuntuOne namespace symbols in the shared library.Michael McCracken <email address hidden>
Add UOA provider plug-in to house login/register UI.
Ensure initial value of _state variable is IDLE.
Set signon plugin name to 'ubuntuoneplugin' as required by the signond plugin loader.
Add cmake rule to generate qmltypes file for qtcreator integration.
Validate input and show error messages for invalid email, short password, etc…
Fix credential deletion and expose it via QML plugin.
Improve UI, better support embedding into external QML, and add embedding example code.
Add error signal for failure cases in Network class - covers connection failures.
Add support for two-factor auth to the ssoservice and QML plugin (LP: #1197081)
Add QML plugin that wraps login/register and signUrl functionality of libubuntuoneauth.Diego Sarmentero <email address hidden>
Fix UI flow requested by design for Returning Customers.
Preview Diff
| 1 | === modified file '.bzrignore' |
| 2 | --- .bzrignore 2013-05-01 15:39:22 +0000 |
| 3 | +++ .bzrignore 2013-08-27 20:30:52 +0000 |
| 4 | @@ -10,6 +10,7 @@ |
| 5 | test-ubuntuoneauthui |
| 6 | ubuntuone-music-login |
| 7 | moc_*.cpp |
| 8 | +qmldir |
| 9 | ui_*.h |
| 10 | *_automoc.cpp |
| 11 | *_resources.cpp |
| 12 | |
| 13 | === modified file 'CMakeLists.txt' |
| 14 | --- CMakeLists.txt 2013-07-08 14:34:25 +0000 |
| 15 | +++ CMakeLists.txt 2013-08-27 20:30:52 +0000 |
| 16 | @@ -15,6 +15,19 @@ |
| 17 | SET (AUTHUI_LIB_API_VERSION 2.0) |
| 18 | SET (AUTHUI_LIB_NAME ubuntuoneauthui-${AUTHUI_LIB_API_VERSION}) |
| 19 | |
| 20 | +# these names are also used in qml-credentials-service/qmldir, be sure to change them in both places |
| 21 | +SET (QML_MODULE_NAME UbuntuOne) |
| 22 | +SET (QML_PLUGIN_API_VERSION 1.0) |
| 23 | +SET (QML_PLUGIN_NAME UbuntuOneCredentialsPlugin-${QML_PLUGIN_API_VERSION}) |
| 24 | + |
| 25 | +# For the signon plug-in module |
| 26 | +SET (SIGNON_PLUGIN_NAME ubuntuoneplugin) |
| 27 | + |
| 28 | +# Need to get libsignon/accounts here, as they get exposed in headers |
| 29 | +find_package (PkgConfig REQUIRED) |
| 30 | +pkg_check_modules(LIBSIGNON REQUIRED libsignon-qt5 accounts-qt5) |
| 31 | +add_definitions(${LIBSIGNON_CFLAGS} ${LIBSIGNON_CFLAGS_OTHER}) |
| 32 | + |
| 33 | # Some default CFLAGS |
| 34 | SET (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O2 -g -Wall -Werror -fPIC") |
| 35 | SET (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x -O2 -g -Wall -Werror -fPIC") |
| 36 | @@ -23,6 +36,8 @@ |
| 37 | SET (LIB_SUFFIX "" CACHE STRING "Define suffix of library directory name.") |
| 38 | SET (LIB_INSTALL_DIR "lib${LIB_SUFFIX}") |
| 39 | |
| 40 | +set (QML_MODULE_INSTALL_DIR ${LIB_INSTALL_DIR}/qt5/qml ) |
| 41 | + |
| 42 | include_directories(${CMAKE_SOURCE_DIR}/libubuntuoneauth |
| 43 | ${CMAKE_SOURCE_DIR}/libubuntuoneauthui) |
| 44 | |
| 45 | @@ -35,9 +50,13 @@ |
| 46 | WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}) |
| 47 | |
| 48 | |
| 49 | +add_subdirectory(data) |
| 50 | add_subdirectory(libubuntuoneauth) |
| 51 | add_subdirectory(libubuntuoneauthui) |
| 52 | add_subdirectory(music-login) |
| 53 | +add_subdirectory(signon-plugin) |
| 54 | +add_subdirectory(qml-credentials-service) |
| 55 | +add_subdirectory(online-accounts-provider) |
| 56 | |
| 57 | # We need to add these here which simply depend on other test rules, as |
| 58 | # CMake doesn't allow defining a "check" rule in multiple places. |
| 59 | |
| 60 | === added directory 'data' |
| 61 | === added file 'data/CMakeLists.txt' |
| 62 | --- data/CMakeLists.txt 1970-01-01 00:00:00 +0000 |
| 63 | +++ data/CMakeLists.txt 2013-08-27 20:30:52 +0000 |
| 64 | @@ -0,0 +1,7 @@ |
| 65 | +file (GLOB PROVIDER_FILES *.provider) |
| 66 | +file (GLOB SERVICE_FILES *.service) |
| 67 | +file (GLOB SERVICE_TYPE_FILES *.service-type) |
| 68 | + |
| 69 | +install (FILES ${PROVIDER_FILES} DESTINATION share/accounts/providers/) |
| 70 | +install (FILES ${SERVICE_FILES} DESTINATION share/accounts/services/) |
| 71 | +install (FILES ${SERVICE_TYPE_FILES} DESTINATION share/accounts/service_types/) |
| 72 | |
| 73 | === added file 'data/ubuntuone.provider' |
| 74 | --- data/ubuntuone.provider 1970-01-01 00:00:00 +0000 |
| 75 | +++ data/ubuntuone.provider 2013-08-27 20:30:52 +0000 |
| 76 | @@ -0,0 +1,14 @@ |
| 77 | +<?xml version="1.0" encoding="UTF-8"?> |
| 78 | +<provider id="ubuntuone"> |
| 79 | + <name>Ubuntu One</name> |
| 80 | + <icon>ubuntuone</icon> |
| 81 | + <plugin>ubuntuone</plugin> |
| 82 | + <translations>ubuntuone-credentials</translations> |
| 83 | + |
| 84 | + <template> |
| 85 | + <group name="auth"> |
| 86 | + <setting name="method">password</setting> |
| 87 | + <setting name="mechanism">password</setting> |
| 88 | + </group> |
| 89 | + </template> |
| 90 | +</provider> |
| 91 | |
| 92 | === added file 'data/ubuntuone.service' |
| 93 | --- data/ubuntuone.service 1970-01-01 00:00:00 +0000 |
| 94 | +++ data/ubuntuone.service 2013-08-27 20:30:52 +0000 |
| 95 | @@ -0,0 +1,8 @@ |
| 96 | +<?xml version="1.0" encoding="UTF-8"?> |
| 97 | +<service id="ubuntuone"> |
| 98 | + <type>ubuntuone</type> |
| 99 | + <name>Ubuntu One</name> |
| 100 | + <icon>ubuntuone</icon> |
| 101 | + <provider>ubuntuone</provider> |
| 102 | + |
| 103 | +</service> |
| 104 | |
| 105 | === added file 'data/ubuntuone.service-type' |
| 106 | --- data/ubuntuone.service-type 1970-01-01 00:00:00 +0000 |
| 107 | +++ data/ubuntuone.service-type 2013-08-27 20:30:52 +0000 |
| 108 | @@ -0,0 +1,7 @@ |
| 109 | +<?xml version="1.0" encoding="UTF-8"?> |
| 110 | +<service-type id="ubuntuone"> |
| 111 | + <name>Ubuntu One</name> |
| 112 | + <description>Integrate with Ubuntu One</description> |
| 113 | + <icon>ubuntuone</icon> |
| 114 | + <translations>ubuntuone-credentials</translations> |
| 115 | +</service-type> |
| 116 | |
| 117 | === modified file 'libubuntuoneauth/CMakeLists.txt' |
| 118 | --- libubuntuoneauth/CMakeLists.txt 2013-06-14 22:30:19 +0000 |
| 119 | +++ libubuntuoneauth/CMakeLists.txt 2013-08-27 20:30:52 +0000 |
| 120 | @@ -18,10 +18,7 @@ |
| 121 | # HEADERS only includes the public headers for installation. |
| 122 | FILE (GLOB HEADERS *.h) |
| 123 | |
| 124 | -find_package (PkgConfig REQUIRED) |
| 125 | -pkg_check_modules(LIBSECRET REQUIRED libsecret-1) |
| 126 | pkg_check_modules(OAUTH REQUIRED oauth) |
| 127 | -add_definitions(${LIBSECRET_CFLAGS} ${LIBSECRET_CFLAGS_OTHER}) |
| 128 | add_definitions(${OAUTH_CFLAGS} ${OAUTH_CFLAGS_OTHER}) |
| 129 | |
| 130 | # Need the project version here |
| 131 | @@ -30,8 +27,9 @@ |
| 132 | add_library (${AUTH_LIB_NAME} ${LIB_TYPE} ${SOURCES}) |
| 133 | qt5_use_modules (${AUTH_LIB_NAME} Core DBus Xml Network) |
| 134 | target_link_libraries (${AUTH_LIB_NAME} |
| 135 | - ${LIBSECRET_LDFLAGS} |
| 136 | + ${LIBSIGNON_LDFLAGS} |
| 137 | ${OAUTH_LDFLAGS} |
| 138 | + -Wl,--version-script -Wl,${CMAKE_CURRENT_SOURCE_DIR}/libubuntuoneauth.symbols |
| 139 | ) |
| 140 | |
| 141 | SET_TARGET_PROPERTIES(${AUTH_LIB_NAME} PROPERTIES |
| 142 | |
| 143 | === modified file 'libubuntuoneauth/identityprovider.cpp' |
| 144 | --- libubuntuoneauth/identityprovider.cpp 2013-06-20 19:17:09 +0000 |
| 145 | +++ libubuntuoneauth/identityprovider.cpp 2013-08-27 20:30:52 +0000 |
| 146 | @@ -19,6 +19,7 @@ |
| 147 | |
| 148 | #include "identityprovider.h" |
| 149 | #include "responses.h" |
| 150 | +#include "errormessages.h" |
| 151 | |
| 152 | |
| 153 | namespace UbuntuOne { |
| 154 | @@ -81,10 +82,16 @@ |
| 155 | |
| 156 | void IdentityProvider::OnErrorOccurred(const ErrorResponse& error) |
| 157 | { |
| 158 | - qWarning("Error occurred creating account: %d (%s)", |
| 159 | - error.code(), error.message().toUtf8().data()); |
| 160 | - |
| 161 | - emit ErrorOccurred(error); |
| 162 | + if (error.code() == CODE_TWOFACTOR_REQUIRED){ |
| 163 | + emit TwoFactorAuthRequired(); |
| 164 | + |
| 165 | + }else{ |
| 166 | + |
| 167 | + qWarning("Error occurred creating token: %d (%s)", |
| 168 | + error.code(), error.message().toUtf8().data()); |
| 169 | + |
| 170 | + emit ErrorOccurred(error); |
| 171 | + } |
| 172 | |
| 173 | } |
| 174 | |
| 175 | |
| 176 | === modified file 'libubuntuoneauth/identityprovider.h' |
| 177 | --- libubuntuoneauth/identityprovider.h 2013-06-14 22:39:59 +0000 |
| 178 | +++ libubuntuoneauth/identityprovider.h 2013-08-27 20:30:52 +0000 |
| 179 | @@ -42,6 +42,7 @@ |
| 180 | void PasswordTokenGranted(const PasswordTokenResponse& token); |
| 181 | void AccountGranted(const AccountResponse& account); |
| 182 | void ErrorOccurred(const ErrorResponse& error); |
| 183 | + void TwoFactorAuthRequired(); |
| 184 | |
| 185 | public slots: |
| 186 | void OnOAuthTokenGranted(const OAuthTokenResponse& token); |
| 187 | |
| 188 | === modified file 'libubuntuoneauth/keyring.cpp' |
| 189 | --- libubuntuoneauth/keyring.cpp 2013-06-20 19:17:09 +0000 |
| 190 | +++ libubuntuoneauth/keyring.cpp 2013-08-27 20:30:52 +0000 |
| 191 | @@ -15,122 +15,182 @@ |
| 192 | * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, |
| 193 | * Boston, MA 02110-1301, USA. |
| 194 | */ |
| 195 | -#include <libsecret/secret.h> |
| 196 | +#include <Accounts/Account> |
| 197 | +#include <Accounts/AccountService> |
| 198 | +#include <Accounts/Service> |
| 199 | +#include <Accounts/ServiceType> |
| 200 | +#include <SignOn/Identity> |
| 201 | |
| 202 | #include <QDebug> |
| 203 | |
| 204 | #include "keyring.h" |
| 205 | |
| 206 | -#define TOKEN_KEY_TYPE "Ubuntu SSO credentials" |
| 207 | -#define TOKEN_ATTR_TYPE_KEY "key-type" |
| 208 | -#define TOKEN_ATTR_NAME_KEY "token-name" |
| 209 | +using namespace Accounts; |
| 210 | +using namespace SignOn; |
| 211 | + |
| 212 | |
| 213 | namespace UbuntuOne { |
| 214 | |
| 215 | Keyring::Keyring(QObject *parent) |
| 216 | - : QObject(parent) |
| 217 | - { |
| 218 | - } |
| 219 | - |
| 220 | - static const SecretSchema *_getTokenSchema() |
| 221 | - { |
| 222 | - static const SecretSchema schema = { |
| 223 | - "com.ubuntu.one.Token", SECRET_SCHEMA_DONT_MATCH_NAME, |
| 224 | - { |
| 225 | - { TOKEN_ATTR_TYPE_KEY, SECRET_SCHEMA_ATTRIBUTE_STRING }, |
| 226 | - { TOKEN_ATTR_NAME_KEY, SECRET_SCHEMA_ATTRIBUTE_STRING }, |
| 227 | - } |
| 228 | - }; |
| 229 | - |
| 230 | - return &schema; |
| 231 | - } |
| 232 | - |
| 233 | - static void _onPasswordLookup(GObject *source, GAsyncResult *result, |
| 234 | - Keyring *keyring) |
| 235 | - { |
| 236 | - GError *error = NULL; |
| 237 | - |
| 238 | - gchar *password = secret_password_lookup_finish(result, &error); |
| 239 | - |
| 240 | - if (error != NULL) { |
| 241 | - QString message(error->message); |
| 242 | - qCritical() << "Error in secret_password_lookup: " << message; |
| 243 | - emit keyring->keyringError(message); |
| 244 | - g_error_free(error); |
| 245 | - } else if (password == NULL) { |
| 246 | - emit keyring->tokenNotFound(); |
| 247 | + : QObject(parent), |
| 248 | + _manager() |
| 249 | + { |
| 250 | + } |
| 251 | + |
| 252 | + void Keyring::handleError(const SignOn::Error &error) |
| 253 | + { |
| 254 | + qCritical() << "Error:" << error.message(); |
| 255 | + emit keyringError(error.message()); |
| 256 | + } |
| 257 | + |
| 258 | + void Keyring::handleSessionData(const SignOn::SessionData &data) |
| 259 | + { |
| 260 | + QString secret = data.Secret(); |
| 261 | + |
| 262 | + if (secret.length() == 0) { |
| 263 | + QString msg("Could not read credentials secret value."); |
| 264 | + qCritical() << msg; |
| 265 | + emit keyringError(msg); |
| 266 | + return; |
| 267 | + } |
| 268 | + |
| 269 | + Token *token = Token::fromQuery(secret); |
| 270 | + if (token->isValid()) { |
| 271 | + emit tokenFound(*token); |
| 272 | } else { |
| 273 | - QString query(password); |
| 274 | - Token *token = Token::fromQuery(query); |
| 275 | - if (token->isValid()) { |
| 276 | - emit keyring->tokenFound(*token); |
| 277 | - } else { |
| 278 | - QString message("Faild to convert result to Token object."); |
| 279 | - qCritical() << message; |
| 280 | - emit keyring->keyringError(message); |
| 281 | - } |
| 282 | - delete token; |
| 283 | - secret_password_free(password); |
| 284 | + QString message("Failed to convert result to Token object."); |
| 285 | + qCritical() << message; |
| 286 | + emit keyringError(message); |
| 287 | } |
| 288 | + delete token; |
| 289 | } |
| 290 | |
| 291 | void Keyring::findToken() |
| 292 | { |
| 293 | - secret_password_lookup(_getTokenSchema(), NULL, |
| 294 | - (GAsyncReadyCallback)_onPasswordLookup, this, |
| 295 | - TOKEN_ATTR_TYPE_KEY, TOKEN_KEY_TYPE, |
| 296 | - TOKEN_ATTR_NAME_KEY, Token::buildTokenName().toUtf8().data(), |
| 297 | - NULL); |
| 298 | + QString _acctName("ubuntuone"); |
| 299 | + AccountIdList _ids = _manager.accountList(_acctName); |
| 300 | + Identity *identity; |
| 301 | + Account *account; |
| 302 | + |
| 303 | + if (_ids.length() > 0) { |
| 304 | + if (_ids.length() > 1) { |
| 305 | + qDebug() << "findToken(): Found '" << _ids.length() << "' accounts. Using first."; |
| 306 | + } |
| 307 | + account = _manager.account(_ids[0]); |
| 308 | + qDebug() << "findToken(): Using Ubuntu One account '" << _ids[0] << "'."; |
| 309 | + identity = Identity::existingIdentity(account->credentialsId()); |
| 310 | + AuthSession *session = identity->createSession(QStringLiteral("password")); |
| 311 | + if (session != NULL) { |
| 312 | + connect(session, SIGNAL(response(const SignOn::SessionData&)), |
| 313 | + this, SLOT(handleSessionData(const SignOn::SessionData&))); |
| 314 | + connect(session, SIGNAL(error(const SignOn::Error&)), |
| 315 | + this, SLOT(handleError(const SignOn::Error&))); |
| 316 | + session->process(SessionData(), QStringLiteral("password")); |
| 317 | + return; |
| 318 | + } |
| 319 | + qCritical() << "Unable to create AuthSession."; |
| 320 | + } |
| 321 | + emit tokenNotFound(); |
| 322 | } |
| 323 | |
| 324 | - static void _onPasswordStored(GObject *source, GAsyncResult *result, |
| 325 | - Keyring *keyring) |
| 326 | + void Keyring::handleCredentialsStored(const quint32 id) |
| 327 | { |
| 328 | - GError *error = NULL; |
| 329 | - |
| 330 | - secret_password_store_finish (result, &error); |
| 331 | - if (error != NULL) { |
| 332 | - QString message(error->message); |
| 333 | - qCritical() << "Error storing token: " << message; |
| 334 | - emit keyring->keyringError(message); |
| 335 | - g_error_free(error); |
| 336 | + QString _acctName("ubuntuone"); |
| 337 | + AccountIdList _ids = _manager.accountList(_acctName); |
| 338 | + Account *account; |
| 339 | + |
| 340 | + if (_ids.length() > 0) { |
| 341 | + if (_ids.length() > 1) { |
| 342 | + qDebug() << "handleCredentialsStored(): Found '" << _ids.length() << "' accounts. Using first."; |
| 343 | + } |
| 344 | + account = _manager.account(_ids[0]); |
| 345 | + qDebug() << "handleCredentialsStored(): Using Ubuntu One account '" << _ids[0] << "'."; |
| 346 | + account->selectService(); |
| 347 | + account->setCredentialsId(id); |
| 348 | + |
| 349 | + ServiceList services = account->services(_acctName); |
| 350 | + if (services.length() > 0) { |
| 351 | + account->selectService(services[0]); |
| 352 | + } else { |
| 353 | + QString errMsg("Unable to enable 'ubuntuone' service."); |
| 354 | + emit keyringError(errMsg); |
| 355 | + } |
| 356 | + account->setEnabled(true); |
| 357 | + account->sync(); |
| 358 | + emit tokenStored(); |
| 359 | return; |
| 360 | } |
| 361 | - emit keyring->tokenStored(); |
| 362 | + emit keyringError(QStringLiteral("Could not sync credentials ID.")); |
| 363 | } |
| 364 | |
| 365 | void Keyring::storeToken(Token token) |
| 366 | { |
| 367 | - secret_password_store(_getTokenSchema(), SECRET_COLLECTION_DEFAULT, |
| 368 | - TOKEN_ID, token.toQuery().toUtf8().data(), NULL, |
| 369 | - (GAsyncReadyCallback)_onPasswordStored, this, |
| 370 | - TOKEN_ATTR_TYPE_KEY, TOKEN_KEY_TYPE, |
| 371 | - TOKEN_ATTR_NAME_KEY, Token::buildTokenName().toUtf8().data(), |
| 372 | - NULL); |
| 373 | - } |
| 374 | - |
| 375 | - static void _onPasswordCleared(GObject *source, GAsyncResult *result, |
| 376 | - Keyring *keyring) |
| 377 | - { |
| 378 | - GError *error = NULL; |
| 379 | - |
| 380 | - secret_password_store_finish (result, &error); |
| 381 | - if (error != NULL) { |
| 382 | - QString message(error->message); |
| 383 | - qDebug() << message; |
| 384 | - emit keyring->keyringError(message); |
| 385 | - g_error_free(error); |
| 386 | + QString _acctName("ubuntuone"); |
| 387 | + AccountIdList _ids = _manager.accountList(_acctName); |
| 388 | + Identity *identity; |
| 389 | + Account *account; |
| 390 | + |
| 391 | + if (_ids.length() > 0) { |
| 392 | + if (_ids.length() > 1) { |
| 393 | + qDebug() << "storeToken(): Found '" << _ids.length() << "' accounts. Using first."; |
| 394 | + } |
| 395 | + account = _manager.account(_ids[0]); |
| 396 | + qDebug() << "storeToken(): Using Ubuntu One account '" << _ids[0] << "'."; |
| 397 | + identity = Identity::existingIdentity(account->credentialsId()); |
| 398 | + } else { |
| 399 | + account = _manager.createAccount(_acctName); |
| 400 | + |
| 401 | + ServiceList services = account->services(_acctName); |
| 402 | + if (services.length() > 0) { |
| 403 | + account->selectService(services[0]); |
| 404 | + } else { |
| 405 | + QString errMsg("Unable to enable 'ubuntuone' service."); |
| 406 | + emit keyringError(errMsg); |
| 407 | + } |
| 408 | + |
| 409 | + identity = Identity::newIdentity(); |
| 410 | + account->setEnabled(true); |
| 411 | + account->sync(); |
| 412 | } |
| 413 | - emit keyring->tokenDeleted(); |
| 414 | + |
| 415 | + connect(identity, SIGNAL(error(const SignOn::Error&)), |
| 416 | + this, SLOT(handleError(const SignOn::Error&))); |
| 417 | + connect(identity, SIGNAL(credentialsStored(const quint32)), |
| 418 | + this, SLOT(handleCredentialsStored(const quint32))); |
| 419 | + |
| 420 | + IdentityInfo info = IdentityInfo(); |
| 421 | + |
| 422 | + info.setSecret(token.toQuery(), true); |
| 423 | + identity->storeCredentials(info); |
| 424 | + } |
| 425 | + |
| 426 | + void Keyring::handleAccountRemoved() |
| 427 | + { |
| 428 | + emit tokenDeleted(); |
| 429 | } |
| 430 | |
| 431 | void Keyring::deleteToken() |
| 432 | { |
| 433 | - secret_password_clear(_getTokenSchema(), NULL, |
| 434 | - (GAsyncReadyCallback)_onPasswordCleared, this, |
| 435 | - TOKEN_ATTR_TYPE_KEY, TOKEN_KEY_TYPE, |
| 436 | - TOKEN_ATTR_NAME_KEY, Token::buildTokenName().toUtf8().data(), |
| 437 | - NULL); |
| 438 | + QString _acctName("ubuntuone"); |
| 439 | + AccountIdList _ids = _manager.accountList(_acctName); |
| 440 | + if (_ids.length() > 0) { |
| 441 | + if (_ids.length() > 1) { |
| 442 | + qDebug() << "deleteToken(): Found '" << _ids.length() << "' accounts. Using first."; |
| 443 | + } |
| 444 | + Account *account = _manager.account(_ids[0]); |
| 445 | + qDebug() << "deleteToken(): Using Ubuntu One account '" << _ids[0] << "'."; |
| 446 | + Identity *identity = Identity::existingIdentity(account->credentialsId()); |
| 447 | + connect(account, SIGNAL(removed()), |
| 448 | + this, SLOT(handleAccountRemoved())); |
| 449 | + connect(identity, SIGNAL(error(const SignOn::Error&)), |
| 450 | + this, SLOT(handleError(const SignOn::Error&))); |
| 451 | + |
| 452 | + identity->remove(); |
| 453 | + account->remove(); |
| 454 | + account->sync(); |
| 455 | + return; |
| 456 | + } |
| 457 | + emit tokenNotFound(); |
| 458 | } |
| 459 | |
| 460 | } // namespace UbuntuOne |
| 461 | |
| 462 | === modified file 'libubuntuoneauth/keyring.h' |
| 463 | --- libubuntuoneauth/keyring.h 2013-05-24 19:10:54 +0000 |
| 464 | +++ libubuntuoneauth/keyring.h 2013-08-27 20:30:52 +0000 |
| 465 | @@ -18,6 +18,9 @@ |
| 466 | #ifndef _U1_KEYRING_H_ |
| 467 | #define _U1_KEYRING_H_ |
| 468 | |
| 469 | +#include <Accounts/Manager> |
| 470 | +#include <SignOn/Identity> |
| 471 | + |
| 472 | #include <QObject> |
| 473 | |
| 474 | #include "token.h" |
| 475 | @@ -42,6 +45,15 @@ |
| 476 | void tokenDeleted(); |
| 477 | |
| 478 | void keyringError(QString message); |
| 479 | + |
| 480 | + private Q_SLOTS: |
| 481 | + void handleError(const SignOn::Error &error); |
| 482 | + void handleSessionData(const SignOn::SessionData &data); |
| 483 | + void handleCredentialsStored(const quint32 id); |
| 484 | + void handleAccountRemoved(); |
| 485 | + |
| 486 | + private: |
| 487 | + Accounts::Manager _manager; |
| 488 | }; |
| 489 | |
| 490 | } /* namespace UbuntuOne */ |
| 491 | |
| 492 | === added file 'libubuntuoneauth/libubuntuoneauth.symbols' |
| 493 | --- libubuntuoneauth/libubuntuoneauth.symbols 1970-01-01 00:00:00 +0000 |
| 494 | +++ libubuntuoneauth/libubuntuoneauth.symbols 2013-08-27 20:30:52 +0000 |
| 495 | @@ -0,0 +1,9 @@ |
| 496 | +{ |
| 497 | + global: |
| 498 | + extern "C++" { |
| 499 | + *UbuntuOne::*; |
| 500 | + }; |
| 501 | + qt_*; |
| 502 | + local: |
| 503 | + *; |
| 504 | +}; |
| 505 | |
| 506 | === modified file 'libubuntuoneauth/logging.cpp' |
| 507 | --- libubuntuoneauth/logging.cpp 2013-05-01 15:39:22 +0000 |
| 508 | +++ libubuntuoneauth/logging.cpp 2013-08-27 20:30:52 +0000 |
| 509 | @@ -114,7 +114,23 @@ |
| 510 | if (type < _logLevel) |
| 511 | return; |
| 512 | |
| 513 | - _logStream << QDateTime::currentDateTime().toString(_datetimeFormat).toUtf8().data() << " - " << getMessageTypeString(type).toUtf8().data() << " - " << message.toUtf8().data() << "\n"; |
| 514 | + QString logMessage; |
| 515 | + QTextStream _logMessage(&logMessage); |
| 516 | + _logMessage << QDateTime::currentDateTime().toString(_datetimeFormat).toUtf8().data() << " - " << getMessageTypeString(type).toUtf8().data() << " - " << message.toUtf8().data() << "\n"; |
| 517 | + |
| 518 | + QTextStream _stdErr(stderr, QIODevice::WriteOnly); |
| 519 | + switch (type) { |
| 520 | + case QtDebugMsg: |
| 521 | + case QtCriticalMsg: |
| 522 | + case QtFatalMsg: |
| 523 | + _stdErr << logMessage; |
| 524 | + break; |
| 525 | + default: |
| 526 | + break; |
| 527 | + } |
| 528 | + _stdErr.device()->close(); |
| 529 | + |
| 530 | + _logStream << logMessage; |
| 531 | _logStream.flush(); |
| 532 | |
| 533 | if (type == QtFatalMsg) |
| 534 | |
| 535 | === modified file 'libubuntuoneauth/network.cpp' |
| 536 | --- libubuntuoneauth/network.cpp 2013-06-14 22:39:59 +0000 |
| 537 | +++ libubuntuoneauth/network.cpp 2013-08-27 20:30:52 +0000 |
| 538 | @@ -23,10 +23,12 @@ |
| 539 | |
| 540 | #include <QStringList> |
| 541 | |
| 542 | +#include "errormessages.h" |
| 543 | #include "network.h" |
| 544 | #include "responses.h" |
| 545 | #include "requests.h" |
| 546 | |
| 547 | +#define NO_HTTP_REASON QString("No HTTP error reason") |
| 548 | |
| 549 | namespace UbuntuOne { |
| 550 | |
| 551 | @@ -51,30 +53,35 @@ |
| 552 | /* TODO: see if we really need to do this check, we could just operate |
| 553 | on a bad value as being an error rather than the extra check? */ |
| 554 | if (!statusAttr.isValid()) { |
| 555 | - qDebug() << "Invalid status received!"; |
| 556 | + QString errmsg = QString("Invalid status attribute in Network::OnReply"); |
| 557 | + // Use login failed code, which results in generic error message: |
| 558 | + emit ErrorOccurred(ErrorResponse(0, NO_HTTP_REASON, LOGIN_FAILED, errmsg)); |
| 559 | return; |
| 560 | } |
| 561 | |
| 562 | int httpStatus = statusAttr.toInt(); |
| 563 | |
| 564 | - qDebug() << "Network::OnReply from " << reply->url(); |
| 565 | - qDebug() << "Network::OnReply status: " << httpStatus; |
| 566 | + qDebug() << "Network::OnReply from " << reply->url() |
| 567 | + << " status: " << httpStatus; |
| 568 | |
| 569 | QByteArray payload = reply->readAll(); |
| 570 | if (payload.isEmpty()) { |
| 571 | - qDebug() << "empty payload"; |
| 572 | - return; /* TODO: Do something to signal we're having a bad time. */ |
| 573 | + QString errmsg = QString("Network::OnReply: empty payload, giving up."); |
| 574 | + emit ErrorOccurred(ErrorResponse(0, NO_HTTP_REASON, LOGIN_FAILED, errmsg)); |
| 575 | + return; |
| 576 | } |
| 577 | |
| 578 | QJsonDocument document = QJsonDocument::fromJson(payload); |
| 579 | - /* TODO: add logging or raise some type of error signal? */ |
| 580 | + |
| 581 | if (document.isEmpty()) { |
| 582 | - qDebug() << "oops, received empty document"; |
| 583 | + QString errmsg = QString("Network::OnReply received empty document"); |
| 584 | + emit ErrorOccurred(ErrorResponse(0, NO_HTTP_REASON, LOGIN_FAILED, errmsg)); |
| 585 | return; |
| 586 | } |
| 587 | |
| 588 | if (!document.isObject()) { |
| 589 | - qDebug() << "uh oh, this isn't good."; |
| 590 | + QString errmsg = QString("Network::OnReply received invalid QJsonDocument"); |
| 591 | + emit ErrorOccurred(ErrorResponse(0, NO_HTTP_REASON, LOGIN_FAILED, errmsg)); |
| 592 | return; |
| 593 | } |
| 594 | |
| 595 | @@ -82,17 +89,18 @@ |
| 596 | |
| 597 | /* TODO: map out urls to reply parsers */ |
| 598 | if (httpStatus == 200 || httpStatus == 201) { |
| 599 | - if (reply->url() == OAUTH_API) |
| 600 | + if (reply->url().path() == OAUTH_PATH) |
| 601 | ProcessOAuthTokenReply(object); |
| 602 | - else if (reply->url() == PASSWORD_API) |
| 603 | + else if (reply->url().path() == PASSWORD_PATH) |
| 604 | ProcessPasswordTokenReply(object); |
| 605 | - else if (reply->url() == ACCOUNTS_API) |
| 606 | + else if (reply->url().path() == ACCOUNTS_PATH) |
| 607 | ProcessAccountsReply(object); |
| 608 | } else /* Statuses outside 200, 201 are fails */ { |
| 609 | QVariant phraseAttr = reply->attribute( |
| 610 | QNetworkRequest::HttpReasonPhraseAttribute); |
| 611 | if (!phraseAttr.isValid()) { |
| 612 | - qDebug() << "got a bad HTTP reason"; |
| 613 | + QString errmsg = QString("HTTP reason phrase is invalid"); |
| 614 | + emit ErrorOccurred(ErrorResponse(httpStatus, NO_HTTP_REASON, LOGIN_FAILED, errmsg)); |
| 615 | return; |
| 616 | } |
| 617 | QString httpReason = phraseAttr.toString(); |
| 618 | |
| 619 | === modified file 'libubuntuoneauth/network.h' |
| 620 | --- libubuntuoneauth/network.h 2013-06-14 22:39:59 +0000 |
| 621 | +++ libubuntuoneauth/network.h 2013-08-27 20:30:52 +0000 |
| 622 | @@ -28,8 +28,6 @@ |
| 623 | |
| 624 | namespace UbuntuOne { |
| 625 | |
| 626 | -//static QString API_BASE = "https://login.ubuntu.com/api/v2/"; |
| 627 | - |
| 628 | class Network : public QObject |
| 629 | { |
| 630 | Q_OBJECT |
| 631 | |
| 632 | === modified file 'libubuntuoneauth/requests.cpp' |
| 633 | --- libubuntuoneauth/requests.cpp 2013-06-14 22:39:59 +0000 |
| 634 | +++ libubuntuoneauth/requests.cpp 2013-08-27 20:30:52 +0000 |
| 635 | @@ -40,13 +40,20 @@ |
| 636 | { |
| 637 | } |
| 638 | |
| 639 | +OAuthTokenRequest::OAuthTokenRequest(QString base_url, |
| 640 | + QString email, QString password, |
| 641 | + QString name, QString otp) |
| 642 | + : RequestInterface(base_url + OAUTH_PATH), |
| 643 | + _email(email), _password(password), _name(name), _otp(otp) |
| 644 | +{ |
| 645 | +} |
| 646 | + |
| 647 | QByteArray OAuthTokenRequest::serialize() const |
| 648 | { |
| 649 | QJsonObject serializer; |
| 650 | serializer.insert("email", this->email()); |
| 651 | serializer.insert("password", this->password()); |
| 652 | serializer.insert("token_name", this->name()); |
| 653 | - /* TODO: check for null */ |
| 654 | if (!this->otp().isEmpty()) |
| 655 | serializer.insert("otp", this->otp()); |
| 656 | |
| 657 | @@ -73,6 +80,17 @@ |
| 658 | { |
| 659 | } |
| 660 | |
| 661 | +AccountRequest::AccountRequest(QString base_url, |
| 662 | + QString email, QString password, QString name, |
| 663 | + QString captchaId, QString captchaSolution, |
| 664 | + bool createCaptcha) |
| 665 | + : RequestInterface(base_url + ACCOUNTS_PATH), |
| 666 | + _email(email), _password(password), _name(name), |
| 667 | + _captchaId(captchaId), _captchaSolution(captchaSolution), |
| 668 | + _createCaptcha(createCaptcha) |
| 669 | +{ |
| 670 | +} |
| 671 | + |
| 672 | QByteArray AccountRequest::serialize() const |
| 673 | { |
| 674 | QJsonObject data; |
| 675 | @@ -97,6 +115,11 @@ |
| 676 | { |
| 677 | } |
| 678 | |
| 679 | +PasswordTokenRequest::PasswordTokenRequest(QString base_url, QString email) |
| 680 | + : RequestInterface(base_url + PASSWORD_PATH), _email(email) |
| 681 | +{ |
| 682 | +} |
| 683 | + |
| 684 | QByteArray PasswordTokenRequest::serialize() const |
| 685 | { |
| 686 | QJsonObject data; |
| 687 | |
| 688 | === modified file 'libubuntuoneauth/requests.h' |
| 689 | --- libubuntuoneauth/requests.h 2013-06-14 22:39:59 +0000 |
| 690 | +++ libubuntuoneauth/requests.h 2013-08-27 20:30:52 +0000 |
| 691 | @@ -24,10 +24,14 @@ |
| 692 | |
| 693 | namespace UbuntuOne { |
| 694 | |
| 695 | -static QString API_BASE = "https://login.ubuntu.com/api/v2/"; |
| 696 | -static QString OAUTH_API = API_BASE + "tokens/oauth"; |
| 697 | -static QString PASSWORD_API = API_BASE + "tokens/password"; |
| 698 | -static QString ACCOUNTS_API = API_BASE + "accounts"; |
| 699 | +static QString API_VERSION = "/api/v2"; |
| 700 | +static QString API_BASE = "https://login.ubuntu.com/"; |
| 701 | +static QString OAUTH_PATH = API_VERSION + "/tokens/oauth"; |
| 702 | +static QString OAUTH_API = API_BASE + OAUTH_PATH; |
| 703 | +static QString PASSWORD_PATH = API_VERSION + "/tokens/password"; |
| 704 | +static QString PASSWORD_API = API_BASE + PASSWORD_PATH; |
| 705 | +static QString ACCOUNTS_PATH = API_VERSION + "/accounts"; |
| 706 | +static QString ACCOUNTS_API = API_BASE + ACCOUNTS_PATH; |
| 707 | |
| 708 | class RequestInterface |
| 709 | { |
| 710 | @@ -47,6 +51,9 @@ |
| 711 | OAuthTokenRequest(); |
| 712 | OAuthTokenRequest(QString email, QString password, |
| 713 | QString token, QString otp); |
| 714 | + OAuthTokenRequest(QString base_url, |
| 715 | + QString email, QString password, |
| 716 | + QString token, QString otp); |
| 717 | |
| 718 | QByteArray serialize() const; |
| 719 | |
| 720 | @@ -71,6 +78,10 @@ |
| 721 | AccountRequest(QString email, QString password, QString name, |
| 722 | QString captchaId, QString captchaSolution, |
| 723 | bool createCaptcha = true); |
| 724 | + AccountRequest(QString base_url, |
| 725 | + QString email, QString password, QString name, |
| 726 | + QString captchaId, QString captchaSolution, |
| 727 | + bool createCaptcha); |
| 728 | |
| 729 | QByteArray serialize() const; |
| 730 | |
| 731 | @@ -98,6 +109,7 @@ |
| 732 | public: |
| 733 | PasswordTokenRequest(); |
| 734 | PasswordTokenRequest(QString email); |
| 735 | + PasswordTokenRequest(QString base_url, QString email); |
| 736 | |
| 737 | QByteArray serialize() const; |
| 738 | |
| 739 | |
| 740 | === modified file 'libubuntuoneauth/ssoservice.cpp' |
| 741 | --- libubuntuoneauth/ssoservice.cpp 2013-06-28 23:44:14 +0000 |
| 742 | +++ libubuntuoneauth/ssoservice.cpp 2013-08-27 20:30:52 +0000 |
| 743 | @@ -67,8 +67,11 @@ |
| 744 | SIGNAL(AccountGranted(const AccountResponse&)), |
| 745 | this, SLOT(accountRegistered(const AccountResponse&))); |
| 746 | connect(&(_provider), |
| 747 | + SIGNAL(TwoFactorAuthRequired()), |
| 748 | + this, SLOT(handleTwoFactorAuthRequired())); |
| 749 | + connect(&(_provider), |
| 750 | SIGNAL(ErrorOccurred(const ErrorResponse&)), |
| 751 | - this, SLOT(errorOcurred(const ErrorResponse&))); |
| 752 | + this, SLOT(errorOccurred(const ErrorResponse&))); |
| 753 | } |
| 754 | |
| 755 | void SSOService::getCredentials() |
| 756 | @@ -88,14 +91,15 @@ |
| 757 | |
| 758 | void SSOService::handleTokenStored() |
| 759 | { |
| 760 | - emit credentialsStored(_pendingPing); |
| 761 | + emit credentialsStored(); |
| 762 | _pendingPing = Token(); |
| 763 | } |
| 764 | |
| 765 | void SSOService::registerUser(QString email, QString password, |
| 766 | QString display_name) |
| 767 | { |
| 768 | - AccountRequest request(email, password, display_name, NULL, NULL); |
| 769 | + AccountRequest request(getAuthBaseUrl(), |
| 770 | + email, password, display_name, NULL, NULL); |
| 771 | |
| 772 | _tempPassword = password; |
| 773 | _tempEmail = email; |
| 774 | @@ -108,14 +112,21 @@ |
| 775 | _tempPassword = ""; |
| 776 | } |
| 777 | |
| 778 | - void SSOService::login(QString email, QString password) |
| 779 | + void SSOService::login(QString email, QString password, QString twoFactorCode) |
| 780 | { |
| 781 | - OAuthTokenRequest request(email, password, Token::buildTokenName(), NULL); |
| 782 | + OAuthTokenRequest request(getAuthBaseUrl(), |
| 783 | + email, password, |
| 784 | + Token::buildTokenName(), twoFactorCode); |
| 785 | _tempEmail = email; |
| 786 | |
| 787 | _provider.GetOAuthToken(request); |
| 788 | } |
| 789 | |
| 790 | + void SSOService::handleTwoFactorAuthRequired() |
| 791 | + { |
| 792 | + emit twoFactorAuthRequired(); |
| 793 | + } |
| 794 | + |
| 795 | static QString _getPlatformDataParams() |
| 796 | { |
| 797 | struct utsname _platData; |
| 798 | @@ -128,7 +139,7 @@ |
| 799 | params->addQueryItem("client_version", PROJECT_VERSION); |
| 800 | |
| 801 | QString result = params->toString(); |
| 802 | - qDebug() << "Ping parameters:" << result; |
| 803 | + |
| 804 | return result; |
| 805 | } |
| 806 | |
| 807 | @@ -136,7 +147,7 @@ |
| 808 | { |
| 809 | QString baseUrl = qgetenv("SSO_AUTH_BASE_URL"); |
| 810 | if (baseUrl.isEmpty()) |
| 811 | - baseUrl = QStringLiteral("https://login.ubuntu.com/"); |
| 812 | + baseUrl = QStringLiteral("https://login.ubuntu.com"); |
| 813 | return baseUrl; |
| 814 | } |
| 815 | |
| 816 | @@ -144,7 +155,7 @@ |
| 817 | { |
| 818 | QString baseUrl = qgetenv("SSO_UONE_BASE_URL"); |
| 819 | if (baseUrl.isEmpty()) |
| 820 | - baseUrl = QStringLiteral("https://one.ubuntu.com/"); |
| 821 | + baseUrl = QStringLiteral("https://one.ubuntu.com"); |
| 822 | return baseUrl; |
| 823 | } |
| 824 | |
| 825 | @@ -152,7 +163,7 @@ |
| 826 | { |
| 827 | Token realToken = Token(token.token_key(), token.token_secret(), |
| 828 | token.consumer_key(), token.consumer_secret()); |
| 829 | - QString urlToSign = getUOneBaseUrl() + "oauth/sso-finished-so-get-tokens/" + _tempEmail + "?" + _getPlatformDataParams(); |
| 830 | + QString urlToSign = getUOneBaseUrl() + "/oauth/sso-finished-so-get-tokens/" + _tempEmail + "?" + _getPlatformDataParams(); |
| 831 | QString authHeader = realToken.signUrl(urlToSign, |
| 832 | QStringLiteral("GET")); |
| 833 | QNetworkRequest *_request = new QNetworkRequest(); |
| 834 | @@ -189,7 +200,7 @@ |
| 835 | _keyring->deleteToken(); |
| 836 | } |
| 837 | |
| 838 | - void SSOService::errorOcurred(const ErrorResponse& error) |
| 839 | + void SSOService::errorOccurred(const ErrorResponse& error) |
| 840 | { |
| 841 | _tempPassword = ""; |
| 842 | emit requestFailed(error); |
| 843 | |
| 844 | === modified file 'libubuntuoneauth/ssoservice.h' |
| 845 | --- libubuntuoneauth/ssoservice.h 2013-06-20 19:21:02 +0000 |
| 846 | +++ libubuntuoneauth/ssoservice.h 2013-08-27 20:30:52 +0000 |
| 847 | @@ -40,7 +40,7 @@ |
| 848 | |
| 849 | void invalidateCredentials(); |
| 850 | void getCredentials(); |
| 851 | - void login(QString email, QString password); |
| 852 | + void login(QString email, QString password, QString twoFactorCode = QString()); |
| 853 | void registerUser(QString email, QString password, |
| 854 | QString display_name); |
| 855 | |
| 856 | @@ -49,10 +49,11 @@ |
| 857 | |
| 858 | signals: |
| 859 | void credentialsDeleted(); |
| 860 | - void credentialsStored(const Token& token); |
| 861 | + void credentialsStored(); |
| 862 | void credentialsFound(const Token& token); |
| 863 | void credentialsNotFound(); |
| 864 | void requestFailed(const ErrorResponse& error); |
| 865 | + void twoFactorAuthRequired(); |
| 866 | |
| 867 | private slots: |
| 868 | void accountPinged(QNetworkReply*); |
| 869 | @@ -62,7 +63,8 @@ |
| 870 | void handleCredentialsNotFound(); |
| 871 | void tokenReceived(const OAuthTokenResponse& token); |
| 872 | void accountRegistered(const AccountResponse& account); |
| 873 | - void errorOcurred(const ErrorResponse&); |
| 874 | + void errorOccurred(const ErrorResponse&); |
| 875 | + void handleTwoFactorAuthRequired(); |
| 876 | |
| 877 | private: |
| 878 | Keyring *_keyring; |
| 879 | |
| 880 | === modified file 'libubuntuoneauth/token.h' |
| 881 | --- libubuntuoneauth/token.h 2013-06-25 15:52:14 +0000 |
| 882 | +++ libubuntuoneauth/token.h 2013-08-27 20:30:52 +0000 |
| 883 | @@ -49,4 +49,4 @@ |
| 884 | |
| 885 | } /* namespace UbuntuOne */ |
| 886 | |
| 887 | -#endif /* _U1_KEYRING_H_ */ |
| 888 | +#endif /* _U1_TOKEN_H_ */ |
| 889 | |
| 890 | === modified file 'music-login/CMakeLists.txt' |
| 891 | --- music-login/CMakeLists.txt 2013-05-09 12:19:06 +0000 |
| 892 | +++ music-login/CMakeLists.txt 2013-08-27 20:30:52 +0000 |
| 893 | @@ -46,8 +46,8 @@ |
| 894 | qt5_use_modules (${MUSIC_LOGIN_LIB} Core DBus Gui Widgets Network) |
| 895 | qt5_use_modules (${MUSIC_LOGIN_EXE} DBus Widgets Network) |
| 896 | target_link_libraries (${MUSIC_LOGIN_EXE} |
| 897 | - -Wl,-rpath,${CMAKE_BINARY_DIR}/lib |
| 898 | - -L${CMAKE_BINARY_DIR}/lib |
| 899 | + -Wl,-rpath,${CMAKE_BINARY_DIR}/libubuntuoneauth |
| 900 | + -L${CMAKE_BINARY_DIR}/libubuntuoneauth |
| 901 | ${AUTH_LIB_NAME} |
| 902 | ${MUSIC_LIB_NAME} |
| 903 | ) |
| 904 | |
| 905 | === modified file 'music-login/loginform.cpp' |
| 906 | --- music-login/loginform.cpp 2013-06-14 22:30:19 +0000 |
| 907 | +++ music-login/loginform.cpp 2013-08-27 20:30:52 +0000 |
| 908 | @@ -71,13 +71,15 @@ |
| 909 | |
| 910 | void LoginForm::validateForm() |
| 911 | { |
| 912 | - bool value = this->checkEmail() && this->checkPassword() && this->_sessionActive; |
| 913 | + bool passwordCheck = this->ui->radioNewCustomer->isChecked() || this->checkPassword(); |
| 914 | + bool value = this->checkEmail() && passwordCheck && this->_sessionActive; |
| 915 | this->ui->btnProceed->setEnabled(value); |
| 916 | } |
| 917 | |
| 918 | bool LoginForm::checkEmail() |
| 919 | { |
| 920 | - bool value = !this->ui->lineEmail->text().isEmpty() && this->ui->lineEmail->text().contains("@"); |
| 921 | + QRegExp mailRE(".+@.+"); |
| 922 | + bool value = mailRE.exactMatch(this->ui->lineEmail->text()); |
| 923 | this->ui->lineEmail->setProperty("error", !value); |
| 924 | this->style()->unpolish(this->ui->lineEmail); |
| 925 | this->style()->polish(this->ui->lineEmail); |
| 926 | @@ -86,7 +88,10 @@ |
| 927 | |
| 928 | bool LoginForm::checkPassword() |
| 929 | { |
| 930 | - bool value = this->ui->linePassword->text().length() > 7; |
| 931 | + bool value = true; |
| 932 | + if(this->ui->radioReturningCustomer->isChecked()){ |
| 933 | + value = this->ui->linePassword->text().length() > 7; |
| 934 | + } |
| 935 | this->ui->linePassword->setProperty("error", !value); |
| 936 | this->style()->unpolish(this->ui->linePassword); |
| 937 | this->style()->polish(this->ui->linePassword); |
| 938 | @@ -121,11 +126,15 @@ |
| 939 | void LoginForm::on_radioNewCustomer_clicked() |
| 940 | { |
| 941 | this->ui->btnProceed->setText(tr("Continue")); |
| 942 | + this->validateForm(); |
| 943 | + this->checkPassword(); |
| 944 | + this->ui->lblPasswordError->setVisible(false); |
| 945 | } |
| 946 | |
| 947 | void LoginForm::on_radioReturningCustomer_clicked() |
| 948 | { |
| 949 | this->ui->btnProceed->setText(tr("Proceed to Checkout")); |
| 950 | + this->validateForm(); |
| 951 | } |
| 952 | |
| 953 | void LoginForm::showEmailWarning() |
| 954 | @@ -135,5 +144,7 @@ |
| 955 | |
| 956 | void LoginForm::showPasswordWarning() |
| 957 | { |
| 958 | - this->ui->lblPasswordError->setVisible(!this->checkPassword()); |
| 959 | + if(this->ui->radioReturningCustomer->isChecked()){ |
| 960 | + this->ui->lblPasswordError->setVisible(!this->checkPassword()); |
| 961 | + } |
| 962 | } |
| 963 | |
| 964 | === modified file 'music-login/registerform.cpp' |
| 965 | --- music-login/registerform.cpp 2013-06-14 22:30:19 +0000 |
| 966 | +++ music-login/registerform.cpp 2013-08-27 20:30:52 +0000 |
| 967 | @@ -104,7 +104,8 @@ |
| 968 | |
| 969 | bool RegisterForm::checkEmail() |
| 970 | { |
| 971 | - bool value = !this->ui->lineEmail->text().isEmpty() && this->ui->lineEmail->text().contains("@"); |
| 972 | + QRegExp mailRE(".+@.+"); |
| 973 | + bool value = mailRE.exactMatch(this->ui->lineEmail->text()); |
| 974 | this->ui->lineEmail->setProperty("error", !value); |
| 975 | this->style()->unpolish(this->ui->lineEmail); |
| 976 | this->style()->polish(this->ui->lineEmail); |
| 977 | |
| 978 | === modified file 'music-login/ssowizard.cpp' |
| 979 | --- music-login/ssowizard.cpp 2013-07-02 18:59:41 +0000 |
| 980 | +++ music-login/ssowizard.cpp 2013-08-27 20:30:52 +0000 |
| 981 | @@ -81,11 +81,14 @@ |
| 982 | QObject::connect(&(this->downloader), SIGNAL(fileDownloaded(QString&)), |
| 983 | this, SLOT(imageDownloaded(QString&))); |
| 984 | |
| 985 | - QObject::connect(&(this->_service), SIGNAL(credentialsStored(const Token&)), |
| 986 | - this, SLOT(accountAuthenticated(Token))); |
| 987 | + QObject::connect(&(this->_service), SIGNAL(credentialsStored()), |
| 988 | + this, SLOT(accountAuthenticated())); |
| 989 | QObject::connect(&(this->_service), SIGNAL(credentialsFound(const Token&)), |
| 990 | this, SLOT(openUrlAndFinish(Token))); |
| 991 | |
| 992 | + QObject::connect(&(this->_service), SIGNAL(twoFactorAuthRequired()), |
| 993 | + this, SLOT(handleTwoFactorAuthRequired())); |
| 994 | + |
| 995 | QObject::connect(&(this->_service), SIGNAL(requestFailed(const ErrorResponse&)), |
| 996 | this, SLOT(serviceFailed(const ErrorResponse&))); |
| 997 | QObject::connect(this->ui->pageLogin, SIGNAL(newCustomerSelected(QString,QString)), |
| 998 | @@ -142,7 +145,7 @@ |
| 999 | this->_service.login(email, password); |
| 1000 | } |
| 1001 | |
| 1002 | -void SSOWizard::accountAuthenticated(Token token) |
| 1003 | +void SSOWizard::accountAuthenticated() |
| 1004 | { |
| 1005 | this->_service.getCredentials(); |
| 1006 | } |
| 1007 | @@ -172,6 +175,12 @@ |
| 1008 | this->ui->stackedWidget->setCurrentIndex(0); |
| 1009 | } |
| 1010 | |
| 1011 | +void SSOWizard::handleTwoFactorAuthRequired() |
| 1012 | +{ |
| 1013 | + this->_overlay->hide(); |
| 1014 | + this->showError(ErrorResponse(401, QString(), TWOFACTOR_REQUIRED, QString())); |
| 1015 | +} |
| 1016 | + |
| 1017 | void SSOWizard::serviceFailed(const ErrorResponse& error) |
| 1018 | { |
| 1019 | this->_overlay->hide(); |
| 1020 | |
| 1021 | === modified file 'music-login/ssowizard.h' |
| 1022 | --- music-login/ssowizard.h 2013-07-02 18:59:41 +0000 |
| 1023 | +++ music-login/ssowizard.h 2013-08-27 20:30:52 +0000 |
| 1024 | @@ -67,8 +67,9 @@ |
| 1025 | void registerAndBuy(QString email, QString password, QString name); |
| 1026 | void showPageLogin(); |
| 1027 | |
| 1028 | - void accountAuthenticated(Token); |
| 1029 | + void accountAuthenticated(); |
| 1030 | void openUrlAndFinish(Token); |
| 1031 | + void handleTwoFactorAuthRequired(); |
| 1032 | void serviceFailed(const ErrorResponse&); |
| 1033 | |
| 1034 | private: |
| 1035 | |
| 1036 | === modified file 'music-login/tests/CMakeLists.txt' |
| 1037 | --- music-login/tests/CMakeLists.txt 2013-05-27 02:26:03 +0000 |
| 1038 | +++ music-login/tests/CMakeLists.txt 2013-08-27 20:30:52 +0000 |
| 1039 | @@ -20,8 +20,8 @@ |
| 1040 | qt5_use_modules (${UI_TESTS_TARGET} Test DBus Network Widgets) |
| 1041 | add_dependencies (${UI_TESTS_TARGET} ${MUSIC_LOGIN_LIB}) |
| 1042 | target_link_libraries (${UI_TESTS_TARGET} |
| 1043 | - -Wl,-rpath,${CMAKE_BINARY_DIR}/lib |
| 1044 | - -L${CMAKE_BINARY_DIR}/lib |
| 1045 | + -Wl,-rpath,${CMAKE_BINARY_DIR}/libubuntuoneauth |
| 1046 | + -L${CMAKE_BINARY_DIR}/libubuntuoneauth |
| 1047 | ${AUTH_LIB_NAME} |
| 1048 | ${MUSIC_LOGIN_LIB} |
| 1049 | ) |
| 1050 | |
| 1051 | === modified file 'music-login/tests/testloginform.cpp' |
| 1052 | --- music-login/tests/testloginform.cpp 2013-06-14 22:30:19 +0000 |
| 1053 | +++ music-login/tests/testloginform.cpp 2013-08-27 20:30:52 +0000 |
| 1054 | @@ -51,6 +51,7 @@ |
| 1055 | this->loginForm.ui->btnProceed->setEnabled(false); |
| 1056 | this->loginForm.ui->lblEmailError->setVisible(false); |
| 1057 | this->loginForm.ui->lblPasswordError->setVisible(false); |
| 1058 | + this->loginForm.ui->btnProceed->setText(QString("Proceed to Checkout")); |
| 1059 | } |
| 1060 | |
| 1061 | void TestLoginForm::cleanup() |
| 1062 | @@ -83,7 +84,7 @@ |
| 1063 | QVERIFY(this->loginForm.checkPassword()); |
| 1064 | } |
| 1065 | |
| 1066 | -void TestLoginForm::testValidateForm() |
| 1067 | +void TestLoginForm::testValidateFormWithPassword() |
| 1068 | { |
| 1069 | QVERIFY(!this->loginForm.ui->btnProceed->isEnabled()); |
| 1070 | this->loginForm.ui->lineEmail->setText("mail@ubuntu.com"); |
| 1071 | @@ -92,6 +93,15 @@ |
| 1072 | QVERIFY(this->loginForm.ui->btnProceed->isEnabled()); |
| 1073 | } |
| 1074 | |
| 1075 | +void TestLoginForm::testValidateFormWithoutPassword() |
| 1076 | +{ |
| 1077 | + QVERIFY(!this->loginForm.ui->btnProceed->isEnabled()); |
| 1078 | + this->loginForm.ui->lineEmail->setText("mail@ubuntu.com"); |
| 1079 | + QVERIFY(!this->loginForm.ui->btnProceed->isEnabled()); |
| 1080 | + this->loginForm.ui->radioNewCustomer->click(); |
| 1081 | + QVERIFY(this->loginForm.ui->btnProceed->isEnabled()); |
| 1082 | +} |
| 1083 | + |
| 1084 | void TestLoginForm::testCheckEmailWarnings() |
| 1085 | { |
| 1086 | this->loginForm.show(); |
| 1087 | @@ -104,9 +114,10 @@ |
| 1088 | QVERIFY(!this->loginForm.ui->lblEmailError->isVisible()); |
| 1089 | } |
| 1090 | |
| 1091 | -void TestLoginForm::testCheckPasswordWarnings() |
| 1092 | +void TestLoginForm::testCheckPasswordWarningsReturningCustomer() |
| 1093 | { |
| 1094 | this->loginForm.show(); |
| 1095 | + this->loginForm.ui->radioReturningCustomer->setChecked(true); |
| 1096 | QVERIFY(!this->loginForm.ui->lblPasswordError->isVisible()); |
| 1097 | this->loginForm.ui->linePassword->setText("pass"); |
| 1098 | this->loginForm.ui->linePassword->editingFinished(); |
| 1099 | @@ -116,6 +127,19 @@ |
| 1100 | QVERIFY(!this->loginForm.ui->lblPasswordError->isVisible()); |
| 1101 | } |
| 1102 | |
| 1103 | +void TestLoginForm::testCheckPasswordWarningsNewCustomer() |
| 1104 | +{ |
| 1105 | + this->loginForm.show(); |
| 1106 | + this->loginForm.ui->radioNewCustomer->setChecked(true); |
| 1107 | + QVERIFY(!this->loginForm.ui->lblPasswordError->isVisible()); |
| 1108 | + this->loginForm.ui->linePassword->setText("pass"); |
| 1109 | + this->loginForm.ui->linePassword->editingFinished(); |
| 1110 | + QVERIFY(!this->loginForm.ui->lblPasswordError->isVisible()); |
| 1111 | + this->loginForm.ui->linePassword->setText("password"); |
| 1112 | + this->loginForm.ui->linePassword->editingFinished(); |
| 1113 | + QVERIFY(!this->loginForm.ui->lblPasswordError->isVisible()); |
| 1114 | +} |
| 1115 | + |
| 1116 | void TestLoginForm::testButtonProceed() |
| 1117 | { |
| 1118 | QVERIFY(!this->_newCustomerEmitted); |
| 1119 | |
| 1120 | === modified file 'music-login/tests/testloginform.h' |
| 1121 | --- music-login/tests/testloginform.h 2013-05-08 14:36:08 +0000 |
| 1122 | +++ music-login/tests/testloginform.h 2013-08-27 20:30:52 +0000 |
| 1123 | @@ -47,9 +47,11 @@ |
| 1124 | void init(); |
| 1125 | void testCheckEmail(); |
| 1126 | void testCheckPassword(); |
| 1127 | - void testValidateForm(); |
| 1128 | + void testValidateFormWithPassword(); |
| 1129 | + void testValidateFormWithoutPassword(); |
| 1130 | void testCheckEmailWarnings(); |
| 1131 | - void testCheckPasswordWarnings(); |
| 1132 | + void testCheckPasswordWarningsReturningCustomer(); |
| 1133 | + void testCheckPasswordWarningsNewCustomer(); |
| 1134 | void testButtonProceed(); |
| 1135 | void testButtonText(); |
| 1136 | void testShowErrorTipsAlreadyRegistered(); |
| 1137 | |
| 1138 | === added directory 'online-accounts-provider' |
| 1139 | === added file 'online-accounts-provider/CMakeLists.txt' |
| 1140 | --- online-accounts-provider/CMakeLists.txt 1970-01-01 00:00:00 +0000 |
| 1141 | +++ online-accounts-provider/CMakeLists.txt 2013-08-27 20:30:52 +0000 |
| 1142 | @@ -0,0 +1,6 @@ |
| 1143 | +file (GLOB QML_PLUGIN_FILES *.qml) |
| 1144 | + |
| 1145 | +# The path (including plug-in name) where the QML files are installed |
| 1146 | +set (QML_PLUGIN_INSTALL_DIR share/accounts/qml-plugins/ubuntuone/) |
| 1147 | + |
| 1148 | +install (FILES ${QML_PLUGIN_FILES} DESTINATION ${QML_PLUGIN_INSTALL_DIR}) |
| 1149 | |
| 1150 | === added file 'online-accounts-provider/ExistingAccount.qml' |
| 1151 | --- online-accounts-provider/ExistingAccount.qml 1970-01-01 00:00:00 +0000 |
| 1152 | +++ online-accounts-provider/ExistingAccount.qml 2013-08-27 20:30:52 +0000 |
| 1153 | @@ -0,0 +1,95 @@ |
| 1154 | +/* |
| 1155 | + * Copyright (C) 2013 Canonical Ltd. |
| 1156 | + * |
| 1157 | + * |
| 1158 | + * This program is free software: you can redistribute it and/or modify it |
| 1159 | + * under the terms of the GNU General Public License version 3, as published |
| 1160 | + * by the Free Software Foundation. |
| 1161 | + * |
| 1162 | + * This program is distributed in the hope that it will be useful, but |
| 1163 | + * WITHOUT ANY WARRANTY; without even the implied warranties of |
| 1164 | + * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR |
| 1165 | + * PURPOSE. See the GNU General Public License for more details. |
| 1166 | + * |
| 1167 | + * You should have received a copy of the GNU General Public License along |
| 1168 | + * with this program. If not, see <http://www.gnu.org/licenses/>. |
| 1169 | + */ |
| 1170 | + |
| 1171 | +import QtQuick 2.0 |
| 1172 | +import Ubuntu.Components 0.1 |
| 1173 | +import Ubuntu.Components.ListItems 0.1 as ListItem |
| 1174 | +import Ubuntu.Components.Popups 0.1 |
| 1175 | +import Ubuntu.OnlineAccounts 0.1 |
| 1176 | +import Ubuntu.OnlineAccounts.Plugin 1.0 |
| 1177 | + |
| 1178 | +Column { |
| 1179 | + id: root |
| 1180 | + |
| 1181 | + property variant __account: account |
| 1182 | + |
| 1183 | + signal finished |
| 1184 | + |
| 1185 | + anchors.left: parent.left |
| 1186 | + anchors.right: parent.right |
| 1187 | + |
| 1188 | + ListItem.SingleValue { |
| 1189 | + text: "User Name" |
| 1190 | + value: account.displayName |
| 1191 | + } |
| 1192 | + |
| 1193 | + ListItem.SingleValue { |
| 1194 | + text: "Token Name" |
| 1195 | + value: account.displayName |
| 1196 | + } |
| 1197 | + |
| 1198 | + ServiceSwitches { |
| 1199 | + account: __account |
| 1200 | + enabled: __account.enabled |
| 1201 | + opacity: enabled ? 1 : 0.5 |
| 1202 | + } |
| 1203 | + |
| 1204 | + // TOFIX: use ListItem.SingleControl when lp #1194844 is fixed |
| 1205 | + ListItem.Base { |
| 1206 | + Button { |
| 1207 | + anchors { |
| 1208 | + verticalCenter: parent.verticalCenter |
| 1209 | + right: parent.right |
| 1210 | + left: parent.left |
| 1211 | + } |
| 1212 | + text: "Remove account…" |
| 1213 | + onClicked: PopupUtils.open(removalConfirmationComponent); // huh? , removeBtn) |
| 1214 | + } |
| 1215 | + showDivider: false |
| 1216 | + } |
| 1217 | + |
| 1218 | + Component { |
| 1219 | + id: removalConfirmationComponent |
| 1220 | + Dialog { |
| 1221 | + id: dialog |
| 1222 | + |
| 1223 | + property bool confirmed: false |
| 1224 | + |
| 1225 | + title: "Remove Credentials" |
| 1226 | + text: "Removing the Ubuntu One credentials will prevent any applications on this device from accessing your account. You can authorize the device again by providing your username and password." |
| 1227 | + |
| 1228 | + Button { |
| 1229 | + text: "Remove" |
| 1230 | + onClicked: { |
| 1231 | + PopupUtils.close(dialog); |
| 1232 | + console.log("Removing account: " + __account); |
| 1233 | + account.removed.connect(root.finished); |
| 1234 | + account.remove(Account.RemoveCredentials); |
| 1235 | + } |
| 1236 | + |
| 1237 | + } |
| 1238 | + |
| 1239 | + Button { |
| 1240 | + text: "Cancel" |
| 1241 | + onClicked: { |
| 1242 | + console.log("User cancelled account removal"); |
| 1243 | + PopupUtils.close(dialog); |
| 1244 | + } |
| 1245 | + } |
| 1246 | + } // Dialog |
| 1247 | + } //Component |
| 1248 | +} |
| 1249 | |
| 1250 | === added file 'online-accounts-provider/LoginForm.qml' |
| 1251 | --- online-accounts-provider/LoginForm.qml 1970-01-01 00:00:00 +0000 |
| 1252 | +++ online-accounts-provider/LoginForm.qml 2013-08-27 20:30:52 +0000 |
| 1253 | @@ -0,0 +1,100 @@ |
| 1254 | +import QtQuick 2.0 |
| 1255 | +import Ubuntu.Components 0.1 |
| 1256 | + |
| 1257 | +Rectangle { |
| 1258 | + // Set a non-zero height and width so that the parent Column in |
| 1259 | + // CredentialsUI lays out correctly. Set matching color so we |
| 1260 | + // don't see a line. |
| 1261 | + height: 0.001 |
| 1262 | + width: main.width |
| 1263 | + color: main.parent.color |
| 1264 | + |
| 1265 | + property alias password: passwordTextField.text |
| 1266 | + property alias twoFactorVisible: twoFactorUI.visible |
| 1267 | + property alias twoFactorCode: twoFactorTextField.text |
| 1268 | + |
| 1269 | + Column { |
| 1270 | + spacing: units.gu(2) |
| 1271 | + |
| 1272 | + Label { |
| 1273 | + text: "I am a returning user and my password is:" |
| 1274 | + fontSize: "small" |
| 1275 | + } |
| 1276 | + TextField { |
| 1277 | + id: passwordTextField |
| 1278 | + |
| 1279 | + placeholderText: "Your password" |
| 1280 | + echoMode: TextInput.Password |
| 1281 | + width: main.width - (2 * main.anchors.margins) |
| 1282 | + |
| 1283 | + Keys.onReturnPressed: main.processForm(); |
| 1284 | + } |
| 1285 | + |
| 1286 | + Label { |
| 1287 | + text: '<a href="https://login.ubuntu.com/+forgot_password"><span style="color: #dd4814;">Forgotten your password?</span></a>' |
| 1288 | + textFormat: Text.RichText |
| 1289 | + fontSize: "small" |
| 1290 | + onLinkActivated: { Qt.openUrlExternally(link); } |
| 1291 | + } |
| 1292 | + |
| 1293 | + |
| 1294 | + Column { |
| 1295 | + id: twoFactorUI |
| 1296 | + spacing: units.gu(2) |
| 1297 | + height: 1 |
| 1298 | + width: parent.width |
| 1299 | + visible: false |
| 1300 | + |
| 1301 | + Label { |
| 1302 | + text: "Type your verification code:" |
| 1303 | + fontSize: "small" |
| 1304 | + } |
| 1305 | + |
| 1306 | + TextField { |
| 1307 | + id: twoFactorTextField |
| 1308 | + placeholderText: "2-factor device code" |
| 1309 | + echoMode: TextInput.Password |
| 1310 | + focus: true |
| 1311 | + width: main.width - (2 * main.anchors.margins) |
| 1312 | + Keys.onReturnPressed: { |
| 1313 | + main.processForm(); |
| 1314 | + } |
| 1315 | + } |
| 1316 | + |
| 1317 | + Label { |
| 1318 | + text: '<a href="https://login.ubuntu.com/+device-help"><span style="color: #dd4814;">Authentication Device Help</span></a>' |
| 1319 | + textFormat: Text.RichText |
| 1320 | + fontSize: "small" |
| 1321 | + onLinkActivated: { Qt.openUrlExternally(link); } |
| 1322 | + } |
| 1323 | + |
| 1324 | + } // Rectangle : twoFactorUI |
| 1325 | + |
| 1326 | + |
| 1327 | + }// Column |
| 1328 | + |
| 1329 | + function resetUI() { |
| 1330 | + twoFactorUI.visible = false; |
| 1331 | + twoFactorTextField.text = ""; |
| 1332 | + passwordTextField.text = ""; |
| 1333 | + } |
| 1334 | + |
| 1335 | + function validateInput() { |
| 1336 | + var passwordLongEnough = passwordTextField.text.length > 7; |
| 1337 | + passwordTextField.errorHighlight = !passwordLongEnough; |
| 1338 | + if (!passwordLongEnough) { |
| 1339 | + main.showError("Password must be at least 8 characters long."); |
| 1340 | + } |
| 1341 | + |
| 1342 | + if (!twoFactorUI.visible) { |
| 1343 | + return passwordLongEnough; |
| 1344 | + } |
| 1345 | + |
| 1346 | + var twoFactorLongEnough = twoFactorTextField.text.length > 0; |
| 1347 | + twoFactorTextField.errorHighlight = !twoFactorLongEnough; |
| 1348 | + if(!twoFactorLongEnough){ |
| 1349 | + main.showError("Please enter your two-factor device code."); |
| 1350 | + } |
| 1351 | + return passwordLongEnough && twoFactorLongEnough; |
| 1352 | + } |
| 1353 | +} |
| 1354 | |
| 1355 | === added file 'online-accounts-provider/Main.qml' |
| 1356 | --- online-accounts-provider/Main.qml 1970-01-01 00:00:00 +0000 |
| 1357 | +++ online-accounts-provider/Main.qml 2013-08-27 20:30:52 +0000 |
| 1358 | @@ -0,0 +1,50 @@ |
| 1359 | +/* |
| 1360 | + * Copyright (C) 2013 Canonical Ltd. |
| 1361 | + * |
| 1362 | + * |
| 1363 | + * This program is free software: you can redistribute it and/or modify it |
| 1364 | + * under the terms of the GNU General Public License version 3, as published |
| 1365 | + * by the Free Software Foundation. |
| 1366 | + * |
| 1367 | + * This program is distributed in the hope that it will be useful, but |
| 1368 | + * WITHOUT ANY WARRANTY; without even the implied warranties of |
| 1369 | + * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR |
| 1370 | + * PURPOSE. See the GNU General Public License for more details. |
| 1371 | + * |
| 1372 | + * You should have received a copy of the GNU General Public License along |
| 1373 | + * with this program. If not, see <http://www.gnu.org/licenses/>. |
| 1374 | + */ |
| 1375 | + |
| 1376 | +import QtQuick 2.0 |
| 1377 | +import Ubuntu.Components 0.1 |
| 1378 | +import Ubuntu.OnlineAccounts 0.1 |
| 1379 | + |
| 1380 | +Flickable { |
| 1381 | + id: root |
| 1382 | + |
| 1383 | + property url newAccountUrl: "NewAccount.qml" |
| 1384 | + property url existingAccountUrl: "ExistingAccount.qml" |
| 1385 | + property Component newAccountComponent: null |
| 1386 | + property Component existingAccountComponent: null |
| 1387 | + |
| 1388 | + property alias source: loader.source |
| 1389 | + |
| 1390 | + signal finished |
| 1391 | + |
| 1392 | + anchors.left: parent.left |
| 1393 | + anchors.right: parent.right |
| 1394 | + contentHeight: contentItem.childrenRect.height |
| 1395 | + |
| 1396 | + Loader { |
| 1397 | + id: loader |
| 1398 | + anchors.left: parent.left |
| 1399 | + anchors.right: parent.right |
| 1400 | + source: sourceComponent === null ? (account.accountId != 0 ? existingAccountUrl : newAccountUrl) : "" |
| 1401 | + sourceComponent: account.accountId != 0 ? existingAccountComponent : newAccountComponent |
| 1402 | + |
| 1403 | + Connections { |
| 1404 | + target: loader.item |
| 1405 | + onFinished: root.finished() |
| 1406 | + } |
| 1407 | + } |
| 1408 | +} |
| 1409 | |
| 1410 | === added file 'online-accounts-provider/NewAccount.qml' |
| 1411 | --- online-accounts-provider/NewAccount.qml 1970-01-01 00:00:00 +0000 |
| 1412 | +++ online-accounts-provider/NewAccount.qml 2013-08-27 20:30:52 +0000 |
| 1413 | @@ -0,0 +1,257 @@ |
| 1414 | +/* |
| 1415 | + * Copyright (C) 2013 Canonical Ltd. |
| 1416 | + * |
| 1417 | + * |
| 1418 | + * This program is free software: you can redistribute it and/or modify it |
| 1419 | + * under the terms of the GNU General Public License version 3, as published |
| 1420 | + * by the Free Software Foundation. |
| 1421 | + * |
| 1422 | + * This program is distributed in the hope that it will be useful, but |
| 1423 | + * WITHOUT ANY WARRANTY; without even the implied warranties of |
| 1424 | + * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR |
| 1425 | + * PURPOSE. See the GNU General Public License for more details. |
| 1426 | + * |
| 1427 | + * You should have received a copy of the GNU General Public License along |
| 1428 | + * with this program. If not, see <http://www.gnu.org/licenses/>. |
| 1429 | + */ |
| 1430 | + |
| 1431 | +import QtQuick 2.0 |
| 1432 | +import Ubuntu.Components 0.1 |
| 1433 | +import UbuntuOne 1.0 |
| 1434 | +import Ubuntu.OnlineAccounts 0.1 |
| 1435 | + |
| 1436 | + |
| 1437 | +Column { |
| 1438 | + id: main |
| 1439 | + |
| 1440 | + //property variant authenticationParameters: null |
| 1441 | + |
| 1442 | + property bool isNewAccount: false |
| 1443 | + property variant __account: account |
| 1444 | +// unneeded:? property alias globalAccountService: globalAccountSettings |
| 1445 | + |
| 1446 | + |
| 1447 | + state: "login" // or "register" or "twofactor" |
| 1448 | + property var currentVisible: loginForm |
| 1449 | + property var formValid: false |
| 1450 | + |
| 1451 | + signal finished |
| 1452 | + |
| 1453 | + anchors.left: parent.left |
| 1454 | + anchors.right: parent.right |
| 1455 | + |
| 1456 | + Component.onCompleted: { |
| 1457 | + isNewAccount = (account.accountId === 0); |
| 1458 | + resetUI(); |
| 1459 | + } |
| 1460 | + |
| 1461 | + Label { |
| 1462 | + id: title |
| 1463 | + text: "One account to log in to everything on Ubuntu" |
| 1464 | + fontSize: "medium" |
| 1465 | + color: UbuntuColors.coolGrey |
| 1466 | + anchors.left: parent.left |
| 1467 | + anchors.right: parent.right |
| 1468 | + anchors.margins: parent.anchors.margins |
| 1469 | + } |
| 1470 | + |
| 1471 | + Label { |
| 1472 | + id: errorLabel |
| 1473 | + text: "" |
| 1474 | + font.bold: true |
| 1475 | + color: "red" |
| 1476 | + visible: false |
| 1477 | + |
| 1478 | + anchors.left: parent.left |
| 1479 | + anchors.right: parent.right |
| 1480 | + anchors.margins: parent.anchors.margins |
| 1481 | + |
| 1482 | + } |
| 1483 | + |
| 1484 | + Label { |
| 1485 | + text: "Please type your email:" |
| 1486 | + fontSize: "large" |
| 1487 | + |
| 1488 | + anchors.left: parent.left |
| 1489 | + anchors.right: parent.right |
| 1490 | + anchors.margins: parent.anchors.margins |
| 1491 | + } |
| 1492 | + |
| 1493 | + TextField { |
| 1494 | + id: emailTextField |
| 1495 | + placeholderText: "Your email" |
| 1496 | + focus: true; |
| 1497 | + |
| 1498 | + width: main.width - (2 * main.anchors.margins) |
| 1499 | + anchors.left: parent.left |
| 1500 | + anchors.margins: parent.anchors.margins |
| 1501 | + } |
| 1502 | + |
| 1503 | + Row { |
| 1504 | + spacing: units.gu(2) |
| 1505 | + Switch { |
| 1506 | + id: newUserToggleSwitch |
| 1507 | + checked: false |
| 1508 | + |
| 1509 | + onCheckedChanged: { |
| 1510 | + toggleNewUser(); |
| 1511 | + } |
| 1512 | + } |
| 1513 | + Label { |
| 1514 | + anchors.verticalCenter: newUserToggleSwitch.verticalCenter |
| 1515 | + text: "I am a new Ubuntu One user" |
| 1516 | + fontSize: "large" |
| 1517 | + } |
| 1518 | + anchors.left: parent.left |
| 1519 | + anchors.right: parent.right |
| 1520 | + anchors.margins: parent.anchors.margins |
| 1521 | + |
| 1522 | + } // Row |
| 1523 | + |
| 1524 | + LoginForm { |
| 1525 | + id: loginForm |
| 1526 | + visible: true |
| 1527 | + |
| 1528 | + anchors.left: parent.left |
| 1529 | + anchors.right: parent.right |
| 1530 | + anchors.margins: parent.anchors.margins |
| 1531 | + } |
| 1532 | + |
| 1533 | + RegisterForm { |
| 1534 | + id: registerForm |
| 1535 | + visible: false |
| 1536 | + |
| 1537 | + anchors.left: parent.left |
| 1538 | + anchors.right: parent.right |
| 1539 | + anchors.margins: parent.anchors.margins |
| 1540 | + } |
| 1541 | + |
| 1542 | + Rectangle { |
| 1543 | + id: loadingOverlay |
| 1544 | + opacity: 0.6 |
| 1545 | + color: "white" |
| 1546 | + visible: false |
| 1547 | + width: main.width |
| 1548 | + height: main.height |
| 1549 | + //TODO: anchors.centerIn: main.parent |
| 1550 | + |
| 1551 | + ActivityIndicator { |
| 1552 | + id: activity |
| 1553 | + //TODO: anchors.centerIn: parent |
| 1554 | + running: true |
| 1555 | + } |
| 1556 | + } |
| 1557 | + |
| 1558 | + // ------------------------------------------------- |
| 1559 | + |
| 1560 | + UbuntuOneCredentialsService { |
| 1561 | + id: u1credservice |
| 1562 | + |
| 1563 | + onLoginOrRegisterSuccess: { |
| 1564 | + handleSuccess(); |
| 1565 | + } |
| 1566 | + |
| 1567 | + onTwoFactorAuthRequired: { |
| 1568 | + showTwoFactorUI(); |
| 1569 | + } |
| 1570 | + |
| 1571 | + onLoginOrRegisterError: { |
| 1572 | + if (errorMessage == "Invalid request data") { |
| 1573 | + errorMessage = "Please enter a valid email address."; |
| 1574 | + } |
| 1575 | + showError(errorMessage); |
| 1576 | + } |
| 1577 | + } |
| 1578 | + |
| 1579 | + function resetUI() { |
| 1580 | + errorLabel.visible = false; |
| 1581 | + emailTextField.text = ""; |
| 1582 | + loginForm.resetUI() |
| 1583 | + registerForm.resetUI(); |
| 1584 | + newUserToggleSwitch.checked = false; |
| 1585 | + state = "login"; |
| 1586 | + switchTo(loginForm); |
| 1587 | + formValid = false; |
| 1588 | + } |
| 1589 | + |
| 1590 | + function showError(message) { |
| 1591 | + errorLabel.text = message; |
| 1592 | + errorLabel.visible = true; |
| 1593 | + loadingOverlay.visible = false; |
| 1594 | + } |
| 1595 | + |
| 1596 | + function switchTo(newVisible) { |
| 1597 | + currentVisible.visible = false; |
| 1598 | + newVisible.visible = true; |
| 1599 | + currentVisible = newVisible; |
| 1600 | + } |
| 1601 | + |
| 1602 | + function toggleNewUser() { |
| 1603 | + if(state == "login") { |
| 1604 | + switchTo(registerForm) |
| 1605 | + state = "register"; |
| 1606 | + } else if(state == "register") { |
| 1607 | + switchTo(loginForm) |
| 1608 | + state = "login"; |
| 1609 | + } else { |
| 1610 | + console.debug("unexpected state" + state + "in toggleNewUser"); |
| 1611 | + } |
| 1612 | + } |
| 1613 | + |
| 1614 | + function processForm() { |
| 1615 | + validateInput(); |
| 1616 | + if (!formValid) { |
| 1617 | + return; |
| 1618 | + } |
| 1619 | + loadingOverlay.visible = true; |
| 1620 | + if(state == "login") { |
| 1621 | + var password = loginForm.password; |
| 1622 | + u1credservice.login(emailTextField.text, password); |
| 1623 | + } else if(state == "register") { |
| 1624 | + var password = registerForm.password; |
| 1625 | + var display_name = registerForm.display_name; |
| 1626 | + u1credservice.registerUser(emailTextField.text, password, display_name); |
| 1627 | + } else if(state == "twofactor") { |
| 1628 | + u1credservice.login(emailTextField.text, loginForm.password, loginForm.twoFactorCode); |
| 1629 | + } |
| 1630 | + } |
| 1631 | + |
| 1632 | + function handleSuccess() { |
| 1633 | + loadingOverlay.visible = false; |
| 1634 | + errorLabel.visible = false; |
| 1635 | + resetUI(); |
| 1636 | + finished(); |
| 1637 | + } |
| 1638 | + |
| 1639 | + function showTwoFactorUI() { |
| 1640 | + loadingOverlay.visible = false; |
| 1641 | + if(state != "login") { |
| 1642 | + console.log("Error: did not expect two factor request from register"); |
| 1643 | + showError("An internal error occurred. Please try again later."); |
| 1644 | + return; |
| 1645 | + } |
| 1646 | + errorLabel.visible = false; |
| 1647 | + state = "twofactor"; |
| 1648 | + loginForm.twoFactorVisible = true; |
| 1649 | + formValid = false; |
| 1650 | + } |
| 1651 | + |
| 1652 | + function validateInput() { |
| 1653 | + formValid = emailTextField.acceptableInput; |
| 1654 | + if(!formValid) { |
| 1655 | + showError("Please enter a valid email address."); |
| 1656 | + return; |
| 1657 | + } |
| 1658 | + |
| 1659 | + if(state == "login" || state == "twofactor") { |
| 1660 | + formValid &= loginForm.validateInput(); |
| 1661 | + } else { |
| 1662 | + formValid &= registerForm.validateInput(); |
| 1663 | + } |
| 1664 | + |
| 1665 | + if(formValid) { |
| 1666 | + errorLabel.visible = false; |
| 1667 | + } |
| 1668 | + } |
| 1669 | + |
| 1670 | +} |
| 1671 | |
| 1672 | === added file 'online-accounts-provider/RegisterForm.qml' |
| 1673 | --- online-accounts-provider/RegisterForm.qml 1970-01-01 00:00:00 +0000 |
| 1674 | +++ online-accounts-provider/RegisterForm.qml 2013-08-27 20:30:52 +0000 |
| 1675 | @@ -0,0 +1,97 @@ |
| 1676 | +import QtQuick 2.0 |
| 1677 | +import Ubuntu.Components 0.1 |
| 1678 | + |
| 1679 | +Rectangle { |
| 1680 | + // Set a non-zero height and width so that the parent Column in |
| 1681 | + // CredentialsUI lays out correctly. Set matching color so we |
| 1682 | + // don't see a 1px line. |
| 1683 | + height: 0.001 |
| 1684 | + width: main.width |
| 1685 | + color: main.parent.color |
| 1686 | + |
| 1687 | + property alias password: passwordTextField.text |
| 1688 | + property alias display_name: nameTextField.text |
| 1689 | + |
| 1690 | + |
| 1691 | + Column { |
| 1692 | + spacing: units.gu(2) |
| 1693 | + |
| 1694 | + Label { |
| 1695 | + id: subtitle |
| 1696 | + fontSize: "small" |
| 1697 | + text: "Please tell us your name and choose a password." |
| 1698 | + } |
| 1699 | + |
| 1700 | + TextField { |
| 1701 | + id: nameTextField |
| 1702 | + placeholderText: "Your name" |
| 1703 | + width: main.width - (2 * main.anchors.margins) |
| 1704 | + } |
| 1705 | + |
| 1706 | + TextField { |
| 1707 | + id: passwordTextField |
| 1708 | + placeholderText: "Password with at least 8 characters" |
| 1709 | + echoMode: TextInput.Password |
| 1710 | + width: main.width - (2 * main.anchors.margins) |
| 1711 | + } |
| 1712 | + |
| 1713 | + TextField { |
| 1714 | + id: confirmPasswordTextField |
| 1715 | + placeholderText: "Re-type password" |
| 1716 | + echoMode: TextInput.Password |
| 1717 | + width: main.width - (2 * main.anchors.margins) |
| 1718 | + } |
| 1719 | + Row { |
| 1720 | + spacing: units.gu(2) |
| 1721 | + CheckBox { |
| 1722 | + id: termsAndConditionsCheckBox |
| 1723 | + checked: false |
| 1724 | + } |
| 1725 | + |
| 1726 | + Label { |
| 1727 | + anchors.verticalCenter: termsAndConditionsCheckBox.verticalCenter |
| 1728 | + text: "I agree to the <a href='http://one.ubuntu.com/terms/'>Ubuntu One Terms and Conditions</a>" |
| 1729 | + fontSize: "small" |
| 1730 | + onLinkActivated: { Qt.openUrlExternally(link); } |
| 1731 | + } |
| 1732 | + } |
| 1733 | + } |
| 1734 | + |
| 1735 | + function resetUI() { |
| 1736 | + termsAndConditionsCheckBox.checked = false; |
| 1737 | + nameTextField.text = ""; |
| 1738 | + passwordTextField.text = ""; |
| 1739 | + confirmPasswordTextField.text = ""; |
| 1740 | + } |
| 1741 | + |
| 1742 | + function validateInput() { |
| 1743 | + var valid = termsAndConditionsCheckBox.checked; |
| 1744 | + if (!valid) { |
| 1745 | + main.showError("Please accept the terms and conditions by checking the box."); |
| 1746 | + return false; |
| 1747 | + } |
| 1748 | + |
| 1749 | + var nameOK = (nameTextField.text != ""); |
| 1750 | + nameTextField.errorHighlight = !nameOK; |
| 1751 | + if (!nameOK) { |
| 1752 | + main.showError("Please enter a name."); |
| 1753 | + return false; |
| 1754 | + } |
| 1755 | + |
| 1756 | + var passwordLongEnough = passwordTextField.length > 7; |
| 1757 | + passwordTextField.errorHighlight = !passwordLongEnough; |
| 1758 | + if (!passwordLongEnough) { |
| 1759 | + main.showError("Your password must be at least 8 characters long."); |
| 1760 | + return false; |
| 1761 | + } |
| 1762 | + |
| 1763 | + var passwordsMatch = (passwordTextField.text == confirmPasswordTextField.text); |
| 1764 | + confirmPasswordTextField.errorHighlight = !passwordsMatch; |
| 1765 | + if (!passwordsMatch) { |
| 1766 | + main.showError("The passwords do not match."); |
| 1767 | + return false; |
| 1768 | + } |
| 1769 | + |
| 1770 | + return true; |
| 1771 | + } |
| 1772 | +} |
| 1773 | |
| 1774 | === added directory 'qml-credentials-service' |
| 1775 | === added file 'qml-credentials-service/CMakeLists.txt' |
| 1776 | --- qml-credentials-service/CMakeLists.txt 1970-01-01 00:00:00 +0000 |
| 1777 | +++ qml-credentials-service/CMakeLists.txt 2013-08-27 20:30:52 +0000 |
| 1778 | @@ -0,0 +1,25 @@ |
| 1779 | +# Qt5 bits |
| 1780 | +set (CMAKE_INCLUDE_CURRENT_DIR ON) |
| 1781 | +set (CMAKE_AUTOMOC ON) |
| 1782 | +find_package(Qt5Core REQUIRED) |
| 1783 | + |
| 1784 | +file (GLOB CPP_SOURCES *.cpp) |
| 1785 | + |
| 1786 | +configure_file (qmldir.template qmldir) |
| 1787 | + |
| 1788 | +add_library (${QML_PLUGIN_NAME} MODULE ${CPP_SOURCES}) |
| 1789 | +qt5_use_modules (${QML_PLUGIN_NAME} Core Widgets Quick Qml ) |
| 1790 | +target_link_libraries (${QML_PLUGIN_NAME} |
| 1791 | + -Wl,-rpath,${CMAKE_BINARY_DIR}/libubuntuoneauth |
| 1792 | + -L${CMAKE_BINARY_DIR}/libubuntuoneauth |
| 1793 | + ${AUTH_LIB_NAME} |
| 1794 | +) |
| 1795 | + |
| 1796 | +install (FILES ${CMAKE_CURRENT_BINARY_DIR}/qmldir DESTINATION ${QML_MODULE_INSTALL_DIR}/${QML_MODULE_NAME} ) |
| 1797 | + |
| 1798 | +install (TARGETS ${QML_PLUGIN_NAME} |
| 1799 | + LIBRARY DESTINATION ${QML_MODULE_INSTALL_DIR}/${QML_MODULE_NAME} |
| 1800 | + NAMELINK_SKIP |
| 1801 | +) |
| 1802 | + |
| 1803 | +install (CODE "execute_process(COMMAND qmlplugindump ${QML_MODULE_NAME} ${QML_PLUGIN_API_VERSION} ${CMAKE_INSTALL_PREFIX}/${QML_MODULE_INSTALL_DIR} OUTPUT_FILE ${CMAKE_INSTALL_PREFIX}/${QML_MODULE_INSTALL_DIR}/${QML_MODULE_NAME}/${QML_MODULE_NAME}.qmltypes)") |
| 1804 | |
| 1805 | === added file 'qml-credentials-service/README' |
| 1806 | --- qml-credentials-service/README 1970-01-01 00:00:00 +0000 |
| 1807 | +++ qml-credentials-service/README 2013-08-27 20:30:52 +0000 |
| 1808 | @@ -0,0 +1,31 @@ |
| 1809 | + |
| 1810 | +Ubuntu One Credentials QML Plugin |
| 1811 | + |
| 1812 | +This plugin provides the UbuntuOne QML Component, which exposes the |
| 1813 | +CredentialsService plugin, allowing you to display login/register UI |
| 1814 | +and check for credentials and sign URLs. |
| 1815 | + |
| 1816 | + |
| 1817 | +HACKING |
| 1818 | + |
| 1819 | +An example for embedding the UI provided by the plugin is in examples/embedding.qml |
| 1820 | + |
| 1821 | +The CMake setup only builds the complete QML component at install, and |
| 1822 | +the qmltypes file required by qtcreator is also only built at install, |
| 1823 | +so to test without installing to a system location, you will need to |
| 1824 | +do something like the following: |
| 1825 | + |
| 1826 | +mkdir -p build |
| 1827 | +cd build |
| 1828 | +cmake -D .. -DCMAKE_INSTALL_PREFIX:PATH=/tmp/installtemp .. |
| 1829 | +make all install |
| 1830 | + |
| 1831 | +Then, when running, point LD_LIBRARY_PATH to the install lib dir so |
| 1832 | +that libubuntuonecredentials is discoverable. Here's an example of running qmlscene to try the example code: |
| 1833 | + |
| 1834 | +LD_LIBRARY_PATH=/tmp/installtemp/lib/ qmlscene -I /tmp/installtemp/lib/qt5/qml/ qml-credentials-service/examples/embeddingMain.qml |
| 1835 | + |
| 1836 | + |
| 1837 | + |
| 1838 | + |
| 1839 | + |
| 1840 | |
| 1841 | === added directory 'qml-credentials-service/examples' |
| 1842 | === added file 'qml-credentials-service/examples/embeddingMain.qml' |
| 1843 | --- qml-credentials-service/examples/embeddingMain.qml 1970-01-01 00:00:00 +0000 |
| 1844 | +++ qml-credentials-service/examples/embeddingMain.qml 2013-08-27 20:30:52 +0000 |
| 1845 | @@ -0,0 +1,129 @@ |
| 1846 | +import QtQuick 2.0 |
| 1847 | +import Ubuntu.Components 0.1 |
| 1848 | +import UbuntuOne 1.0 |
| 1849 | + |
| 1850 | +Rectangle { |
| 1851 | + id: exampleMain |
| 1852 | + width: units.gu(100) |
| 1853 | + height: units.gu(120) |
| 1854 | + color: UbuntuColors.coolGrey |
| 1855 | + |
| 1856 | + Column { |
| 1857 | + spacing: units.gu(2) |
| 1858 | + anchors.fill: parent |
| 1859 | + |
| 1860 | + add: Transition { |
| 1861 | + NumberAnimation { properties: "opacity"; easing.type: Easing.OutQuad; duration: 1000} |
| 1862 | + } |
| 1863 | + |
| 1864 | + Row { |
| 1865 | + anchors.left: parent.left |
| 1866 | + anchors.margins: units.gu(2) |
| 1867 | + spacing: units.gu(2) |
| 1868 | + |
| 1869 | + Switch { |
| 1870 | + id: showCredsUISwitch |
| 1871 | + checked: true |
| 1872 | + } |
| 1873 | + |
| 1874 | + Label { |
| 1875 | + id: label |
| 1876 | + color: "white" |
| 1877 | + text: "Show Creds UI" |
| 1878 | + anchors.verticalCenter: showCredsUISwitch.verticalCenter |
| 1879 | + } |
| 1880 | + |
| 1881 | + Label { |
| 1882 | + id: statusLabel |
| 1883 | + color: "white" |
| 1884 | + text: "" |
| 1885 | + anchors.verticalCenter: showCredsUISwitch.verticalCenter |
| 1886 | + } |
| 1887 | + } |
| 1888 | + |
| 1889 | + // Here is where we've embedded the UI for UbuntuOne login and register. |
| 1890 | + // Note that you must declare some width and height for the layout to work. |
| 1891 | + |
| 1892 | + CredentialsUI { |
| 1893 | + id: credsUI |
| 1894 | + |
| 1895 | + width: parent.width * 0.80 |
| 1896 | + height: (parent.height - showCredsUISwitch.height) * 0.80 |
| 1897 | + anchors.horizontalCenter: parent.horizontalCenter |
| 1898 | + visible: showCredsUISwitch.checked |
| 1899 | + |
| 1900 | + onUserCancelled: { |
| 1901 | + showCredsUISwitch.checked = false; |
| 1902 | + statusLabel.text = "Login/Register cancelled by user"; |
| 1903 | + credsUI.resetUI(); |
| 1904 | + } |
| 1905 | + |
| 1906 | + onSucceeded: { |
| 1907 | + showCredsUISwitch.checked = false; |
| 1908 | + statusLabel.text = "Login/Register succeeded"; |
| 1909 | + credsUI.resetUI(); |
| 1910 | + } |
| 1911 | + } |
| 1912 | + |
| 1913 | + Label { |
| 1914 | + id: infoLabel |
| 1915 | + text: "Press this button to check for credentials in local keyring:" |
| 1916 | + color: "white" |
| 1917 | + } |
| 1918 | + |
| 1919 | + Button { |
| 1920 | + id: btnCancel |
| 1921 | + text: "Check existing creds" |
| 1922 | + color: "#1c091a" |
| 1923 | + onClicked: { |
| 1924 | + u1credservice.checkCredentials(); |
| 1925 | + } |
| 1926 | + } |
| 1927 | + |
| 1928 | + Label { |
| 1929 | + id: revokeLabel |
| 1930 | + text: "Press this button to delete the credentials in local keyring:" |
| 1931 | + color: "white" |
| 1932 | + } |
| 1933 | + |
| 1934 | + Button { |
| 1935 | + id: btnRevoke |
| 1936 | + text: "Invalidate existing creds" |
| 1937 | + color: "#1c091a" |
| 1938 | + onClicked: { |
| 1939 | + u1credservice.invalidateCredentials(); |
| 1940 | + } |
| 1941 | + } |
| 1942 | + |
| 1943 | + } // Column |
| 1944 | + |
| 1945 | + /* Below, an example of how to use the service without showing UI, |
| 1946 | + just to test if there is a local credential already, and sign a |
| 1947 | + url with it, if it does exist.*/ |
| 1948 | + |
| 1949 | + UbuntuOneCredentialsService { |
| 1950 | + id: u1credservice |
| 1951 | + |
| 1952 | + onCredentialsFound: { |
| 1953 | + infoLabel.text = "Credentials Found. signing a url."; |
| 1954 | + signUrl("http://server", "GET"); |
| 1955 | + } |
| 1956 | + |
| 1957 | + onUrlSigned: { |
| 1958 | + infoLabel.text = "signed url is "+ signedUrl; |
| 1959 | + } |
| 1960 | + |
| 1961 | + onUrlSigningError: { |
| 1962 | + infoLabel.text = "signing error:" + errorMessage; |
| 1963 | + } |
| 1964 | + |
| 1965 | + onCredentialsNotFound: { |
| 1966 | + infoLabel.text = "No Credentials Found."; |
| 1967 | + signUrl("http://server", "GET"); // xfail |
| 1968 | + } |
| 1969 | + |
| 1970 | + onCredentialsDeleted: { |
| 1971 | + revokeLabel.text = "Deleted Credentials successfully"; |
| 1972 | + } |
| 1973 | + } |
| 1974 | +} // UbuntuShape |
| 1975 | |
| 1976 | === added file 'qml-credentials-service/qmldir.template' |
| 1977 | --- qml-credentials-service/qmldir.template 1970-01-01 00:00:00 +0000 |
| 1978 | +++ qml-credentials-service/qmldir.template 2013-08-27 20:30:52 +0000 |
| 1979 | @@ -0,0 +1,3 @@ |
| 1980 | +module @QML_MODULE_NAME@ |
| 1981 | +plugin @QML_PLUGIN_NAME@ |
| 1982 | +typeinfo @QML_MODULE_NAME@.qmltypes |
| 1983 | |
| 1984 | === added file 'qml-credentials-service/ubuntuone_credentials_plugin.cpp' |
| 1985 | --- qml-credentials-service/ubuntuone_credentials_plugin.cpp 1970-01-01 00:00:00 +0000 |
| 1986 | +++ qml-credentials-service/ubuntuone_credentials_plugin.cpp 2013-08-27 20:30:52 +0000 |
| 1987 | @@ -0,0 +1,11 @@ |
| 1988 | +#include "ubuntuone_credentials_plugin.h" |
| 1989 | +#include "ubuntuone_credentials_service.h" |
| 1990 | + |
| 1991 | +#include <qqml.h> |
| 1992 | + |
| 1993 | +void UbuntuOneCredentialsPlugin::registerTypes(const char *uri) |
| 1994 | +{ |
| 1995 | + qmlRegisterType<UbuntuOneCredentialsService>(uri, 1, 0, "UbuntuOneCredentialsService"); |
| 1996 | +} |
| 1997 | + |
| 1998 | + |
| 1999 | |
| 2000 | === added file 'qml-credentials-service/ubuntuone_credentials_plugin.h' |
| 2001 | --- qml-credentials-service/ubuntuone_credentials_plugin.h 1970-01-01 00:00:00 +0000 |
| 2002 | +++ qml-credentials-service/ubuntuone_credentials_plugin.h 2013-08-27 20:30:52 +0000 |
| 2003 | @@ -0,0 +1,16 @@ |
| 2004 | +#ifndef UBUNTUONECREDENTIALS_PLUGIN_H |
| 2005 | +#define UBUNTUONECREDENTIALS_PLUGIN_H |
| 2006 | + |
| 2007 | +#include <QQmlExtensionPlugin> |
| 2008 | + |
| 2009 | +class UbuntuOneCredentialsPlugin : public QQmlExtensionPlugin |
| 2010 | +{ |
| 2011 | + Q_OBJECT |
| 2012 | + Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QQmlExtensionInterface") |
| 2013 | + |
| 2014 | +public: |
| 2015 | + void registerTypes(const char *uri); |
| 2016 | +}; |
| 2017 | + |
| 2018 | +#endif // UBUNTUONECREDENTIALS_PLUGIN_H |
| 2019 | + |
| 2020 | |
| 2021 | === added file 'qml-credentials-service/ubuntuone_credentials_service.cpp' |
| 2022 | --- qml-credentials-service/ubuntuone_credentials_service.cpp 1970-01-01 00:00:00 +0000 |
| 2023 | +++ qml-credentials-service/ubuntuone_credentials_service.cpp 2013-08-27 20:30:52 +0000 |
| 2024 | @@ -0,0 +1,157 @@ |
| 2025 | +#include "ubuntuone_credentials_service.h" |
| 2026 | +#include <QDebug> |
| 2027 | + |
| 2028 | +UbuntuOneCredentialsService::UbuntuOneCredentialsService(QQuickItem *parent): |
| 2029 | + QQuickItem(parent) |
| 2030 | +{ |
| 2031 | + _state = IDLE; |
| 2032 | + QObject::connect(&(this->_service), SIGNAL(credentialsFound(Token)), |
| 2033 | + this, SLOT(handleCredentialsFound(Token))); |
| 2034 | + QObject::connect(&(this->_service), SIGNAL(credentialsNotFound()), |
| 2035 | + this, SLOT(handleCredentialsNotFound())); |
| 2036 | + QObject::connect(&(this->_service), SIGNAL(credentialsStored()), |
| 2037 | + this, SLOT(handleCredentialsStored())); |
| 2038 | + QObject::connect(&(this->_service), SIGNAL(credentialsDeleted()), |
| 2039 | + this, SLOT(handleCredentialsDeleted())); |
| 2040 | + |
| 2041 | + QObject::connect(&(this->_service), SIGNAL(twoFactorAuthRequired()), |
| 2042 | + this, SLOT(handleTwoFactorAuthRequired())); |
| 2043 | + |
| 2044 | + QObject::connect(&(this->_service), SIGNAL(requestFailed(ErrorResponse)), |
| 2045 | + this, SLOT(handleError(ErrorResponse))); |
| 2046 | +} |
| 2047 | + |
| 2048 | +UbuntuOneCredentialsService::~UbuntuOneCredentialsService() |
| 2049 | +{ |
| 2050 | +} |
| 2051 | + |
| 2052 | + |
| 2053 | +// public API (Q_INVOKABLE) |
| 2054 | + |
| 2055 | +void UbuntuOneCredentialsService::checkCredentials() |
| 2056 | +{ |
| 2057 | + Q_ASSERT(_state == IDLE); |
| 2058 | + _state = CHECK; |
| 2059 | + _service.getCredentials(); |
| 2060 | +} |
| 2061 | + |
| 2062 | +void UbuntuOneCredentialsService::invalidateCredentials() |
| 2063 | +{ |
| 2064 | + Q_ASSERT(_state == IDLE); |
| 2065 | + _state = DELETE; |
| 2066 | + _service.invalidateCredentials(); |
| 2067 | +} |
| 2068 | + |
| 2069 | +void UbuntuOneCredentialsService::login(QString email, QString password, QString twoFactorCode) |
| 2070 | +{ |
| 2071 | + Q_ASSERT(_state == IDLE); |
| 2072 | + _state = LOGIN; |
| 2073 | + _service.login(email, password, twoFactorCode); |
| 2074 | +} |
| 2075 | + |
| 2076 | +void UbuntuOneCredentialsService::registerUser(QString email, QString password, QString name) |
| 2077 | +{ |
| 2078 | + Q_ASSERT(_state == IDLE); |
| 2079 | + _state = REGISTER; |
| 2080 | + _service.registerUser(email, password, name); |
| 2081 | +} |
| 2082 | + |
| 2083 | +// calling signUrl with no credentials stored will emit an error |
| 2084 | +void UbuntuOneCredentialsService::signUrl(const QString url, const QString method, bool asQuery) |
| 2085 | +{ |
| 2086 | + Q_ASSERT(_state == IDLE); |
| 2087 | + _state = SIGN; |
| 2088 | + _sign_url = url; |
| 2089 | + _sign_method = method; |
| 2090 | + _sign_asQuery = asQuery; |
| 2091 | + _service.getCredentials(); |
| 2092 | +} |
| 2093 | + |
| 2094 | +// signal handlers |
| 2095 | + |
| 2096 | +// credentials found is only sent by _service.getCredentials(), not login or register |
| 2097 | +void UbuntuOneCredentialsService::handleCredentialsFound(const Token& token) |
| 2098 | +{ |
| 2099 | + QString signedUrl; |
| 2100 | + |
| 2101 | + qDebug() << "in UbuntuOneCredentialsService::handleCredentialsFound"; |
| 2102 | + |
| 2103 | + // set state before emitting any signals, as signals happen 'after' transition |
| 2104 | + CredentialsServiceState calledState = _state; |
| 2105 | + _state = IDLE; |
| 2106 | + |
| 2107 | + switch(calledState){ |
| 2108 | + case CHECK: |
| 2109 | + emit credentialsFound(); |
| 2110 | + break; |
| 2111 | + case SIGN: |
| 2112 | + signedUrl = token.signUrl(_sign_url, _sign_method, _sign_asQuery); |
| 2113 | + emit urlSigned(signedUrl); |
| 2114 | + break; |
| 2115 | + default: |
| 2116 | + qDebug() << "UbuntuOneCredentialsService did not expect credentialsFound in state " << calledState; |
| 2117 | + } |
| 2118 | + |
| 2119 | +} |
| 2120 | + |
| 2121 | +void UbuntuOneCredentialsService::handleCredentialsNotFound() |
| 2122 | +{ |
| 2123 | + qDebug() << "in UbuntuOneCredentialsService::handleCredentialsNotFound"; |
| 2124 | + |
| 2125 | + // set state before emitting any signals, as signals happen 'after' transition |
| 2126 | + CredentialsServiceState calledState = _state; |
| 2127 | + _state = IDLE; |
| 2128 | + |
| 2129 | + switch(calledState){ |
| 2130 | + case CHECK: |
| 2131 | + emit credentialsNotFound(); |
| 2132 | + break; |
| 2133 | + case SIGN: |
| 2134 | + emit urlSigningError(QString("Attempt to sign without credentials in keyring")); |
| 2135 | + break; |
| 2136 | + default: |
| 2137 | + qDebug() << "UbuntuOneCredentialsService did not expect credentialsNotFound in state " << calledState; |
| 2138 | + } |
| 2139 | +} |
| 2140 | + |
| 2141 | +// Credentials stored is signaled when the u1 ping is done after login/register |
| 2142 | +void UbuntuOneCredentialsService::handleCredentialsStored() |
| 2143 | +{ |
| 2144 | + qDebug() << "in UbuntuOneCredentialsService::handleCredentialsStored"; |
| 2145 | + |
| 2146 | + // set state before emitting any signals, as signals happen 'after' transition |
| 2147 | + CredentialsServiceState calledState = _state; |
| 2148 | + _state = IDLE; |
| 2149 | + |
| 2150 | + if (calledState == LOGIN || calledState == REGISTER){ |
| 2151 | + emit loginOrRegisterSuccess(); |
| 2152 | + }else{ |
| 2153 | + qDebug() << "UbuntuOneCredentialsService did not expect credentialsStored in state " << calledState; |
| 2154 | + } |
| 2155 | +} |
| 2156 | + |
| 2157 | +void UbuntuOneCredentialsService::handleCredentialsDeleted() |
| 2158 | +{ |
| 2159 | + qDebug() << "in UbuntuOneCredentialsService::handleCredentialsDeleted"; |
| 2160 | + |
| 2161 | + // set state before emitting any signals, as signals happen 'after' transition |
| 2162 | + CredentialsServiceState calledState = _state; |
| 2163 | + _state = IDLE; |
| 2164 | + |
| 2165 | + if (calledState == DELETE){ |
| 2166 | + emit credentialsDeleted(); |
| 2167 | + }else{ |
| 2168 | + qDebug() << "UbuntuOneCredentialsService did not expect credentialsDeleted in state " << calledState; |
| 2169 | + } |
| 2170 | +} |
| 2171 | + |
| 2172 | +void UbuntuOneCredentialsService::handleTwoFactorAuthRequired(){ |
| 2173 | + _state = IDLE; |
| 2174 | + emit twoFactorAuthRequired(); |
| 2175 | +} |
| 2176 | + |
| 2177 | +void UbuntuOneCredentialsService::handleError(const ErrorResponse& error) |
| 2178 | +{ |
| 2179 | + _state = IDLE; |
| 2180 | + emit loginOrRegisterError(error.message()); |
| 2181 | +} |
| 2182 | |
| 2183 | === added file 'qml-credentials-service/ubuntuone_credentials_service.h' |
| 2184 | --- qml-credentials-service/ubuntuone_credentials_service.h 1970-01-01 00:00:00 +0000 |
| 2185 | +++ qml-credentials-service/ubuntuone_credentials_service.h 2013-08-27 20:30:52 +0000 |
| 2186 | @@ -0,0 +1,62 @@ |
| 2187 | +#ifndef UBUNTUONE_CREDENTIALS_SERVICE_H |
| 2188 | +#define UBUNTUONE_CREDENTIALS_SERVICE_H |
| 2189 | + |
| 2190 | +#include <QQuickItem> |
| 2191 | +#include "ssoservice.h" |
| 2192 | + |
| 2193 | +using namespace UbuntuOne; |
| 2194 | + |
| 2195 | +enum CredentialsServiceState{ |
| 2196 | + IDLE = 0, |
| 2197 | + CHECK, |
| 2198 | + LOGIN, |
| 2199 | + REGISTER, |
| 2200 | + SIGN, |
| 2201 | + DELETE |
| 2202 | +}; |
| 2203 | + |
| 2204 | +class UbuntuOneCredentialsService : public QQuickItem |
| 2205 | +{ |
| 2206 | + Q_OBJECT |
| 2207 | + Q_DISABLE_COPY(UbuntuOneCredentialsService) |
| 2208 | + |
| 2209 | +public: |
| 2210 | + UbuntuOneCredentialsService(QQuickItem *parent = 0); |
| 2211 | + ~UbuntuOneCredentialsService(); |
| 2212 | + |
| 2213 | + Q_INVOKABLE void checkCredentials(); |
| 2214 | + Q_INVOKABLE void invalidateCredentials(); |
| 2215 | + Q_INVOKABLE void login(QString email, QString password, QString twoFactorCode = QString()); |
| 2216 | + Q_INVOKABLE void registerUser(QString email, QString password, QString name); |
| 2217 | + Q_INVOKABLE void signUrl(QString url, QString method, bool asQuery = false); |
| 2218 | + |
| 2219 | +signals: |
| 2220 | + void credentialsFound(); |
| 2221 | + void credentialsNotFound(); |
| 2222 | + void credentialsDeleted(); |
| 2223 | + void loginOrRegisterSuccess(); |
| 2224 | + void loginOrRegisterError(QString errorMessage); |
| 2225 | + void twoFactorAuthRequired(); |
| 2226 | + void urlSigned(QString signedUrl); |
| 2227 | + void urlSigningError(QString errorMessage); |
| 2228 | + |
| 2229 | +private slots: |
| 2230 | + void handleCredentialsFound(const Token&); |
| 2231 | + void handleCredentialsNotFound(); |
| 2232 | + void handleCredentialsStored(); |
| 2233 | + void handleCredentialsDeleted(); |
| 2234 | + void handleTwoFactorAuthRequired(); |
| 2235 | + void handleError(const ErrorResponse&); |
| 2236 | + |
| 2237 | +private: |
| 2238 | + SSOService _service; |
| 2239 | + CredentialsServiceState _state; |
| 2240 | + QString _sign_url; |
| 2241 | + QString _sign_method; |
| 2242 | + bool _sign_asQuery; |
| 2243 | +}; |
| 2244 | + |
| 2245 | +QML_DECLARE_TYPE(UbuntuOneCredentialsService) |
| 2246 | + |
| 2247 | +#endif // UBUNTUONE_CREDENTIALS_SERVICE_H |
| 2248 | + |
| 2249 | |
| 2250 | === added directory 'signon-plugin' |
| 2251 | === added file 'signon-plugin/CMakeLists.txt' |
| 2252 | --- signon-plugin/CMakeLists.txt 1970-01-01 00:00:00 +0000 |
| 2253 | +++ signon-plugin/CMakeLists.txt 2013-08-27 20:30:52 +0000 |
| 2254 | @@ -0,0 +1,37 @@ |
| 2255 | +# Qt5 bits |
| 2256 | +SET (CMAKE_INCLUDE_CURRENT_DIR ON) |
| 2257 | +SET (CMAKE_AUTOMOC ON) |
| 2258 | +find_package(Qt5Core REQUIRED) |
| 2259 | + |
| 2260 | +# The sources for building the library |
| 2261 | +FILE (GLOB SOURCES *.cpp) |
| 2262 | +# HEADERS only includes the public headers for installation. |
| 2263 | +FILE (GLOB HEADERS *.h) |
| 2264 | + |
| 2265 | +find_package (PkgConfig REQUIRED) |
| 2266 | +pkg_check_modules(SIGNON REQUIRED signon-plugins) |
| 2267 | +add_definitions(${SIGNON_CFLAGS} ${SIGNON_CFLAGS_OTHER}) |
| 2268 | + |
| 2269 | +# Workaround for cmake not adding these to automoc properly |
| 2270 | +SET (CMAKE_AUTOMOC_MOC_OPTIONS "${SIGNON_CFLAGS} ${CMAKE_AUTOMOC_MOC_OPTIONS}") |
| 2271 | + |
| 2272 | +# Need the project version here |
| 2273 | +add_definitions("-DPROJECT_VERSION=\"${PROJECT_VERSION}\"") |
| 2274 | + |
| 2275 | +add_library (${SIGNON_PLUGIN_NAME} MODULE ${SOURCES}) |
| 2276 | +qt5_use_modules (${SIGNON_PLUGIN_NAME} Core Xml Network) |
| 2277 | +target_link_libraries (${SIGNON_PLUGIN_NAME} |
| 2278 | + -Wl,-rpath,${CMAKE_BINARY_DIR}/libubuntuoneauth |
| 2279 | + -L${CMAKE_BINARY_DIR}/libubuntuoneauth |
| 2280 | + ${AUTH_LIB_NAME} |
| 2281 | + ${SIGNON_PLUGIN_LDFLAGS} |
| 2282 | +) |
| 2283 | + |
| 2284 | +SET (SIGNON_PLUGIN_INSTALL_DIR lib/signon) |
| 2285 | + |
| 2286 | +INSTALL ( |
| 2287 | + TARGETS ${SIGNON_PLUGIN_NAME} |
| 2288 | + LIBRARY DESTINATION ${SIGNON_PLUGIN_INSTALL_DIR} |
| 2289 | +) |
| 2290 | + |
| 2291 | +#add_subdirectory(tests) |
| 2292 | |
| 2293 | === added file 'signon-plugin/ubuntuone-plugin.cpp' |
| 2294 | --- signon-plugin/ubuntuone-plugin.cpp 1970-01-01 00:00:00 +0000 |
| 2295 | +++ signon-plugin/ubuntuone-plugin.cpp 2013-08-27 20:30:52 +0000 |
| 2296 | @@ -0,0 +1,80 @@ |
| 2297 | +/* |
| 2298 | + * Copyright 2013 Canonical Ltd. |
| 2299 | + * |
| 2300 | + * This library is free software; you can redistribute it and/or |
| 2301 | + * modify it under the terms of version 3 of the GNU Lesser General Public |
| 2302 | + * License as published by the Free Software Foundation. |
| 2303 | + * |
| 2304 | + * This program is distributed in the hope that it will be useful, |
| 2305 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 2306 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| 2307 | + * General Public License for more details. |
| 2308 | + * |
| 2309 | + * You should have received a copy of the GNU Lesser General Public |
| 2310 | + * License along with this library; if not, write to the |
| 2311 | + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, |
| 2312 | + * Boston, MA 02110-1301, USA. |
| 2313 | + */ |
| 2314 | +#include <token.h> |
| 2315 | + |
| 2316 | +#include "ubuntuone-plugin.h" |
| 2317 | + |
| 2318 | + |
| 2319 | +namespace UbuntuOne { |
| 2320 | + |
| 2321 | + SignOnPlugin::SignOnPlugin(QObject *parent) |
| 2322 | + : AuthPluginInterface(parent) |
| 2323 | + { |
| 2324 | + } |
| 2325 | + |
| 2326 | + SignOnPlugin::~SignOnPlugin() |
| 2327 | + { |
| 2328 | + } |
| 2329 | + |
| 2330 | + QString SignOnPlugin::type() const |
| 2331 | + { |
| 2332 | + return QLatin1String("ubuntuone"); |
| 2333 | + } |
| 2334 | + |
| 2335 | + QStringList SignOnPlugin::mechanisms() const |
| 2336 | + { |
| 2337 | + QStringList res = QStringList(QLatin1String("ubuntuone")); |
| 2338 | + |
| 2339 | + return res; |
| 2340 | + } |
| 2341 | + |
| 2342 | + void SignOnPlugin::cancel() |
| 2343 | + { |
| 2344 | + } |
| 2345 | + |
| 2346 | + void SignOnPlugin::process(const SignOn::SessionData &inData, |
| 2347 | + const QString &mechanism) |
| 2348 | + { |
| 2349 | + Q_UNUSED(mechanism); |
| 2350 | + PluginData response; |
| 2351 | + m_data = inData.data<PluginData>(); |
| 2352 | + |
| 2353 | + if (!inData.Secret().isEmpty()) { |
| 2354 | + response.setConsumer(m_data.Consumer()); |
| 2355 | + response.setConsumerSecret(m_data.ConsumerSecret()); |
| 2356 | + response.setToken(m_data.Token()); |
| 2357 | + response.setTokenSecret(m_data.TokenSecret()); |
| 2358 | + |
| 2359 | + response.setName(Token::buildTokenName()); |
| 2360 | + |
| 2361 | + emit result(response); |
| 2362 | + return; |
| 2363 | + } |
| 2364 | + |
| 2365 | + SignOn::UiSessionData data; |
| 2366 | + data.setRealm(inData.Realm()); |
| 2367 | + data.setShowRealm(!data.Realm().isEmpty()); |
| 2368 | + emit userActionRequired(data); |
| 2369 | + } |
| 2370 | + |
| 2371 | + void SignOnPlugin::userActionFinished(const SignOn::UiSessionData &data) |
| 2372 | + { |
| 2373 | + } |
| 2374 | + |
| 2375 | + SIGNON_DECL_AUTH_PLUGIN(SignOnPlugin) |
| 2376 | +} // namespace UbuntuOne |
| 2377 | |
| 2378 | === added file 'signon-plugin/ubuntuone-plugin.h' |
| 2379 | --- signon-plugin/ubuntuone-plugin.h 1970-01-01 00:00:00 +0000 |
| 2380 | +++ signon-plugin/ubuntuone-plugin.h 2013-08-27 20:30:52 +0000 |
| 2381 | @@ -0,0 +1,56 @@ |
| 2382 | +/* |
| 2383 | + * Copyright 2013 Canonical Ltd. |
| 2384 | + * |
| 2385 | + * This library is free software; you can redistribute it and/or |
| 2386 | + * modify it under the terms of version 3 of the GNU Lesser General Public |
| 2387 | + * License as published by the Free Software Foundation. |
| 2388 | + * |
| 2389 | + * This program is distributed in the hope that it will be useful, |
| 2390 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 2391 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| 2392 | + * General Public License for more details. |
| 2393 | + * |
| 2394 | + * You should have received a copy of the GNU Lesser General Public |
| 2395 | + * License along with this library; if not, write to the |
| 2396 | + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, |
| 2397 | + * Boston, MA 02110-1301, USA. |
| 2398 | + */ |
| 2399 | +#ifndef _UBUNTUONE_PLUGIN_H_ |
| 2400 | +#define _UBUNTUONE_PLUGIN_H_ |
| 2401 | + |
| 2402 | +#include <QtCore> |
| 2403 | + |
| 2404 | +#include <SignOn/AuthPluginInterface> |
| 2405 | +#include <SignOn/Error> |
| 2406 | +#include <SignOn/SessionData> |
| 2407 | +#include <SignOn/UiSessionData> |
| 2408 | + |
| 2409 | +#include "ubuntuonedata.h" |
| 2410 | + |
| 2411 | + |
| 2412 | +namespace UbuntuOne { |
| 2413 | + |
| 2414 | + class SignOnPlugin : public AuthPluginInterface |
| 2415 | + { |
| 2416 | + Q_OBJECT |
| 2417 | + Q_INTERFACES(AuthPluginInterface) |
| 2418 | + |
| 2419 | + public: |
| 2420 | + SignOnPlugin(QObject *parent = 0); |
| 2421 | + virtual ~SignOnPlugin(); |
| 2422 | + |
| 2423 | + public Q_SLOTS: |
| 2424 | + QString type() const; |
| 2425 | + QStringList mechanisms() const; |
| 2426 | + void cancel(); |
| 2427 | + void process(const SignOn::SessionData &inData, |
| 2428 | + const QString &mechanism = 0); |
| 2429 | + void userActionFinished(const SignOn::UiSessionData &data); |
| 2430 | + |
| 2431 | + private: |
| 2432 | + PluginData m_data; |
| 2433 | + }; |
| 2434 | + |
| 2435 | +} // namespace UbuntuOne |
| 2436 | + |
| 2437 | +#endif |
| 2438 | |
| 2439 | === added file 'signon-plugin/ubuntuonedata.h' |
| 2440 | --- signon-plugin/ubuntuonedata.h 1970-01-01 00:00:00 +0000 |
| 2441 | +++ signon-plugin/ubuntuonedata.h 2013-08-27 20:30:52 +0000 |
| 2442 | @@ -0,0 +1,42 @@ |
| 2443 | +/* |
| 2444 | + * Copyright 2013 Canonical Ltd. |
| 2445 | + * |
| 2446 | + * This library is free software; you can redistribute it and/or |
| 2447 | + * modify it under the terms of version 3 of the GNU Lesser General Public |
| 2448 | + * License as published by the Free Software Foundation. |
| 2449 | + * |
| 2450 | + * This program is distributed in the hope that it will be useful, |
| 2451 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 2452 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| 2453 | + * General Public License for more details. |
| 2454 | + * |
| 2455 | + * You should have received a copy of the GNU Lesser General Public |
| 2456 | + * License along with this library; if not, write to the |
| 2457 | + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, |
| 2458 | + * Boston, MA 02110-1301, USA. |
| 2459 | + */ |
| 2460 | +#ifndef _UBUNTUONE_DATA_H_ |
| 2461 | +#define _UBUNTUONE_DATA_H_ |
| 2462 | + |
| 2463 | +#include <sessiondata.h> |
| 2464 | + |
| 2465 | +namespace UbuntuOne { |
| 2466 | + |
| 2467 | + class PluginData : public SignOn::SessionData |
| 2468 | + { |
| 2469 | + public: |
| 2470 | + // The name of the token |
| 2471 | + SIGNON_SESSION_DECLARE_PROPERTY(QString, Name); |
| 2472 | + |
| 2473 | + // The consumer key and secret for signing |
| 2474 | + SIGNON_SESSION_DECLARE_PROPERTY(QString, Consumer); |
| 2475 | + SIGNON_SESSION_DECLARE_PROPERTY(QString, ConsumerSecret); |
| 2476 | + |
| 2477 | + // The access token and secret for signing |
| 2478 | + SIGNON_SESSION_DECLARE_PROPERTY(QString, Token); |
| 2479 | + SIGNON_SESSION_DECLARE_PROPERTY(QString, TokenSecret); |
| 2480 | + }; |
| 2481 | + |
| 2482 | +} // namespace UbuntuOne |
| 2483 | + |
| 2484 | +#endif |

+1 exhausted