Commit 54f56a99 authored by Aard's avatar Aard

Import first opensource version

parents
Makefile
build/*
doc/html
doc/latex
*.pro.user
This diff is collapsed.
isEmpty(BUILD){
BUILD = $$PWD/build/$$TARGET
}
isEmpty(DESTDIR){
DESTDIR = $$BUILD
}
OBJECTS_DIR = $$BUILD
MOC_DIR = $$BUILD
UI_DIR = $$BUILD
UI_HEADERS_DIR = $$BUILD
UI_SOURCES_DIR = $$BUILD
RCC_DIR = $$BUILD
LIBS += -L$$PWD/build/libssu
INCLUDEPATH += $$PWD/libssu
/**
* @file constants.h
* @copyright 2012 Jolla Ltd.
* @author Bernd Wachter <bernd.wachter@jollamobile.com>
* @date 2012
*/
#ifndef _CONSTANTS_H
#define _CONSTANTS_H
/// The group ID SSU expects to run as. This is usually the GID of the main phone user
#define SSU_GROUP_ID 1000
/// Path to the main SSU configuration file
#define SSU_CONFIGURATION "/etc/ssu/ssu.ini"
/// Path to the main SSU configuration file
#define SSU_REPO_CONFIGURATION "/usr/share/ssu/repos.ini"
/// The SSU protocol version used by the ssu client libraries
#define SSU_PROTOCOL_VERSION "1"
#endif
This diff is collapsed.
BUILD = ../build/libssu
HEADERS = ssu.h \
../constants.h
SOURCES = ssu.cpp
TEMPLATE = lib
TARGET = ssu
CONFIG += dll mobility
QT -= gui
QT += network xml
MOBILITY += systeminfo
unix:target.path = $${PREFIX}/usr/lib
INSTALLS += target
!include( ../buildpath.pri ) { error("Unable to find build path specification") }
This diff is collapsed.
/**
* @file ssu.h
* @copyright 2012 Jolla Ltd.
* @author Bernd Wachter <bernd.wachter@jollamobile.com>
* @date 2012
*/
#ifndef _Ssu_H
#define _Ssu_H
#include <QObject>
#include <QSettings>
#include <QDebug>
#include <QtNetwork>
#include <QtXml/QDomDocument>
class Ssu: public QObject {
Q_OBJECT
public:
Ssu();
/**
* Find a username/password pair for the given scope
* @return a QPair with username and password, or an empty QPair if scope is invalid
*/
QPair<QString, QString> credentials(QString scope);
/**
* Get the scope for a repository, taking into account different scopes for
* release and RnD repositories
*
* Please note that variable scope is not yet implemented -- one default scope is
* read from the configuration file.
*
* @return a string containing the scope; it can be used to look up login credentials using credentials()
*/
QString credentialsScope(QString repoName, bool rndRepo=false);
/**
* Try to find the device family for the system this is running on
*/
Q_INVOKABLE QString deviceFamily();
/**
* Try to find out ond what kind of system this is running
*/
Q_INVOKABLE QString deviceModel();
/**
* Calculate the device ID used in SSU requests
* @return QSystemDeviceInfo::imei(), if available, or QSystemDeviceInfo::uniqueDeviceID()
*/
Q_INVOKABLE QString deviceUid();
/**
* Returns if the last operation was successful
* @retval true last operation was successful
* @retval false last operation failed, you should check lastError() for details
*/
Q_INVOKABLE bool error();
/**
* Get the current flavour when RnD repositories are used
* @return current flavour (usually something like testing, release, ..)
*/
Q_INVOKABLE QString flavour();
/**
* Return devices RND registration status
* @retval true device is registered
* @retval false device is not registered
*/
Q_INVOKABLE bool isRegistered();
/**
* Return the date/time when the credentials to access internal
* SSU servers were updated the last time
*/
Q_INVOKABLE QDateTime lastCredentialsUpdate();
/**
* Return an error message for the last error encountered. The message
* will not be cleared, check error() to see if the last operation was
* successful.
*/
Q_INVOKABLE QString lastError();
/**
* Return the release version string for either a release, or a RnD snapshot
*/
Q_INVOKABLE QString release(bool rnd=false);
/**
* Resolve a repository url
* @return the repository URL on success, an empty string on error
*/
QString repoUrl(QString repoName, bool rndRepo=false, QHash<QString, QString> repoParameters=QHash<QString, QString>());
/**
* Set the flavour used when resolving RND repositories
*/
Q_INVOKABLE void setFlavour(QString flavour);
/**
* Set the release version string for either a release, or a RnD snapshot
*/
Q_INVOKABLE void setRelease(QString release, bool rnd=false);
/**
* Unregister a device. This will clean all registration data from a device,
* though will not touch the information on SSU server; the information there
* has to be manually cleaned for a device we don't own anymore, but will be
* overwritten next time the device gets registered
*/
Q_INVOKABLE void unregister();
/**
* Return configuration settings regarding ssl verification
* @retval true SSL verification must be used; that's the default if not configured
* @retval false SSL verification should be disabled
*/
Q_INVOKABLE bool useSslVerify();
private:
QString errorString;
bool errorFlag;
QNetworkAccessManager *manager;
QSettings *settings, *repoSettings;
bool registerDevice(QDomDocument *response);
bool setCredentials(QDomDocument *response);
bool verifyResponse(QDomDocument *response);
private slots:
void requestFinished(QNetworkReply *reply);
/**
* Set errorString returned by lastError to errorMessage, set
* errorFlag returned by error() to true, and emit done()
*/
void setError(QString errorMessage);
public slots:
/**
* Attempt RND device registration, using @a username and @a password supplied
* @param username Jolla username
* @param password Jolla password
*
* When the operation has finished the done() signal will be sent. You can call
* error() to check if an error occured, and use lastError() to retrieve the last
* error message.
*/
void sendRegistration(QString username, QString password);
/**
* Try to update the RND repository credentials. The device needs to be registered
* for this to work. updateCredentials remembers the time of the last credentials
* update, and skips updating if only little time has elapsed since the last update.
* An update may be forced by setting @a force to true
* @param force force credentials updating
*
* When the operation has finished the done() signal will be sent. You can call
* error() to check if an error occured, and use lastError() to retrieve the last
* error message.
*/
void updateCredentials(bool force=false);
signals:
/**
* Emitted after an asynchronous operation finished
*/
void done();
// we don't get notifications from settings -> this won't work over different instances (yet)
void flavourChanged();
void releaseChanged();
void registrationStatusChanged();
void credentialsChanged();
};
#endif
### Don't edit this file manually. Update it in git, if there's a good reason to do so ###
#
# Variables resolved during package build:
# %(arch) Package architecture, as in i586 or armv7hl
#
# Variables resolved by URL parameters in repository:
# %(deviceFamily) A device family in adaptation, like mrst or n9xx
# %(debugSplit) Set to debug if 'debug' parameter is present, to packages otherwise
#
# Variables resolved from configuration:
# %(release) A release, which will be replaced to 'next' or 'latest' for RnD, or a release number
# %(flavour) A flavour (RnD only), which will be replaced to one of 'devel', 'testing' or 'release'
# %(adaptation) The device specific adaptation, for example 'n900' or 'n950-n9'
#
#
# Repository lookup will happen based on the 'repo' parameter in repository
# URLs. For RnD repositories order will be <flavour> -> rnd -> all, for
# release repositories release -> all.
#
# Valid url specifications in repo files for RnD repositories include:
#
# baseurl=plugin:ssu?repo=non-oss&rnd
# baseurl=plugin:ssu?repo=mer-core&rnd&debug
# baseurl=plugin:ssu?repo=non-oss&rnd&deviceFamily=mrst
#
# Valid url specifications in repo files for release repositories include:
#
# baseurl=plugin:ssu?repo=non-oss
# baseurl=plugin:ssu?repo=non-oss&deviceFamily=mrst
[all]
credentials=jolla
[release]
jolla=https://packages.example.com/releases/%(release)/jolla/%(arch)/
jolla-bad=https://packages.example.com/notused-bad/%(release)/bad/%(arch)/
mer-core=https://packages.example.com/%(release)/mer/%(arch)/%(debugSplit)/
adaptation-common-main=https://packages.example.com/releases/%(release)/nemo/adaptation-%(deviceFamily)-common/%(arch)/
adaptation=https://packages.example.com/releases/%(release)/nemo/adaptation-%(adaptation)/%(arch)/
nemo=https://packages.example.com/releases/%(release)/nemo/platform/%(arch)/
[rnd]
mer-core=https://packages.example.com/mer/%(release)/builds/%(arch)/%(debugSplit)/
adaptation-common-main=https://packages.example.com/nemo/%(release)/adaptation-%(adaptation)-common/%(arch)/
adaptation=https://packages.example.com/nemo/%(release)/adaptation-%(deviceFamily)/%(arch)/
nemo=https://packages.example.com/nemo/%(release)/platform/%(arch)/
non-oss-bad=https://dump.example.com/pj:/non-oss-bad%(flavour)/%(release)_%(arch)/
non-oss=https://dump.example.com/pj:/non-oss%(flavour)/%(release)_%(arch)/
oss-bad=https://dump.example.com/pj:/oss-bad%(flavour)/%(release)_%(arch)/
oss=https://dump.example.com/pj:/oss%(flavour)/%(release)_%(arch)/
[devel-flavour]
flavour-pattern=
[release-flavour]
flavour-pattern=:/release
[testing-flavour]
flavour-pattern=:/testing
/**
* @file main.cpp
* @copyright 2012 Jolla Ltd.
* @author Bernd Wachter <bernd.wachter@jollamobile.com>
* @date 2012
*/
#include <QApplication>
#include "rndregisterui.h"
Q_DECL_EXPORT int main(int argc, char** argv){
QApplication app(argc, argv);
QCoreApplication::setOrganizationName("Jolla");
QCoreApplication::setOrganizationDomain("http://www.jollamobile.com");
QCoreApplication::setApplicationName("rndregisterui");
RndRegisterUi mw;
mw.showFullScreen();
return app.exec();
}
<RCC>
<qresource prefix="/">
<file>resources/qml/rndregisterui.qml</file>
<file>resources/qml/RndSsuPage.qml</file>
</qresource>
</RCC>
\ No newline at end of file
import QtQuick 1.1
import com.nokia.meego 1.0
Page {
id: rndSsuPage
Connections {
target: ssu
onDone: {
if (ssu.error()){
lblRegistrationStatus.text = qsTr("Device registration failed")
lblRegistrationStatus.text += ssu.lastError()
registerButton.enabled = true
} else {
lblRegistrationStatus.text = qsTr("Device is registered")
}
refreshCredentialsButton.enabled = true
}
onRegistrationStatusChanged: {
if (ssu.isRegistered()){
columnRegister.visible = false
columnRegistered.visible = true
} else {
columnRegister.visible = true
columnRegistered.visible = false
}
}
onCredentialsChanged: {
lblCredentialsDate.text = ssu.lastCredentialsUpdate()
}
onFlavourChanged: {
var flavour = ssu.flavour();
if (flavour == "devel"){
btnFlvrDevel.checked = true
} else if (flavour == "testing"){
btnFlvrTesting.checked = true
} else if (flavour == "release"){
btnFlvrRelease.checked = true
}
}
}
TabGroup{
id: tabgroup
currentTab: tab1
Page {
id: tab1
Flickable {
id: flickT1
width: parent.width
height: parent.height
flickableDirection: Flickable.VerticalFlick
contentWidth: columnT1.paintedWidth
contentHeight: columnT1.height
Column {
id: columnT1
width: parent.width
spacing: 20;
Label {
id: lblRegistrationHeader
width: parent.width
text: qsTr("Device registration")
}
Column {
id: columnRegister
width: parent.width
visible: !ssu.isRegistered()
spacing: 20
Label {
id: lblJollaId
text: qsTr("Jolla Username:")
width: parent.width
}
TextField {
id: inputJollaId
text: ""
width: parent.width
}
Label {
id: lblJollaPasswd
text: "Jolla password:"
width: parent.width
}
TextField {
id: inputJollaPasswd
echoMode: TextInput.Password
text: ""
width: parent.width
}
Button {
id: registerButton
function registerButtonClicked(){
registerButton.enabled = false
ssu.sendRegistration(inputJollaId.text, inputJollaPasswd.text)
}
onClicked: registerButtonClicked()
text: qsTr("Register Device")
width: parent.width
}
Label {
id: lblRegistrationStatus
width: parent.width
}
}
Column {
id: columnRegistered
width: parent.width
visible: ssu.isRegistered()
spacing: 20;
Label {
id: lblDeviceRegistered
text: qsTr("This device is registered")
width: parent.width
}
Button {
id: unregisterDeviceButton
onClicked: ssu.unregister()
text: qsTr("Unregister device")
width: parent.width
}
Button {
id: refreshCredentialsButton
function refreshCredentialsButtonClicked(){
refreshCredentialsButton.enabled = false
ssu.updateCredentials(true);
}
onClicked: refreshCredentialsButtonClicked()
text: qsTr("Update credentials")
width: parent.width
}
Label { text: qsTr("Last credentials update:") }
Label {
id: lblCredentialsDate
text: ssu.lastCredentialsUpdate()
width: parent.width
}
}
}
}
}
Page {
id: tab2
Flickable {
id: flickT2
width: parent.width
height: parent.height
flickableDirection: Flickable.VerticalFlick
contentWidth: columnT2.paintedWidth
contentHeight: columnT2.height
Column {
id: columnT2
width: parent.width
spacing: 20
}
}
}
Page {
id: tab3
Flickable {
id: flickT3
width: parent.width
height: parent.height
flickableDirection: Flickable.VerticalFlick
contentWidth: columnT3.paintedWidth
contentHeight: columnT3.height
Column {
id: columnT3
width: parent.width
spacing: 20
Label { id: lblT3_1; text: "Settings" }
Label { id: lblFlvr; text: "Flavour" }
ButtonColumn {
width: parent.width
Button {
id: btnFlvrDevel
text: "devel"
onClicked: ssu.setFlavour("devel")
checked: ssu.flavour() == "devel"
}
Button {
id: btnFlvrTesting
text: "testing"
onClicked: ssu.setFlavour("testing")
checked: ssu.flavour() == "testing"
}
Button {
id: btnFlvrRelease
text: "release"
onClicked: ssu.setFlavour("release")
checked: ssu.flavour() == "release"
}
}
Label { id: lblRelease; text: "Release" }
ButtonColumn {
width: parent.width
Button { text: "latest"; onClicked: ssu.setRelease("latest", true) }
Button { text: "next"; onClicked: ssu.setRelease("next", true) }
}
}
}
}
}
tools:ToolBarLayout {
id: commonTools
visible: true
ButtonRow {
style: TabButtonStyle { }
TabButton {
text: qsTr("Registration")
tab: tab1
}
TabButton {
text: "B"
tab: tab2
visible: false
}
TabButton {
text: qsTr("Settings")
tab: tab3
}
}
ToolIcon {
platformIconId: "toolbar-view-menu"
anchors.right: (parent === undefined) ? undefined : parent.right
onClicked: (myMenu.status == DialogStatus.Closed) ? myMenu.open() : myMenu.close()
}
}
Menu {
id: myMenu
visualParent: pageStack
MenuLayout {
MenuItem { text: qsTr("About"); }
MenuItem { text: qsTr("Exit application"); onClicked: root.quit() }
}
}
}
import QtQuick 1.1
import com.nokia.meego 1.0
PageStackWindow {
id: root
signal quit()
showStatusBar: true
showToolBar: true
initialPage: RndSsuPage {}
}
/**
* @file rndregisterui.cpp
* @copyright 2012 Jolla Ltd.
* @author Bernd Wachter <bernd.wachter@jollamobile.com>
* @date 2012
*/
#include <QDeclarativeContext>
#include <QGraphicsObject>
#include <QApplication>
#include "rndregisterui.h"
RndRegisterUi::RndRegisterUi(QWidget *parent): QMainWindow(parent){
ui = new QDeclarativeView;
ui->rootContext()->setContextProperty("ssu", &ssu);
QDir dir;
if (dir.exists("/home/nemo/rndregisterui.qml"))
ui->setSource(QUrl("file:///home/nemo/rndregisterui.qml"));
else
ui->setSource(QUrl("qrc:/resources/qml/rndregisterui.qml"));
setCentralWidget(ui);
QObject *item=dynamic_cast<QObject*>(ui->rootObject());
connect(item, SIGNAL(quit()), QApplication::instance(), SLOT(quit()));
}
RndRegisterUi::~RndRegisterUi(){
delete ui;
}
[Desktop Entry]
Encoding=UTF-8
Version=1.0
Type=Application
Terminal=false
Name=Jolla RND
Exec=invoker --type=q -s /usr/bin/rndregisterui
Icon=mad-developer
StartupNotify=true
/**
* @file rndregisterui.h
* @copyright 2012 Jolla Ltd.
* @author Bernd Wachter <bernd.wachter@jollamobile.com>
* @date 2012
*/
#ifndef RndRegisterUi_H
#define RndRegisterUi_H
#include <QMainWindow>
#include <QtDeclarative/QDeclarativeView>
#include <ssu.h>
namespace Ui {
class RndRegisterUi;
}
class RndRegisterUi: public QMainWindow{
Q_OBJECT
public:
explicit RndRegisterUi(QWidget *parent = 0);
~RndRegisterUi();
private:
Ssu ssu;
QDeclarativeView *ui;
};
#endif
HEADERS = rndregisterui.h
SOURCES = main.cpp \
rndregisterui.cpp
RESOURCES = resources.qrc
TEMPLATE = app
TARGET = rndregisterui
LIBS += -lssu
CONFIG += qdeclarative-boostable
CONFIG -= app_bundle
QT += core gui declarative network
OTHER_FILES += \
resources/qml/rndregisterui.qml \
resources/qml/RndSsuPage.qml
unix:target.path = $${PREFIX}/usr/bin
desktop.files = rndregisterui.desktop
desktop.path = /usr/share/applications/
INSTALLS += target desktop
!include( ../buildpath.pri ) { error("Unable to find build path specification") }
/**
* @file main.cpp
* @copyright 2012 Jolla Ltd.
* @author Bernd Wachter <bernd.wachter@jollamobile.com>
* @date 2012
*/
#include <QCoreApplication>
#include <QTranslator>
#include <QLocale>
#include <QLibraryInfo>
#include "rndssucli.h"
int main(int argc, char** argv){
QCoreApplication app(argc, argv);
QCoreApplication::setOrganizationName("Jolla");
QCoreApplication::setOrganizationDomain("http://www.jollamobile.com");
QCoreApplication::setApplicationName("rndssu");
QTranslator qtTranslator;
qtTranslator.load("qt_" + QLocale::system().name(),
QLibraryInfo::location(QLibraryInfo::TranslationsPath));
app.installTranslator(&qtTranslator);
RndSsuCli mw;
QTimer::singleShot(0, &mw, SLOT(run()));
return app.exec();
}
/**
* @file rndssucli.cpp
* @copyright 2012 Jolla Ltd.
* @author Bernd Wachter <bernd.wachter@jollamobile.com>
* @date 2012
*/
#include <QCoreApplication>
#include "rndssucli.h"
RndSsuCli::RndSsuCli(): QObject(){
connect(this,SIGNAL(done()),
QCoreApplication::instance(),SLOT(quit()), Qt::DirectConnection);
connect(