</head>
<body>
<h1>Tizen Extensions Crosswalk examples</h1>
-<a href="tizen.html"><div class="block">tizen top namespace</div></a>
-<a href="network_bearer_selection.html"><div class="block">network bearer selection</div></a>
-<a href="notification.html"><div class="block">notification</div></a>
-<a href="system_info.html"><div class="block">system info</div></a>
-<a href="system_setting.html"><div class="block">system setting</div></a>
-<a href="time.html"><div class="block">time</div></a>
-<a href="power.html"><div class="block">power</div></a>
+<a href="alarm.html"><div class="block">alarm</div></a>
+<a href="application.html"><div class="block">application</div></a>
+<a href="audiosystem.html"><div class="block">audiosystem</div></a>
<a href="bluetooth.html"><div class="block">bluetooth</div></a>
+<a href="callhistory.html"><div class="block">Call History</div></a>
+<a href="content.html"><div class="block">content</div></a>
<a href="download.html"><div class="block">download</div></a>
<a href="filesystem.html"><div class="block">filesystem</div></a>
-<a href="application.html"><div class="block">application</div></a>
-<a href="callhistory.html"><div class="block">Call History</div></a>
<a href="mediaserver.html"><div class="block">mediaserver</div></a>
-<a href="audiosystem.html"><div class="block">audiosystem</div></a>
-<a href="content.html"><div class="block">content</div></a>
+<a href="network_bearer_selection.html"><div class="block">network bearer selection</div></a>
+<a href="notification.html"><div class="block">notification</div></a>
+<a href="power.html"><div class="block">power</div></a>
<a href="speech.html"><div class="block">speech</div></a>
-<a href="alarm.html"><div class="block">alarm</div></a>
+<a href="sso.html"><div class="block">SSO</div></a>
+<a href="system_info.html"><div class="block">system info</div></a>
+<a href="system_setting.html"><div class="block">system setting</div></a>
+<a href="time.html"><div class="block">time</div></a>
+<a href="tizen.html"><div class="block">tizen top namespace</div></a>
</body>
</html>
--- /dev/null
+<html>
+<head>
+<title>SSO example</title>
+</head>
+<body>
+<style type="text/css">
+ .topleftcorner {
+ position:relative;
+ width: 33%;
+ }
+ .toprightcorner {
+ position:absolute;
+ top:0;
+ right:0;
+ width: 33%;
+ }
+ .topcenter {
+ position: absolute;
+ width: 100%;
+ left: 100%;
+ top: 0%;
+ height:100%
+ }
+</style>
+
+<div id='serviceContainer' class="topleftcorner">
+<table id="service" border="5">
+ <tr>
+ <th colspan="2">
+ <H3><BR>Service</H3>
+ </th>
+ </tr>
+ <th>API</th>
+ <th>Arg1</th>
+ <tr><td><button onclick='queryMethods()'>Query Methods</button></td></tr>
+ <tr><td><button onclick='queryMechanisms()'>Query Mechanisms</button></td>
+ <td><form>Method: <input type="text" name="serv_method" id="serv_method"><br></form></td>
+ </tr>
+ <tr><td><button onclick='queryIdentities()'>Query Identities</button></td>
+ <td><form>Filter(key1:val1,key2:val2,...):
+ <input type="text" name="serv_filter" id="serv_filter"><br></form></td>
+ </tr>
+ <tr><td><button onclick='getIdentity()'>Get Identity</button></td>
+ <td><form>Id: <input type="text" name="serv_identityid" id="serv_identityid"><br></form></td>
+ </tr>
+ <tr><td><button onclick='clearDB()'>Clear DB</button></td></tr>
+</table>
+
+<table id="creat_identity" border="5">
+ <tr>
+ <th colspan="1">
+ <H3><button onclick='onCreateIdentity()'><BR>Create Identity</button>
+ <button onclick='onUpdateIdentity()'><BR>Update Identity</button></H3>
+ </th>
+ </tr>
+ <tr><td><form>Select Type: <select name="cident_type" id="cident_type">
+ <option value = "APP" >Application</option>
+ <option value = "WEB" selected >Web</option>
+ <option value = "NET" >Network</option>
+ </select></form></td></tr>
+ <tr><td><form>Username:
+ <input type="text" name="cident_username" id="cident_username"><br></form></td></tr>
+ <tr><td><form>Password:
+ <input type="text" name="cident_secret" id="cident_secret"><br></form></td></tr>
+ <tr><td><form>StoreSecret:
+ <input type="checkbox" name="cident_storesecret" id="cident_storesecret"><br></form></td></tr>
+ <tr><td><form>Caption:
+ <input type="text" name="cident_caption" id="cident_caption"><br></form></td></tr>
+ <tr><td><form>Realms(realm1,realm2,..):
+ <input type="text" name="cident_realms" id="cident_realms"><br></form></td></tr>
+ <tr><td><form>Owner(appcontext,syscontext):
+ <input type="text" name="cident_owner" id="cident_owner"><br></form></td></tr>
+ <tr><td><form>ACL(json: [{"secContext":{"sysContext":"*","appContext":"*"},
+ "method":"password","mechanisms":["password"]}]):
+ <input type="text" name="cident_acl" id="cident_acl"><br></form></td></tr>
+</table>
+<div id='resultContainer' class="topcenter">>
+<form name='form_out'>
+ <textarea name="form_text" id="form_text" style="width:100%; height:100%"></textarea>
+</form>
+</div>
+
+</div>
+
+<div id='identityContainer' class="toprightcorner">
+<table width="115%" id="identity" border="5">
+ <tr>
+ <th colspan="2">
+ <H3><BR>Identity</H3>
+ <form>Selected Identity JSId:
+ <select name="ident_options" id="ident_options" onchange="onIdentityChanged(this)">
+ </select></form>
+ </th>
+ </tr>
+ <th>API</th>
+ <th>Arg1</th>
+ <tr><td><button onclick='startSession()'>Start Session</button></td>
+ <td><form>Method: <input type="text" name="ident_method" id="ident_method"><br></form></td>
+ </tr>
+ <tr><td><button onclick='requestCredentialsUpdate()'>Update Credentials</button></td>
+ <td><form>Message: <input type="text" name="ident_message" id="ident_message"><br></form></td>
+ </tr>
+ <tr><td><button onclick='store(null)'>Store</button></td>
+ </tr>
+ <tr><td><button onclick='addReference()'>Add Reference</button></td>
+ <td><form>Reference: <input type="text" name="ident_addref" id="ident_addref"><br></form></td>
+ </tr>
+ <tr><td><button onclick='removeReference()'>Remove Reference</button></td>
+ <td><form>Reference: <input type="text" name="ident_remref" id="ident_remref"><br></form></td>
+ </tr>
+ <tr><td><button onclick='removeIdentity()'>Remove</button></td>
+ </tr>
+ <tr><td><button onclick='signout()'>Signout</button></td>
+ </tr>
+</table>
+
+<table id="session" border="5">
+ <tr>
+ <th colspan="3">
+ <H3><BR>Session</H3>
+ <form>Selected Session JSId: <select name="sess_options" id="sess_options"></select></form>
+ </th>
+ </tr>
+ <th>API</th>
+ <th>Arg1</th>
+ <th>Arg2</th>
+ <tr><td><button onclick='queryAvailableMechanisms()'>QueryAvailableMechanisms</button></td>
+ <td><form>WantedMechanisms(mech1,mech2,..):
+ <input type="text" name="sess_mechs" id="sess_mechs"><br></form></td>
+ </tr>
+ <tr><td><button onclick='challenge()'>Challenge</button></td>
+ <td><form>Mechanism: <input type="text" name="sess_mech" id="sess_mech"><br></form></td>
+ <td><form>SessionData (json: {"key1":"value1","key2":"value2",...}):
+ <input type="text" name="sess_data" id="sess_data"><br></form></td>
+ </tr>
+ <tr><td><button onclick='cancel()'>Cancel</button></td>
+ </tr>
+</table>
+</div>
+
+<script>
+
+function _logData(data) {
+ var old = document.form_out.form_text.value
+ document.form_out.form_text.value = data + '\n\n' + old;
+}
+
+function queryMethods() {
+ tizen.sso.authService.queryMethods().then(function(result) {
+ _logData('QueryMethods successful: ' + JSON.stringify(result));},
+ function (err) { document.form_out.form_text.value += "\n" + "QueryMethods failed: " + err;});
+}
+
+function queryMechanisms() {
+ var method = document.getElementById('serv_method').value;
+ tizen.sso.authService.queryMechanisms(method).then(function (result) {
+ _logData('QueryMechanisms successful: ' + JSON.stringify(result));},
+ function(err) {_logData('QueryMechanisms failed: ' + err);});
+}
+
+function queryIdentities() {
+ var str = document.getElementById('serv_filter').value;
+ var filters = {};
+ if (typeof str === 'string' && str.length > 0) {
+ var ufilter = str.split(",");
+ for (var i = 0; i < ufilter.length; i++) {
+ var keyval = ufilter[i].split(":");
+ filters[keyval[0]] = keyval[1];
+ }
+ }
+ tizen.sso.authService.queryIdentities(filters).then(onQueryIdentitiesComplete, function(err) {
+ _logData('QueryIdentities failed: ' + err);});
+}
+
+function onQueryIdentitiesComplete(result) {
+ _logData('QueryIdentities successful: ' + JSON.stringify(result));
+}
+
+function getIdentity() {
+ var id = parseFloat(document.getElementById('serv_identityid').value);
+ if (id == NaN) {
+ _logData('Invalid id');
+ return;
+ }
+ var res = tizen.sso.authService.getIdentity(id);
+ if (res != null)
+ res.then(onGetIdentityComplete, function(err) {
+ _logData('GetIdentity failed: ' + err);});
+ else
+ _logData('Identity not found with the specified id');
+}
+
+function onGetIdentityComplete(result) {
+ _logData('GetIdentity successful: ' + JSON.stringify(result));
+}
+
+function clearDB() {
+ tizen.sso.authService.clear().then(function(result) {
+ _logData('Clear successful: ' + JSON.stringify(result));
+ clearSelect(document.getElementById("ident_options"));
+ clearSelect(document.getElementById("sess_options"));},
+ function(err) {_logData('Clear failed: ' + err);});
+}
+
+function getInfo() {
+ var owner = {};
+ var str = document.getElementById('cident_owner').value;
+ if (typeof str === 'string' && str.length > 0) {
+ arr = str.split(",");
+ if (arr.length == 2) {
+ owner.sysContext = arr[0];
+ owner.appContext = arr[1];
+ }
+ }
+ var realms = [];
+ str = document.getElementById('cident_realms').value;
+ if (typeof str === 'string' && str.length > 0) {
+ arr = str.split(",");
+ if (arr.length > 0) realms = arr;
+ }
+ var acl = [{}];
+ str = document.getElementById('cident_acl').value;
+ if (typeof str === 'string' && str.length > 0) {
+ acl = JSON.parse(str);
+ }
+ var info = {
+ 'type': document.getElementById('cident_type').value,
+ 'username': document.getElementById('cident_username').value,
+ 'secret': document.getElementById('cident_secret').value,
+ 'storeSecret': document.getElementById('cident_storesecret').checked,
+ 'caption': document.getElementById('cident_caption').value,
+ 'realms': realms,
+ 'owner': owner,
+ 'accessControlList': acl
+ };
+ return info;
+}
+
+function onCreateIdentity() {
+ var info = getInfo();
+ var res = tizen.sso.authService.createIdentity(info);
+ if (res.syncOpErrorMsg != null) {
+ _logData('Identity creation FAILED with error: ' + res.asyncOpErrorMsg);
+ return;
+ }
+
+ identityAdded(res.identity);
+ _logData('Identity is added with jsid: ' + res.identity.jsid);
+}
+
+function onUpdateIdentity() {
+ var info = getInfo();
+ store(info);
+}
+
+function identityAdded(ident) {
+ var select = document.getElementById("ident_options");
+ var option = document.createElement('option');
+ option.text = option.value = ident.jsid;
+ select.add(option, 0);
+
+ ident.onsignedout = function (ident) {
+ _logData('Identity with id ' + ident.info.id + ' is signedout and jsid is '
+ + ident.jsid);};
+ ident.onremoved = onIdentityRemoved;
+}
+
+function onIdentityRemoved(ident) {
+ _logData('Identity with id ' + ident.info.id + ' is removed and its jsid is '
+ + ident.jsid);
+ if (document.getElementById('ident_options').value == ident.jsid) {
+ for (var i = 0; i < ident.sessions.length; i++) {
+ var sessionobj = ident.sessions[i];
+ sessionobj.removeEventListener('statechanged', onSessionStateChanged);
+ document.getElementById('sess_options').remove(i);
+ }
+ clearSelectOption(document.getElementById("ident_options"), ident.jsid);
+ }
+}
+
+function clearSelectOption(element, value) {
+ for (var i=0; i<element.length; i++) {
+ if (element.options[i].value == value)
+ element.remove(i);
+ }
+}
+
+function clearSelect(element) {
+ for (var i=0; i<element.length; i++) {
+ element.remove(i);
+ }
+}
+
+function onIdentityChanged(select) {
+ var jsid = document.getElementById("ident_options").value;
+ _logData('Identity selected with jsid: ' + jsid);
+ var identobj = tizen.sso.authService.getIdentityByJSId(jsid);
+ if (identobj == null) {
+ _logData('identity NOT found');
+ return;
+ }
+ clearSelect(document.getElementById("sess_options"));
+ for (var i = 0; i < identobj.sessions.length; i++) {
+ var option = document.createElement('option');
+ option.text = option.value = identobj.sessions[i].jsid;
+ document.getElementById('sess_options').add(option, 0);
+ }
+}
+
+//identity interface
+function startSession() {
+ var identobj = tizen.sso.authService.getIdentityByJSId(
+ document.getElementById('ident_options').value);
+ if (identobj == null) {
+ _logData('identity NOT selected/found. Please select/create an identity first');
+ return;
+ }
+ _logData('identity found with JSId: ' + identobj.jsid);
+ var method = document.getElementById('ident_method').value;
+
+ identobj.startSession(method).then(onStartSessionComplete,
+ function(err) {_logData('startSession failed: ' + err);});
+}
+
+function onStartSessionComplete(sessionobj) {
+ _logData('startSession successful: ' + JSON.stringify(sessionobj));
+ sessionobj.addEventListener('statechanged', onSessionStateChanged);
+
+ _logData('Session with jsid as ' + sessionobj.jsid + ' is added for identity with jsid '
+ + sessionobj.identityJSId);
+ var select = document.getElementById("ident_options");
+ if (select.value == sessionobj.identityJSId) {
+ var sess_select = document.getElementById("sess_options");
+ var option = document.createElement('option');
+ option.text = option.value = sessionobj.jsid;
+ sess_select.add(option, 0);
+ }
+}
+
+function onSessionStateChanged(event) {
+ var sessionobj = event.session;
+ _logData('Session with jsid ' + sessionobj.jsid + ' state has changed to '
+ + sessionobj.sessionState);
+}
+
+function requestCredentialsUpdate() {
+ var identobj = tizen.sso.authService.getIdentityByJSId(
+ document.getElementById('ident_options').value);
+ if (identobj == null) {
+ _logData('identity NOT selected/found. Please select/create an identity first');
+ return;
+ }
+ _logData('identity found with JSId: ' + identobj.jsid);
+ var message = document.getElementById('ident_message').value;
+
+ identobj.requestCredentialsUpdate(message).then(function(msg) {
+ document.form_out.form_text.value += "\n" + "requestCredentialsUpdate succeeded";},
+ function(err) {_logData('requestCredentialsUpdate failed: ' + err);});
+}
+
+function store(info) {
+ var identobj = tizen.sso.authService.getIdentityByJSId(
+ document.getElementById('ident_options').value);
+ if (identobj == null) {
+ _logData('identity NOT selected/found. Please select/create an identity first');
+ return;
+ }
+ _logData('identity found with JSId: ' + identobj.jsid);
+ if (info != null) identobj.updateInfo(info);
+
+ identobj.store().then(function(msg) {
+ _logData('store succeeded with resp: ' + JSON.stringify(msg));},
+ function(err) {_logData('store failed: ' + err);});
+}
+
+function addReference() {
+ var identobj = tizen.sso.authService.getIdentityByJSId(
+ document.getElementById('ident_options').value);
+ if (identobj == null) {
+ _logData('identity NOT selected/found. Please select/create an identity first');
+ return;
+ }
+ _logData('identity found with JSId: ' + identobj.jsid);
+ var reference = document.getElementById('ident_addref').value;
+
+ identobj.addReference(reference).then(function(msg) {
+ _logData('addReference succeeded');},
+ function(err) {_logData('addReference failed: ' + err);});
+}
+
+function removeReference() {
+ var identobj = tizen.sso.authService.getIdentityByJSId(
+ document.getElementById('ident_options').value);
+ if (identobj == null) {
+ _logData('identity NOT selected/found. Please select/create an identity first');
+ return;
+ }
+ _logData('identity found with JSId: ' + identobj.jsid);
+ var reference = document.getElementById('ident_remref').value;
+
+ identobj.removeReference(reference).then(function(msg) {
+ _logData('removeReference succeeded');},
+ function(err) {_logData('removeReference failed: ' + err);});
+}
+
+function removeIdentity() {
+ var identobj = tizen.sso.authService.getIdentityByJSId(
+ document.getElementById('ident_options').value);
+ if (identobj == null) {
+ _logData('identity NOT selected/found. Please select/create an identity first');
+ return;
+ }
+ _logData('identity found with JSId: ' + identobj.jsid);
+ identobj.remove().then(onIdentityRemoved,
+ function(err) {_logData('remove failed: ' + err);});
+}
+
+function signout() {
+ var identobj = tizen.sso.authService.getIdentityByJSId(
+ document.getElementById('ident_options').value);
+ if (identobj == null) {
+ _logData('identity NOT selected/found. Please select/create an identity first');
+ return;
+ }
+ _logData('identity found with JSId: ' + identobj.jsid);
+ identobj.signout().then(function(msg) {
+ _logData('signout succeeded');},
+ function(err) {_logData('signout failed: ' + err);});
+}
+
+//authsession interface
+function queryAvailableMechanisms() {
+ var identobj = tizen.sso.authService.getIdentityByJSId(
+ document.getElementById('ident_options').value);
+ if (identobj == null) {
+ _logData('identity NOT selected/found. Please select/create an identity first');
+ return;
+ }
+ _logData('identity found with JSId: ' + identobj.jsid);
+ var sessionobj = identobj.getSessionByJSId(document.getElementById('sess_options').value);
+ if (sessionobj == null) {
+ _logData('session NOT selected/found. Please select/create session first');
+ return;
+ }
+ _logData('session found with JSId: ' + sessionobj.jsid);
+
+ var str = document.getElementById('sess_mechs').value;
+ var wantedMechs = [];
+ if (typeof str === 'string' && str.length > 0) {
+ arr = str.split(",");
+ if (arr.length > 0) wantedMechs = arr;
+ }
+ sessionobj.queryAvailableMechanisms(wantedMechs).then(function(msg) {
+ _logData('queryAvailableMechanisms succeeded with mechanisms:' + JSON.stringify(msg));},
+ function(err) {_logData('queryAvailableMechanisms failed: ' + err);});
+}
+
+function challenge() {
+ var identobj = tizen.sso.authService.getIdentityByJSId(
+ document.getElementById('ident_options').value);
+ if (identobj == null) {
+ _logData('identity NOT selected/found. Please select/create an identity first');
+ return;
+ }
+ _logData('identity found with JSId: ' + identobj.jsid);
+ var sessionobj = identobj.getSessionByJSId(document.getElementById('sess_options').value);
+ if (sessionobj == null) {
+ _logData('session NOT selected/found. Please select/create session first');
+ return;
+ }
+ _logData('session found with JSId: ' + sessionobj.jsid);
+
+ var mech = document.getElementById('sess_mech').value;
+ var sessionData = document.getElementById('sess_data').value;
+
+ sessionobj.challenge(mech, sessionData).then(function(msg) {
+ _logData('challenge succeeded with sessionData: ' + JSON.stringify(msg));},
+ function(err) {_logData('challenge failed: ' + err);});
+}
+
+function cancel() {
+ var identobj = tizen.sso.authService.getIdentityByJSId(
+ document.getElementById('ident_options').value);
+ if (identobj == null) {
+ _logData('identity NOT selected/found. Please select/create an identity first');
+ return;
+ }
+ _logData('identity found with JSId: ' + identobj.jsid);
+ var sessionobj = identobj.getSessionByJSId(document.getElementById('sess_options').value);
+ if (sessionobj == null) {
+ _logData('session NOT selected/found. Please select/create session first');
+ return;
+ }
+ _logData('session found with JSId: ' + sessionobj.jsid);
+
+ sessionobj.removeEventListener('statechanged', onSessionStateChanged);
+ sessionobj.cancel().then(function(msg) {
+ _logData('cancel succeeded');},
+ function(err) {_logData('cancel failed: ' + err);});
+ clearSelectOption(document.getElementById('sess_options'), sessionobj.jsid);
+}
+
+window.onload = function() {
+ document.getElementById('cident_acl').value =
+ JSON.stringify([{"secContext":{"sysContext":"*","appContext":"*"},
+ "method":"password","mechanisms":["password"]}]);
+ document.getElementById('cident_owner').value = "*,*";
+};
+
+</script>
+
+</body>
+</html>
BuildRequires: pkgconfig(evas)
BuildRequires: pkgconfig(gio-2.0)
BuildRequires: pkgconfig(glib-2.0)
-BuildRequires: pkgconfig(tapi)
-BuildRequires: pkgconfig(libudev)
+BuildRequires: pkgconfig(libgsignon-glib)
BuildRequires: pkgconfig(libpulse) >= 5.0
+BuildRequires: pkgconfig(libudev)
BuildRequires: pkgconfig(message-port)
BuildRequires: pkgconfig(notification)
BuildRequires: pkgconfig(pkgmgr)
BuildRequires: pkgconfig(pkgmgr-info)
BuildRequires: pkgconfig(pmapi)
+BuildRequires: pkgconfig(tapi)
BuildRequires: pkgconfig(vconf)
%if %{with wayland}
BuildRequires: pkgconfig(wayland-client)
--- /dev/null
+## Introduction
+This folder contains implementation of Web Single Signon API for Crosswalk runtime.
+API specification can be located at https://code.google.com/p/accounts-sso/source/browse/widl/signon.widl?repo=libgsignon-glib
+
+Backend that provides core functionality is gSSO and more information about that
+component could be found at https://01.org/gsso
\ No newline at end of file
--- /dev/null
+{
+ 'includes':[
+ '../common/common.gypi',
+ ],
+ 'targets': [
+ {
+ 'target_name': 'tizen_sso',
+ 'type': 'loadable_module',
+ 'variables': {
+ 'packages': [
+ 'libgsignon-glib',
+ ],
+ },
+ 'includes': [
+ '../common/pkg-config.gypi',
+ ],
+ 'sources': [
+ 'sso_api.js',
+ 'sso_async_op.cc',
+ 'sso_async_op.h',
+ 'sso_auth_service.cc',
+ 'sso_auth_service.h',
+ 'sso_auth_session.cc',
+ 'sso_auth_session.h',
+ 'sso_extension.cc',
+ 'sso_extension.h',
+ 'sso_identity.cc',
+ 'sso_identity.h',
+ 'sso_identity_info.cc',
+ 'sso_identity_info.h',
+ 'sso_instance.cc',
+ 'sso_instance.h',
+ 'sso_utils.cc',
+ 'sso_utils.h',
+ ],
+ },
+ ],
+}
--- /dev/null
+// Copyright (c) 2014 Intel Corporation. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+///////////////////////////////////////////////////////////////////////////////
+// Utilities
+///////////////////////////////////////////////////////////////////////////////
+
+var g_next_async_call_id = 0;
+var g_async_calls = {};
+var g_next_obj_id = 0;
+
+function AsyncCall(resolve, reject, command) {
+ this.resolve = resolve;
+ this.reject = reject;
+ this.command = command;
+}
+
+function _createPromise(msg) {
+ var promise = new Promise(function(resolve, reject) {
+ g_async_calls[g_next_async_call_id] = new AsyncCall(resolve, reject,
+ msg.asyncOpCmd);
+ });
+ msg.asyncOpId = g_next_async_call_id;
+ extension.postMessage(JSON.stringify(msg));
+ ++g_next_async_call_id;
+ return promise;
+}
+
+function _sendSyncMessage(msg) {
+ return JSON.parse(extension.internal.sendSyncMessage(JSON.stringify(msg)));
+}
+
+function _isCommandInProgress(command) {
+ for (var key in g_async_calls) {
+ if (g_async_calls.hasOwnProperty(key) &&
+ g_async_calls[key].command == command) {
+ return true;
+ }
+ }
+ return false;
+}
+
+function _addConstProperty(obj, propertyKey, propertyValue) {
+ Object.defineProperty(obj, propertyKey, {
+ configurable: true,
+ enumerable: true,
+ writable: false,
+ value: propertyValue
+ });
+}
+
+function _addConstPropertyFromObject(obj, propertyKey, propObject) {
+ if (!propObject.hasOwnProperty(propertyKey))
+ return;
+ Object.defineProperty(obj, propertyKey, {
+ configurable: false,
+ enumerable: true,
+ writable: false,
+ value: propObject[propertyKey]});
+}
+
+function _addPropertyFromObject(obj, propertyKey, propObject) {
+ if (!propObject.hasOwnProperty(propertyKey))
+ return;
+ Object.defineProperty(obj, propertyKey, {
+ configurable: false,
+ enumerable: true,
+ writable: true,
+ value: propObject[propertyKey]});
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// Enumerations and dictionaries
+///////////////////////////////////////////////////////////////////////////////
+
+var IdentityType = {
+ APPLICATION: 0,
+ WEB: 1,
+ NETWORK: 2
+};
+
+var SessionState = {
+ NOT_STARTED: 0,
+ RESOLVING_HOST: 1,
+ CONNECTING: 2,
+ SENDING_DATA: 3,
+ WAITING_REPLY: 4,
+ USER_PENDING: 5,
+ UI_REFRESHING: 6,
+ PROCESS_PENDING: 7,
+ STARTED: 8,
+ PROCESS_CANCELLING: 9,
+ PROCESS_DONE: 10,
+ CUSTOM: 11
+};
+
+var UserPromptPolicy = {
+ DEFAULT: 0,
+ REQUEST_PASSWORD: 1,
+ NO_USER_INTERACTION: 2,
+ VALIDATION: 3
+};
+
+function MechanismQueryResult(obj) {
+ _addConstPropertyFromObject(this, 'method', obj);
+ _addConstPropertyFromObject(this, 'mechanisms', obj);
+}
+
+function IdentityInfo(obj) {
+ _addConstPropertyFromObject(this, 'id', obj);
+ _addConstProperty(this, 'type', _convertToIdentityType(obj.type));
+ _addPropertyFromObject(this, 'username', obj);
+ _addPropertyFromObject(this, 'caption', obj);
+ _addPropertyFromObject(this, 'secret', obj);
+ _addPropertyFromObject(this, 'storeSecret', obj);
+ _addPropertyFromObject(this, 'realms', obj);
+ _addConstPropertyFromObject(this, 'owner', obj);
+ _addPropertyFromObject(this, 'accessControlList', obj);
+}
+
+function _destroyIdentity(ident) {
+ var msg = {
+ 'asyncOpCmd': 'destroyIdentity',
+ 'serviceJSId': g_auth_service.jsid,
+ 'identityJSId': ident.jsid
+ };
+ return _createPromise(msg);
+}
+
+function _getSessionObj(sessionJSId) {
+ var sessobj = null;
+ if (sessionJSId == -1) return null;
+ for (var i = 0; i < g_identities.length; i++) {
+ var identity = g_identities[i];
+ for (var j = 0; j < identity.sessions.length; j++) {
+ var sess = identity.sessions[j];
+ if (sess.jsid == sessionJSId) {
+ sessobj = sess;
+ break;
+ }
+ }
+ }
+ return sessobj;
+}
+
+function _getIdentityObj(id) {
+ if (id == -1) return null;
+ var identobj = null;
+ for (var i = 0; i < g_identities.length; i++) {
+ var curr_ident = g_identities[i];
+ if (curr_ident.info.id == id) {
+ identobj = curr_ident;
+ break;
+ }
+ }
+ return identobj;
+}
+
+function _getIdentityObjByJSId(jsid) {
+ if (jsid == -1) return null;
+ var identobj = null;
+ for (var i = 0; i < g_identities.length; i++) {
+ var curr_ident = g_identities[i];
+ if (curr_ident.jsid == jsid) {
+ identobj = curr_ident;
+ break;
+ }
+ }
+ return identobj;
+}
+
+function _convertToIdentityType(stringtype) {
+ if (stringtype == 'APPLICATION') return IdentityType.APPLICATION;
+ else if (stringtype == 'WEB') return IdentityType.WEB;
+ else if (stringtype == 'NETWORK') return IdentityType.NETWORK;
+ else return IdentityType.WEB;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// Extension msg listener and utility functions
+///////////////////////////////////////////////////////////////////////////////
+var g_identities = [];
+var g_auth_service = new AuthService();
+exports.authService = g_auth_service;
+
+var g_auth_session_listeners = {};
+g_auth_session_listeners['statechanged'] = [];
+
+extension.setMessageListener(function(json) {
+ var msg = JSON.parse(json);
+ if (msg.asyncOpErrorMsg != null) {
+ handleAsyncCallError(msg);
+ return;
+ }
+
+ if (msg.asyncOpCmd != null) {
+ switch (msg.asyncOpCmd) {
+ case 'queryMethods':
+ case 'queryMechanisms':
+ case 'queryIdentities':
+ case 'clear':
+ case 'destroyIdentity':
+ case 'requestCredentialsUpdate':
+ case 'addReference':
+ case 'removeReference':
+ case 'verifyUser':
+ case 'verifyUserPrompt':
+ case 'signout':
+ case 'cancel':
+ handleAsyncCallSuccess(msg);
+ break;
+ case 'getIdentity':
+ handleGetIdentity(msg);
+ break;
+ case 'startSession':
+ handleStartSession(msg);
+ break;
+ case 'store':
+ handleStore(msg);
+ break;
+ case 'remove':
+ handleRemoveIdentity(msg);
+ break;
+ case 'queryAvailableMechanisms':
+ handleQueryAvailableMechanisms(msg);
+ break;
+ case 'challenge':
+ handleChallenge(msg);
+ break;
+ default:
+ handleAsyncCallError(msg);
+ break;
+ }
+ } else if (msg.info != null) {
+ switch (msg.info.info) {
+ case 'signedout':
+ var identobj = g_auth_service.getIdentityByJSId(msg.objectJSId);
+ if (identobj != null && identobj.onsignedout) identobj.onsignedout(identobj);
+ break;
+ case 'removed':
+ if (_isCommandInProgress('remove'))
+ break;
+ var identobj = g_auth_service.getIdentityByJSId(msg.objectJSId);
+ if (identobj != null) {
+ if (identobj.onremoved) identobj.onremoved(identobj);
+ g_identities.splice(g_identities.indexOf(identobj), 1);
+ _destroyIdentity(identobj);
+ }
+ break;
+ case 'sessionStateChanged':
+ handleSessionStateChanged(msg);
+ break;
+ default:
+ console.log('Unknown signal received: ' + JSON.stringify(msg));
+ break;
+ }
+ }
+});
+
+function handleAsyncCallSuccess(msg) {
+ g_async_calls[msg.asyncOpId].resolve(msg.responseData);
+ delete g_async_calls[msg.asyncOpId];
+}
+
+function handleAsyncCallError(msg) {
+ if (msg.asyncOpCmd == 'getIdentity') {
+ var identobj = g_auth_service.getIdentityByJSId(
+ msg.responseData.identityJSId);
+ if (identobj != null)
+ g_identities.splice(g_identities.indexOf(identobj), 1);
+ }
+ g_async_calls[msg.asyncOpId].reject(Error(msg.asyncOpErrorMsg));
+ delete g_async_calls[msg.asyncOpId];
+}
+
+function handleGetIdentity(msg) {
+ var identobj = _getIdentityObjByJSId(msg.responseData.identityJSId);
+ if (identobj) {
+ identobj.info = new IdentityInfo(msg.responseData.info);
+ g_async_calls[msg.asyncOpId].resolve(identobj);
+ } else {
+ g_async_calls[msg.asyncOpId].reject(Error('Identity object not found for getidentity'));
+ }
+ delete g_async_calls[msg.asyncOpId];
+}
+
+function handleStartSession(msg) {
+ var identobj = g_auth_service.getIdentityByJSId(msg.objectJSId);
+ if (identobj) {
+ var session = new AuthSession(msg.responseData, msg.objectJSId);
+ identobj.sessions.push(session);
+ g_async_calls[msg.asyncOpId].resolve(session);
+ } else {
+ g_async_calls[msg.asyncOpId].reject(Error('Identity object not found for session'));
+ }
+ delete g_async_calls[msg.asyncOpId];
+}
+
+function handleStore(msg) {
+ var identobj = g_auth_service.getIdentityByJSId(msg.objectJSId);
+ if (identobj != null) {
+ identobj.info.id = msg.responseData.identityId;
+ g_async_calls[msg.asyncOpId].resolve(identobj);
+ } else {
+ g_async_calls[msg.asyncOpId].reject(Error('Identity NOT FOUND'));
+ }
+ delete g_async_calls[msg.asyncOpId];
+}
+
+function handleRemoveIdentity(msg) {
+ var identobj = g_auth_service.getIdentityByJSId(msg.objectJSId);
+ if (identobj != null) {
+ g_async_calls[msg.asyncOpId].resolve(identobj);
+ g_identities.splice(g_identities.indexOf(identobj), 1);
+ } else {
+ g_async_calls[msg.asyncOpId].reject(Error('Identity NOT FOUND'));
+ }
+ delete g_async_calls[msg.asyncOpId];
+}
+
+function handleSessionStateChanged(msg) {
+ var session = _getSessionObj(msg.objectJSId);
+ if (session == null) return;
+
+ var event = new CustomEvent('statechanged');
+ session.sessionState = msg.info.object.sessionState;
+ _addConstProperty(event, 'session', session);
+ if (msg.message) _addConstProperty(event, 'message', msg.message);
+ session.dispatchEvent(event);
+ if (session.onstatechanged)
+ session.onstatechanged(event);
+}
+
+function handleQueryAvailableMechanisms(msg) {
+ g_async_calls[msg.asyncOpId].resolve(msg.responseData.mechanisms);
+ delete g_async_calls[msg.asyncOpId];
+}
+
+function handleChallenge(msg) {
+ g_async_calls[msg.asyncOpId].resolve(msg.responseData.sessionData);
+ delete g_async_calls[msg.asyncOpId];
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// AuthService
+///////////////////////////////////////////////////////////////////////////////
+
+function AuthService() {
+ this.jsid = ++g_next_obj_id;
+}
+
+AuthService.prototype.queryMethods = function() {
+ var msg = {
+ 'asyncOpCmd': 'queryMethods',
+ 'serviceJSId': this.jsid
+ };
+ return _createPromise(msg);
+};
+
+AuthService.prototype.queryMechanisms = function(method) {
+ var msg = {
+ 'asyncOpCmd': 'queryMechanisms',
+ 'serviceJSId': this.jsid,
+ 'method': method
+ };
+ return _createPromise(msg);
+};
+
+AuthService.prototype.queryIdentities = function(filter) {
+ var msg = {
+ 'asyncOpCmd': 'queryIdentities',
+ 'serviceJSId': this.jsid,
+ 'filter': filter
+ };
+ return _createPromise(msg);
+};
+
+AuthService.prototype.getIdentity = function(identity_id) {
+ var identobj = _getIdentityObj(identity_id);
+ if (identobj == null) {
+ identobj = new Identity(null);
+ g_identities.push(identobj);
+ }
+ var msg = {
+ 'asyncOpCmd': 'getIdentity',
+ 'serviceJSId': this.jsid,
+ 'identityId': identity_id,
+ 'identityJSId': identobj.jsid
+ };
+ return _createPromise(msg);
+};
+
+AuthService.prototype.getIdentityByJSId = function(jsid) {
+ return _getIdentityObjByJSId(jsid);
+};
+
+AuthService.prototype.createIdentity = function(info) {
+ var identobj = new Identity(new IdentityInfo(info));
+ var msg = {
+ 'syncOpCmd': 'createIdentity',
+ 'serviceJSId': this.jsid,
+ 'identityJSId': identobj.jsid
+ };
+ var res = _sendSyncMessage(msg);
+ if (res.syncOpErrorMsg != null) {
+ return res;
+ }
+ g_identities.push(identobj);
+ res.identity = identobj;
+ return res;
+};
+
+AuthService.prototype.clear = function() {
+ var msg = {
+ 'asyncOpCmd': 'clear',
+ 'serviceJSId': this.jsid
+ };
+ return _createPromise(msg);
+};
+
+///////////////////////////////////////////////////////////////////////////////
+// Identity
+///////////////////////////////////////////////////////////////////////////////
+function Identity(info) {
+ this.onsignedout = null;
+ this.onremoved = null;
+ this.info = info;
+ this.sessions = [];
+ this.jsid = ++g_next_obj_id;
+}
+
+Identity.prototype.startSession = function(method) {
+ var msg = {
+ 'asyncOpCmd': 'startSession',
+ 'identityJSId': this.jsid,
+ 'sessionJSId': ++g_next_obj_id,
+ 'method': method
+ };
+ return _createPromise(msg);
+};
+
+Identity.prototype.getSessionByJSId = function(jsid) {
+ if (jsid == -1) return null;
+ var sessobj = null;
+ for (var i = 0; i < this.sessions.length; i++) {
+ var sess = this.sessions[i];
+ if (sess.jsid == jsid) {
+ sessobj = sess;
+ break;
+ }
+ }
+ return sessobj;
+};
+
+Identity.prototype.requestCredentialsUpdate = function(message) {
+ var msg = {
+ 'asyncOpCmd': 'requestCredentialsUpdate',
+ 'identityJSId': this.jsid,
+ 'message': message
+ };
+ return _createPromise(msg);
+};
+
+Identity.prototype.store = function() {
+ var msg = {
+ 'asyncOpCmd': 'store',
+ 'identityJSId': this.jsid,
+ 'info': this.info
+ };
+ return _createPromise(msg);
+};
+
+Identity.prototype.addReference = function(reference) {
+ var msg = {
+ 'asyncOpCmd': 'addReference',
+ 'identityJSId': this.jsid,
+ 'reference': reference
+ };
+ return _createPromise(msg);
+};
+
+Identity.prototype.removeReference = function(reference) {
+ var msg = {
+ 'asyncOpCmd': 'removeReference',
+ 'identityJSId': this.jsid,
+ 'reference': reference
+ };
+ return _createPromise(msg);
+};
+
+Identity.prototype.verifyUser = function(message) {
+ var msg = {
+ 'asyncOpCmd': 'verifyUser',
+ 'identityJSId': this.jsid,
+ 'message': message
+ };
+ return _createPromise(msg);
+};
+
+Identity.prototype.verifyUserPrompt = function(params) {
+ var msg = {
+ 'asyncOpCmd': 'verifyUserPrompt',
+ 'identityJSId': this.jsid,
+ 'params': params
+ };
+ return _createPromise(msg);
+};
+
+Identity.prototype.remove = function() {
+ var msg = {
+ 'asyncOpCmd': 'remove',
+ 'identityJSId': this.jsid
+ };
+ return _createPromise(msg);
+};
+
+Identity.prototype.signout = function() {
+ var msg = {
+ 'asyncOpCmd': 'signout',
+ 'identityJSId': this.jsid
+ };
+ return _createPromise(msg);
+};
+
+Identity.prototype.updateInfo = function(info) {
+ var old = this.info;
+ this.info = new IdentityInfo(info);
+ if (old != null)
+ this.info.id = old.id;
+};
+
+///////////////////////////////////////////////////////////////////////////////
+// AuthSession
+///////////////////////////////////////////////////////////////////////////////
+function AuthSession(obj, identity_jsid) {
+ _addConstProperty(this, 'jsid', obj.sessionJSId);
+ _addConstProperty(this, 'identityJSId', identity_jsid);
+ _addConstPropertyFromObject(this, 'method', obj);
+ _addPropertyFromObject(this, 'sessionState', obj);
+ this.onstatechanged = null;
+}
+
+function isValidType(type) {
+ return (type === 'statechanged');
+}
+
+AuthSession.prototype.addEventListener = function(type, callback) {
+ if (callback != null && isValidType(type)) {
+ if (g_auth_session_listeners[type].indexOf(callback) != -1)
+ g_auth_session_listeners[type].push(callback);
+ }
+};
+
+AuthSession.prototype.removeEventListener = function(type, callback) {
+ if (callback != null && isValidType(type)) {
+ var index = g_auth_session_listeners[type].indexOf(callback);
+ if (index >= 0)
+ g_auth_session_listeners[type].splice(index, 1);
+ }
+};
+
+AuthSession.prototype.dispatchEvent = function(event) {
+ var handled = true;
+ if (typeof event !== 'object' || !isValidType(event.type))
+ return false;
+
+ g_auth_session_listeners[event.type].forEach(function(callback) {
+ var res = callback(event);
+ if (!res && handled) handled = false;
+ });
+ return handled;
+};
+
+AuthSession.prototype.queryAvailableMechanisms = function(wantedMechanisms) {
+ var msg = {
+ 'asyncOpCmd': 'queryAvailableMechanisms',
+ 'sessionJSId': this.jsid,
+ 'wantedMechanisms': wantedMechanisms
+ };
+ return _createPromise(msg);
+};
+
+AuthSession.prototype.challenge = function(mechanism, sessionData) {
+ var msg = {
+ 'asyncOpCmd': 'challenge',
+ 'sessionJSId': this.jsid,
+ 'mechanism': mechanism,
+ 'sessionData': sessionData
+ };
+ return _createPromise(msg);
+};
+
+AuthSession.prototype.cancel = function() {
+ var msg = {
+ 'asyncOpCmd': 'cancel',
+ 'sessionJSId': this.jsid
+ };
+ return _createPromise(msg);
+};
--- /dev/null
+// Copyright (c) 2014 Intel Corporation. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "sso/sso_async_op.h"
+
+#include "common/extension.h"
+
+SSOAsyncOp::SSOAsyncOp(common::Instance* instance,
+ picojson::value* request_data, gpointer user_data)
+ : instance_(instance), request_data_(request_data), user_data_(user_data) {
+}
+
+SSOAsyncOp::~SSOAsyncOp() {
+ if (request_data_)
+ delete request_data_;
+ request_data_ = NULL;
+}
+
+void SSOAsyncOp::PostInfo(const picojson::value& info, int jsid) {
+ picojson::value::object object;
+ object["info"] = info;
+ object["objectJSId"] = picojson::value(static_cast<double>(jsid));
+ picojson::value value(object);
+ instance_->PostMessage(value.serialize().c_str());
+}
+
+void SSOAsyncOp::PostResult(const picojson::value& response, int jsid) {
+ picojson::value::object object;
+ object["asyncOpCmd"] = picojson::value(GetCommand());
+ object["asyncOpId"] = picojson::value(GetId());
+ object["objectJSId"] = picojson::value(static_cast<double>(jsid));
+ object["responseData"] = response;
+ picojson::value value(object);
+ instance_->PostMessage(value.serialize().c_str());
+}
+
+void SSOAsyncOp::PostResult(int jsid) {
+ picojson::value::object object;
+ object["asyncOpCmd"] = picojson::value(GetCommand());
+ object["asyncOpId"] = picojson::value(GetId());
+ object["objectJSId"] = picojson::value(static_cast<double>(jsid));
+ picojson::value value(object);
+ instance_->PostMessage(value.serialize().c_str());
+}
+
+void SSOAsyncOp::PostError(const gchar* error, int jsid) {
+ picojson::value::object object;
+ object["asyncOpCmd"] = picojson::value(GetCommand());
+ object["asyncOpId"] = picojson::value(GetId());
+ object["asyncOpErrorMsg"] = picojson::value(error);
+ object["objectJSId"] = picojson::value(static_cast<double>(jsid));
+ picojson::value value(object);
+ instance_->PostMessage(value.serialize().c_str());
+}
+
+void SSOAsyncOp::PostError(const gchar* error, const picojson::value& response,
+ int jsid) {
+ picojson::value::object object;
+ object["asyncOpCmd"] = picojson::value(GetCommand());
+ object["asyncOpId"] = picojson::value(GetId());
+ object["asyncOpErrorMsg"] = picojson::value(error);
+ object["objectJSId"] = picojson::value(static_cast<double>(jsid));
+ object["responseData"] = response;
+ picojson::value value(object);
+ instance_->PostMessage(value.serialize().c_str());
+}
+
+double SSOAsyncOp::GetId() const {
+ if (!request_data_)
+ return -1;
+ return request_data_->get("asyncOpId").get<double>();
+}
+
+std::string SSOAsyncOp::GetCommand() const {
+ if (!request_data_)
+ return std::string("Unknown");
+ return request_data_->get("asyncOpCmd").get<std::string>();
+}
--- /dev/null
+// Copyright (c) 2014 Intel Corporation. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef SSO_SSO_ASYNC_OP_H_
+#define SSO_SSO_ASYNC_OP_H_
+
+#include <glib.h>
+
+#include <string>
+
+#include "common/picojson.h"
+#include "common/utils.h"
+
+namespace common {
+
+class Instance;
+
+} // namespace common
+
+class SSOAsyncOp {
+ public:
+ SSOAsyncOp(common::Instance* instance, picojson::value* request_data,
+ gpointer user_data);
+ virtual ~SSOAsyncOp();
+
+ void PostInfo(const picojson::value& info, int jsid);
+ void PostResult(const picojson::value& response, int jsid);
+ void PostResult(int jsid);
+ void PostError(const gchar* error, int jsid);
+ void PostError(const gchar* error, const picojson::value& response, int jsid);
+
+ picojson::value* request_data() const { return request_data_; }
+ gpointer user_data() const { return user_data_; }
+
+ private:
+ picojson::value* request_data_;
+ common::Instance* instance_;
+ gpointer user_data_;
+
+ double GetId() const;
+ std::string GetCommand() const;
+
+ DISALLOW_COPY_AND_ASSIGN(SSOAsyncOp);
+};
+
+#endif // SSO_SSO_ASYNC_OP_H_
--- /dev/null
+// Copyright (c) 2014 Intel Corporation. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "sso/sso_auth_service.h"
+
+#include <libgsignon-glib/signon-identity.h>
+#include <stdlib.h>
+#include <string>
+
+#include "common/picojson.h"
+#include "sso/sso_async_op.h"
+#include "sso/sso_instance.h"
+#include "sso/sso_utils.h"
+
+MechanismQueryResult::MechanismQueryResult(const std::string& method,
+ const gchar* const* mechs)
+ : method_(method) {
+ if (mechs) {
+ while (*mechs)
+ mechanisms_.push_back(*mechs++);
+ }
+}
+
+MechanismQueryResult::~MechanismQueryResult() {
+}
+
+void MechanismQueryResult::FromJSON(const picojson::value& value) {
+ if (value.contains("method"))
+ method_ = value.get("method").to_str();
+ if (value.contains("mechanisms"))
+ mechanisms_ = SSOUtils::FromJSONArrayToStringVector(
+ value.get("mechanisms").get<picojson::array>());
+}
+
+picojson::value MechanismQueryResult::ToJSON() const {
+ picojson::value::object object;
+ if (!method_.empty())
+ object["method"] = picojson::value(method_);
+ if (!mechanisms_.empty())
+ object["mechanisms"] = picojson::value(
+ SSOUtils::FromStringVectorToJSONArray(mechanisms_));
+ return picojson::value(object);
+}
+
+bool MechanismQueryResult::ContainsData() const {
+ return (!method_.empty() || !mechanisms_.empty());
+}
+
+void SSOAuthService::QueryMethodsCb(SignonAuthService* auth_service,
+ gchar** methods, const GError* error, gpointer user_data) {
+ SSOAsyncOp* async_op = reinterpret_cast<SSOAsyncOp*>(user_data);
+ SSOAuthService* service = reinterpret_cast<SSOAuthService*>(
+ async_op->user_data());
+ if (error) {
+ async_op->PostError(error->message, service->jsid());
+ delete async_op;
+ return;
+ }
+ picojson::value::object resp;
+ resp["methods"] = picojson::value(SSOUtils::FromStringArrayToJSONArray(
+ reinterpret_cast<const gchar* const*>(methods)));
+ g_strfreev(methods);
+ async_op->PostResult(picojson::value(resp), service->jsid());
+ delete async_op;
+}
+
+void SSOAuthService::QueryMechanismsCb(SignonAuthService* auth_service,
+ const gchar* method, gchar** mechanisms, const GError* error,
+ gpointer user_data) {
+ SSOAsyncOp* async_op = reinterpret_cast<SSOAsyncOp*>(user_data);
+ SSOAuthService* service = reinterpret_cast<SSOAuthService*>(
+ async_op->user_data());
+ if (error) {
+ async_op->PostError(error->message, service->jsid());
+ delete async_op;
+ return;
+ }
+ MechanismQueryResult query_result(
+ async_op->request_data()->get("method").get<std::string>(),
+ reinterpret_cast<const gchar* const*>(mechanisms));
+ if (mechanisms)
+ g_strfreev(mechanisms);
+
+ async_op->PostResult(query_result.ToJSON(), service->jsid());
+ delete async_op;
+}
+
+void SSOAuthService::QueryIdentitiesCb(SignonAuthService* auth_service,
+ SignonIdentityList* identity_list, const GError* error,
+ gpointer user_data) {
+ GList* iter = identity_list;
+ SSOAsyncOp* async_op = reinterpret_cast<SSOAsyncOp*>(user_data);
+ SSOAuthService* service = reinterpret_cast<SSOAuthService*>(
+ async_op->user_data());
+ if (error) {
+ async_op->PostError(error->message, service->jsid());
+ delete async_op;
+ return;
+ }
+ picojson::array infos;
+ while (iter) {
+ SignonIdentityInfo* info = static_cast<SignonIdentityInfo*>(iter->data);
+ SSOIdentityInfo identity_info(info);
+ infos.push_back(identity_info.ToJSON());
+ iter = g_list_next(iter);
+ }
+ g_list_free_full(identity_list, (GDestroyNotify) signon_identity_info_free);
+
+ async_op->PostResult(picojson::value(infos), service->jsid());
+ delete async_op;
+}
+
+void SSOAuthService::GetIdentityCb(SignonIdentity* identity,
+ SignonIdentityInfo* info, const GError* error, gpointer user_data) {
+ SSOAsyncOp* async_op = reinterpret_cast<SSOAsyncOp*>(user_data);
+ SSOAuthService* service = reinterpret_cast<SSOAuthService*>(
+ async_op->user_data());
+ if (error) {
+ picojson::value::object resp;
+ resp["identityJSId"] = async_op->request_data()->get("identityJSId");
+ async_op->PostError(error->message, picojson::value(resp), service->jsid());
+ delete async_op;
+ return;
+ }
+ SSOIdentityPtr id_ptr = service->AddIdentity(identity,
+ static_cast<int>(async_op->request_data()->get(
+ "identityJSId").get<double>()), signon_identity_info_get_id(info));
+ SSOIdentityInfo id_info(info);
+ picojson::value::object resp;
+ resp["identityJSId"] = async_op->request_data()->get("identityJSId");
+ resp["info"] = id_info.ToJSON();
+ async_op->PostResult(picojson::value(resp), service->jsid());
+ delete async_op;
+}
+
+void SSOAuthService::ClearCb(SignonAuthService* auth_service, gboolean success,
+ const GError* error, gpointer user_data) {
+ SSOAsyncOp* async_op = reinterpret_cast<SSOAsyncOp*>(user_data);
+ SSOAuthService* service = reinterpret_cast<SSOAuthService*>(
+ async_op->user_data());
+ if (error) {
+ async_op->PostError(error->message, service->jsid());
+ delete async_op;
+ return;
+ }
+ picojson::value::object resp;
+ resp["success"] = picojson::value(static_cast<bool>(success));
+ async_op->PostResult(picojson::value(resp), service->jsid());
+ delete async_op;
+}
+
+SSOAuthService::SSOAuthService(common::Instance* instance,
+ const std::string& appcontext)
+ : instance_(instance), auth_service_(0), jsid_(-1),
+ appcontext_(appcontext) {
+ auth_service_ = signon_auth_service_new();
+}
+
+SSOAuthService::~SSOAuthService() {
+ if (auth_service_) {
+ g_object_unref(auth_service_);
+ auth_service_ = 0;
+ }
+}
+
+void SSOAuthService::HandleQueryMethods(const picojson::value& value) {
+ signon_auth_service_query_methods(auth_service_,
+ &SSOAuthService::QueryMethodsCb,
+ new SSOAsyncOp(instance_, new picojson::value(value), this));
+}
+
+void SSOAuthService::HandleQueryMechanisms(const picojson::value& value) {
+ signon_auth_service_query_mechanisms(auth_service_,
+ reinterpret_cast<const gchar*>(value.get("method").to_str().c_str()),
+ &SSOAuthService::QueryMechanismsCb,
+ new SSOAsyncOp(instance_, new picojson::value(value), this));
+}
+
+void SSOAuthService::HandleQueryIdentities(const picojson::value& value) {
+ GHashTable* filters = IdentityFilterItem::FromJSONValueArray(
+ value.get("filter").get<picojson::object>());
+ signon_auth_service_query_identities(auth_service_, filters,
+ reinterpret_cast<const gchar*>(appcontext_.c_str()),
+ &SSOAuthService::QueryIdentitiesCb,
+ new SSOAsyncOp(instance_, new picojson::value(value), this));
+ if (filters)
+ g_hash_table_unref(filters);
+}
+
+void SSOAuthService::HandleGetIdentity(const picojson::value& value) {
+ double id = value.get("identityId").get<double>();
+ SignonIdentity* identity = signon_identity_new_with_context_from_db(
+ static_cast<gint>(id),
+ reinterpret_cast<const gchar*>(appcontext_.c_str()));
+ signon_identity_query_info(identity, &SSOAuthService::GetIdentityCb,
+ new SSOAsyncOp(instance_, new picojson::value(value), this));
+}
+
+void SSOAuthService::HandleCreateIdentity(const picojson::value& value) {
+ SignonIdentity* identity = signon_identity_new_with_context(
+ reinterpret_cast<const gchar*>(appcontext_.c_str()));
+ AddIdentity(identity,
+ static_cast<int>(value.get("identityJSId").get<double>()), 0);
+}
+
+void SSOAuthService::HandleDestroyIdentity(const picojson::value& value) {
+ identities_.erase(static_cast<int>(value.get("identityJSId").get<double>()));
+}
+
+void SSOAuthService::HandleClear(const picojson::value& value) {
+ signon_auth_service_clear(auth_service_, &SSOAuthService::ClearCb,
+ new SSOAsyncOp(instance_, new picojson::value(value), this));
+}
+
+SSOIdentityPtr SSOAuthService::AddIdentity(SignonIdentity* identity, int jsid,
+ int identity_id) {
+ std::map<int, SSOIdentityPtr>::const_iterator it = identities_.find(jsid);
+ if (it != identities_.end())
+ return it->second;
+
+ SSOIdentityPtr identity_ptr;
+ if (identity_id != 0) {
+ for (it = identities_.begin(); it != identities_.end(); ++it) {
+ SSOIdentityPtr ptr = it->second;
+ if (identity_id == ptr->identity_id()) {
+ identity_ptr = ptr;
+ break;
+ }
+ }
+ }
+ if (!identity_ptr) {
+ identity_ptr = std::make_shared<SSOIdentity>(instance_, identity,
+ identity_id, jsid);
+ }
+ identities_.insert(std::make_pair(jsid, identity_ptr));
+ return identity_ptr;
+}
+
+SSOIdentityPtr SSOAuthService::GetIdentityPtr(int jsid) const {
+ SSOIdentityPtr identity_ptr;
+ std::map<int, SSOIdentityPtr>::const_iterator it = identities_.find(jsid);
+ if (it != identities_.end())
+ identity_ptr = it->second;
+ return identity_ptr;
+}
+
+SSOAuthSessionPtr SSOAuthService::GetAuthSessionPtr(int jsid) const {
+ std::map<int, SSOIdentityPtr>::const_iterator it;
+ for (it = identities_.begin(); it != identities_.end(); ++it) {
+ SSOAuthSessionPtr ptr = it->second->GetAuthSessionPtr(jsid);
+ if (ptr)
+ return ptr;
+ }
+ return SSOAuthSessionPtr();
+}
--- /dev/null
+// Copyright (c) 2014 Intel Corporation. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef SSO_SSO_AUTH_SERVICE_H_
+#define SSO_SSO_AUTH_SERVICE_H_
+
+#include <libgsignon-glib/signon-auth-service.h>
+
+#include <map>
+#include <string>
+#include <utility>
+#include <vector>
+
+#include "sso/sso_auth_session.h"
+#include "sso/sso_identity.h"
+#include "sso/sso_utils.h"
+
+namespace common {
+
+class Instance;
+
+} // namespace common
+
+namespace picojson {
+
+class value;
+
+} // namespace picojson
+
+class MechanismQueryResult {
+ public:
+ MechanismQueryResult(const std::string& method, const gchar* const* mechs);
+ ~MechanismQueryResult();
+
+ void FromJSON(const picojson::value& value);
+ picojson::value ToJSON() const;
+ bool ContainsData() const;
+
+ private:
+ std::string method_;
+ std::vector<std::string> mechanisms_;
+};
+
+class SSOAuthService {
+ public:
+ SSOAuthService(common::Instance* instance, const std::string& appcontext);
+ virtual ~SSOAuthService();
+
+ int jsid() const { return jsid_; }
+ void set_jsid(int id) { jsid_ = id; }
+ const std::string& appcontext() const { return appcontext_; }
+
+ void HandleQueryMethods(const picojson::value& value);
+ void HandleQueryMechanisms(const picojson::value& value);
+ void HandleQueryIdentities(const picojson::value& value);
+ void HandleGetIdentity(const picojson::value& value);
+ void HandleCreateIdentity(const picojson::value& value);
+ void HandleDestroyIdentity(const picojson::value& value);
+ void HandleStartSession(const picojson::value& value);
+ void HandleClear(const picojson::value& value);
+
+ SSOIdentityPtr GetIdentityPtr(int jsid) const;
+ SSOAuthSessionPtr GetAuthSessionPtr(int jsid) const;
+
+ private:
+ static void QueryMethodsCb(SignonAuthService* auth_service, gchar** methods,
+ const GError* error, gpointer user_data);
+ static void QueryMechanismsCb(SignonAuthService* auth_service,
+ const gchar* method, gchar** mechanisms, const GError* error,
+ gpointer user_data);
+ static void QueryIdentitiesCb(SignonAuthService* auth_service,
+ SignonIdentityList* identity_list, const GError* error,
+ gpointer user_data);
+ static void GetIdentityCb(SignonIdentity* identity, SignonIdentityInfo* info,
+ const GError* error, gpointer user_data);
+ static void ClearCb(SignonAuthService* auth_service, gboolean success,
+ const GError* error, gpointer user_data);
+ SSOIdentityPtr AddIdentity(SignonIdentity* identity, int jsid, int id);
+
+ private:
+ common::Instance* instance_;
+ SignonAuthService* auth_service_;
+ std::map<int, SSOIdentityPtr> identities_;
+ int jsid_;
+ std::string appcontext_;
+
+ DISALLOW_COPY_AND_ASSIGN(SSOAuthService);
+};
+
+#endif // SSO_SSO_AUTH_SERVICE_H_
--- /dev/null
+// Copyright (c) 2014 Intel Corporation. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "sso/sso_auth_session.h"
+
+#include "sso/sso_async_op.h"
+#include "sso/sso_instance.h"
+#include "sso/sso_utils.h"
+
+SessionData::SessionData()
+ : data_(0) {
+ data_ = g_hash_table_new_full(g_str_hash, g_str_equal, g_free,
+ signon_gvalue_free);
+}
+
+SessionData::~SessionData() {
+ if (data_) {
+ g_hash_table_unref(data_);
+ data_ = NULL;
+ }
+}
+
+bool SessionData::IsSupportedType(GType type) const {
+ return (signon_gtype_to_variant_type(type) != 0);
+}
+
+void SessionData::ToJSONType(picojson::object& object, const gchar* key,
+ GValue* value) const {
+ GType type = G_VALUE_TYPE(value);
+ if (!IsSupportedType(type))
+ return;
+
+ switch (type) {
+ case G_TYPE_STRING: {
+ std::string str = g_value_get_string(value);
+ if (!str.empty())
+ object[std::string(key)] = picojson::value(str);
+ break;
+ }
+ case G_TYPE_BOOLEAN: {
+ object[std::string(key)] = picojson::value(
+ static_cast<bool>(g_value_get_boolean(value)));
+ break;
+ }
+ case G_TYPE_UCHAR: {
+ object[std::string(key)] = picojson::value(
+ static_cast<double>(g_value_get_uchar(value)));
+ break;
+ }
+ case G_TYPE_INT: {
+ object[std::string(key)] = picojson::value(
+ static_cast<double>(g_value_get_int(value)));
+ break;
+ }
+ case G_TYPE_UINT: {
+ object[std::string(key)] = picojson::value(
+ static_cast<double>(g_value_get_uint(value)));
+ break;
+ }
+ case G_TYPE_INT64: {
+ object[std::string(key)] = picojson::value(
+ static_cast<double>(g_value_get_int64(value)));
+ break;
+ }
+ case G_TYPE_UINT64: {
+ object[std::string(key)] = picojson::value(
+ static_cast<double>(g_value_get_uint64(value)));
+ break;
+ }
+ case G_TYPE_DOUBLE: {
+ object[std::string(key)] = picojson::value(g_value_get_double(value));
+ break;
+ }
+ default:
+ if (type == G_TYPE_STRV) {
+ GVariant* var = g_value_get_variant(value);
+ const gchar** strv = g_variant_get_strv(var, 0);
+ if (strv) {
+ object[std::string(key)] = picojson::value(
+ SSOUtils::FromStringArrayToJSONArray(
+ reinterpret_cast<const gchar* const*>(strv)));
+ }
+ }
+ break;
+ }
+}
+
+void SessionData::InsertStringData(const std::string& key,
+ const picojson::value& obj) {
+ GValue* val = g_new0(GValue, 1);
+ g_value_init(val, G_TYPE_STRING);
+ g_value_set_string(val, obj.get(key).to_str().c_str());
+ g_hash_table_insert(data_, g_strdup(key.c_str()), val);
+}
+
+void SessionData::InsertData(const std::string& key,
+ const picojson::value& obj) {
+ GValue* val = NULL;
+ if (obj.is<bool>()) {
+ val = g_new0(GValue, 1);
+ g_value_init(val, G_TYPE_BOOLEAN);
+ g_value_set_boolean(val, (gboolean) obj.get("renewToken").get<bool>());
+ g_hash_table_insert(data_, g_strdup(key.c_str()), val);
+ } else if (obj.is<std::string>()) {
+ val = g_new0(GValue, 1);
+ g_value_init(val, G_TYPE_STRING);
+ g_value_set_string(val, obj.to_str().c_str());
+ g_hash_table_insert(data_, g_strdup(key.c_str()), val);
+ } else if (obj.is<double>()) {
+ val = g_new0(GValue, 1);
+ g_value_init(val, G_TYPE_INT);
+ g_value_set_int(val, (gint) obj.get<double>());
+ g_hash_table_insert(data_, g_strdup(key.c_str()), val);
+ } else if (obj.is<picojson::array>() && IsSupportedType(G_TYPE_STRV)) {
+ val = g_new0(GValue, 1);
+ g_value_init(val, G_TYPE_STRV);
+ gchar** strv = SSOUtils::FromJSONArrayToStringArray(
+ obj.get<picojson::array>());
+ GVariant* var = g_variant_new_strv(strv, -1);
+ g_strfreev(strv);
+ g_value_set_variant(val, var);
+ g_hash_table_insert(data_, g_strdup(key.c_str()), val);
+ }
+}
+
+bool SessionData::InsertKnownData(const std::string& key,
+ const picojson::value& obj) {
+ bool inserted = true;
+ GValue* val = NULL;
+ if (key == "username" ||
+ key == "secret" ||
+ key == "realm" ||
+ key == "networkProxy" ||
+ key == "caption") {
+ InsertStringData(key, obj);
+ } else if (key == "networkTimeout") {
+ val = g_new0(GValue, 1);
+ g_value_init(val, G_TYPE_UINT);
+ g_value_set_uint(val, (guint) obj.get("networkTimeout").get<double>());
+ g_hash_table_insert(data_, g_strdup(key.c_str()), val);
+ } else if (key == "renewToken") {
+ val = g_new0(GValue, 1);
+ g_value_init(val, G_TYPE_BOOLEAN);
+ g_value_set_boolean(val, (gboolean) obj.get("renewToken").get<bool>());
+ g_hash_table_insert(data_, g_strdup(key.c_str()), val);
+ } else if (key == "userPromptPolicy") {
+ val = g_new0(GValue, 1);
+ g_value_init(val, G_TYPE_UINT);
+ g_value_set_uint(val, (guint) obj.get("userPromptPolicy").get<double>());
+ g_hash_table_insert(data_, g_strdup(key.c_str()), val);
+ } else if (key == "window_id") {
+ val = g_new0(GValue, 1);
+ g_value_init(val, G_TYPE_INT);
+ g_value_set_int(val, (gint) obj.get("window_id").get<double>());
+ g_hash_table_insert(data_, g_strdup(key.c_str()), val);
+ } else {
+ inserted = false;
+ }
+ return inserted;
+}
+
+void SessionData::FromJSON(const picojson::value& value) {
+ if (!value.is<picojson::object>())
+ return;
+
+ const picojson::object& obj = value.get<picojson::object>();
+ picojson::object::const_iterator it;
+ for (it = obj.begin(); it != obj.end(); ++it) {
+ std::string key = it->first;
+ picojson::value val = it->second;
+ if (!InsertKnownData(key, val)) {
+ InsertData(key, val);
+ }
+ }
+}
+
+picojson::value SessionData::ToJSON() const {
+ GHashTableIter iter;
+ g_hash_table_iter_init(&iter, data_);
+
+ char* key = NULL;
+ GValue* value = NULL;
+ picojson::value::object object;
+ while (g_hash_table_iter_next(&iter, reinterpret_cast<gpointer*>(&key),
+ reinterpret_cast<gpointer*>(&value))) {
+ ToJSONType(object, key, value);
+ }
+ return picojson::value(object);
+}
+
+GVariant* SessionData::ToVariant() const {
+ return signon_hash_table_to_variant(data_);
+}
+
+void SessionData::FromVariant(GVariant* vdata) {
+ if (data_) {
+ g_hash_table_unref(data_);
+ data_ = NULL;
+ }
+ data_ = signon_hash_table_from_variant(vdata);
+}
+
+void SSOAuthSession::QueryAvailableMechanismsCb(SignonAuthSession* self,
+ gchar** mechanisms, const GError* error, gpointer user_data) {
+ SSOAsyncOp* async_op = reinterpret_cast<SSOAsyncOp*>(user_data);
+ SSOAuthSession* session = reinterpret_cast<SSOAuthSession*>(
+ async_op->user_data());
+ if (error) {
+ async_op->PostError(error->message, session->jsid_);
+ delete async_op;
+ return;
+ }
+
+ picojson::value::object resp;
+ resp["mechanisms"] = picojson::value(SSOUtils::FromStringArrayToJSONArray(
+ reinterpret_cast<const gchar* const*>(mechanisms)));
+ g_strfreev(mechanisms);
+
+ async_op->PostResult(picojson::value(resp), session->jsid_);
+ delete async_op;
+}
+
+void SSOAuthSession::ChallengeCb(GObject* source_object, GAsyncResult* res,
+ gpointer user_data) {
+ SSOAsyncOp* async_op = reinterpret_cast<SSOAsyncOp*>(user_data);
+ SSOAuthSession* session = reinterpret_cast<SSOAuthSession*>(
+ async_op->user_data());
+
+ GError* error = NULL;
+ SignonAuthSession* auth_session = SIGNON_AUTH_SESSION(source_object);
+ GVariant* v_reply = signon_auth_session_process_finish(auth_session, res,
+ &error);
+ if (error) {
+ async_op->PostError(error->message, session->jsid_);
+ delete async_op;
+ g_error_free(error);
+ return;
+ }
+
+ SessionData data;
+ data.FromVariant(v_reply);
+ g_variant_unref(v_reply);
+ picojson::value::object resp;
+ resp["sessionData"] = picojson::value(data.ToJSON());
+ async_op->PostResult(picojson::value(resp), session->jsid_);
+ delete async_op;
+}
+
+void SSOAuthSession::StateChangeCb(SignonAuthSession* self, gint state,
+ gchar* message, gpointer user_data) {
+ SSOAuthSession* session = reinterpret_cast<SSOAuthSession*>(user_data);
+ SSOAsyncOp op(session->instance_, 0, session);
+ session->session_state_ = static_cast<SessionState>(state);
+ picojson::value::object info;
+ info["info"] = picojson::value("sessionStateChanged");
+ if (message)
+ info["message"] = picojson::value(std::string(message));
+ info["object"] = session->ToJSON();
+ op.PostInfo(picojson::value(info), session->jsid_);
+}
+
+SSOAuthSession::SSOAuthSession(common::Instance* instance,
+ SignonAuthSession* session, const std::string& method, int jsid)
+ : instance_(instance), session_(session), method_(method),
+ session_state_(SESSION_STATE_NOT_STARTED), jsid_(jsid) {
+ if (session_) {
+ g_signal_connect(session_, "state-changed",
+ G_CALLBACK(&SSOAuthSession::StateChangeCb), this);
+ }
+}
+
+SSOAuthSession::~SSOAuthSession() {
+ if (session_) {
+ g_object_unref(session_);
+ session_ = NULL;
+ }
+}
+
+void SSOAuthSession::HandleQueryAvailableMechanisms(
+ const picojson::value& value) {
+ gchar** mechs = SSOUtils::FromJSONArrayToStringArray(
+ value.get("wantedMechanisms").get<picojson::array>());
+ signon_auth_session_query_available_mechanisms(session_,
+ const_cast<const gchar**>(mechs),
+ &SSOAuthSession::QueryAvailableMechanismsCb,
+ new SSOAsyncOp(instance_, new picojson::value(value), this));
+ g_strfreev(mechs);
+}
+
+void SSOAuthSession::HandleChallenge(const picojson::value& value) {
+ SessionData session_data;
+ session_data.FromJSON(value.get("sessionData"));
+ GVariant* vsess = session_data.ToVariant();
+ signon_auth_session_process_async(session_, vsess,
+ value.get("mechanism").to_str().c_str(), 0, &SSOAuthSession::ChallengeCb,
+ new SSOAsyncOp(instance_, new picojson::value(value), this));
+}
+
+void SSOAuthSession::HandleCancel(const picojson::value& value) {
+ SSOAsyncOp op(instance_, new picojson::value(value), this);
+ signon_auth_session_cancel(session_);
+ op.PostResult(jsid());
+}
+
+picojson::value SSOAuthSession::ToJSON() const {
+ picojson::value::object object;
+ object["method"] = picojson::value(method_);
+ object["sessionJSId"] = picojson::value(static_cast<double>(jsid_));
+ object["sessionState"] = picojson::value(static_cast<double>(session_state_));
+ return picojson::value(object);
+}
--- /dev/null
+// Copyright (c) 2014 Intel Corporation. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef SSO_SSO_AUTH_SESSION_H_
+#define SSO_SSO_AUTH_SESSION_H_
+
+#include <glib.h>
+#include <glib-object.h>
+#include <libgsignon-glib/signon-auth-session.h>
+#include <libgsignon-glib/signon-utils.h>
+
+#include <memory>
+#include <string>
+
+#include "common/utils.h"
+#include "sso/sso_utils.h"
+
+namespace common {
+
+class Instance;
+
+} // namespace common
+
+typedef enum {
+ SESSION_STATE_NOT_STARTED,
+ SESSION_STATE_RESOLVING_HOST,
+ SESSION_STATE_CONNECTING,
+ SESSION_STATE_SENDING_DATA,
+ SESSION_STATE_WAITING_REPLY,
+ SESSION_STATE_USER_PENDING,
+ SESSION_STATE_UI_REFRESHING,
+ SESSION_STATE_PROCESS_PENDING,
+ SESSION_STATE_STARTED,
+ SESSION_STATE_PROCESS_CANCELLING,
+ SESSION_STATE_PROCESS_DONE,
+ SESSION_STATE_CUSTOM
+} SessionState;
+
+class SessionData {
+ public:
+ SessionData();
+ virtual ~SessionData();
+
+ void FromJSON(const picojson::value& value);
+ picojson::value ToJSON() const;
+
+ GVariant* ToVariant() const;
+ void FromVariant(GVariant* vdata);
+
+ private:
+ GHashTable* data_;
+
+ bool IsSupportedType(GType type) const;
+ void ToJSONType(picojson::object& object, const gchar* key,
+ GValue* value) const;
+ void InsertStringData(const std::string& key, const picojson::value& obj);
+ void InsertData(const std::string& key, const picojson::value& obj);
+ bool InsertKnownData(const std::string& key, const picojson::value& obj);
+};
+
+class SSOAuthSession {
+ public:
+ SSOAuthSession(common::Instance* instance, SignonAuthSession* session,
+ const std::string& method, int jsid);
+ virtual ~SSOAuthSession();
+
+ int jsid() const { return jsid_; }
+ picojson::value ToJSON() const;
+
+ void HandleQueryAvailableMechanisms(const picojson::value& value);
+ void HandleChallenge(const picojson::value& value);
+ void HandleCancel(const picojson::value& value);
+
+ private:
+ static void QueryAvailableMechanismsCb(SignonAuthSession* self,
+ gchar** mechanisms, const GError* error, gpointer user_data);
+ static void ChallengeCb(GObject* source_object, GAsyncResult* res,
+ gpointer user_data);
+ static void StateChangeCb(SignonAuthSession* self, gint state, gchar* message,
+ gpointer user_data);
+
+ common::Instance* instance_;
+ SignonAuthSession* session_;
+ std::string method_;
+ SessionState session_state_;
+ int jsid_;
+
+ DISALLOW_COPY_AND_ASSIGN(SSOAuthSession);
+};
+typedef std::shared_ptr<SSOAuthSession> SSOAuthSessionPtr;
+
+#endif // SSO_SSO_AUTH_SESSION_H_
--- /dev/null
+// Copyright (c) 2014 Intel Corporation. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "sso/sso_extension.h"
+
+#include <glib-object.h>
+
+#include "sso/sso_instance.h"
+
+common::Extension* CreateExtension() {
+#if !GLIB_CHECK_VERSION (2, 36, 0)
+ g_type_init();
+#endif
+ return new SSOExtension();
+}
+
+extern const char kSource_sso_api[];
+
+SSOExtension::SSOExtension() {
+ SetExtensionName("tizen.sso");
+ SetJavaScriptAPI(kSource_sso_api);
+}
+
+SSOExtension::~SSOExtension() {
+}
+
+common::Instance* SSOExtension::CreateInstance() {
+ return new SSOInstance();
+}
--- /dev/null
+// Copyright (c) 2014 Intel Corporation. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef SSO_SSO_EXTENSION_H_
+#define SSO_SSO_EXTENSION_H_
+
+#include "common/extension.h"
+
+class SSOExtension: public common::Extension {
+ public:
+ SSOExtension();
+ virtual ~SSOExtension();
+
+ private:
+ // common::Extension implementation.
+ virtual common::Instance* CreateInstance();
+};
+
+#endif // SSO_SSO_EXTENSION_H_
--- /dev/null
+// Copyright (c) 2014 Intel Corporation. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "sso/sso_identity.h"
+
+#include "sso/sso_async_op.h"
+#include "sso/sso_instance.h"
+#include "sso/sso_utils.h"
+
+IdentityFilterItem::IdentityFilterItem() {
+}
+
+IdentityFilterItem::~IdentityFilterItem() {
+}
+
+void IdentityFilterItem::FromJSON(const std::string& key,
+ const picojson::value& value) {
+ key_ = key;
+ if (value.contains("value_"))
+ value_ = value.get("value").to_str();
+}
+
+GHashTable* IdentityFilterItem::FromJSONValueArray(
+ const picojson::object& object) {
+ GHashTable* filters = NULL;
+ if (!object.empty())
+ filters = g_hash_table_new_full((GHashFunc) g_str_hash,
+ (GEqualFunc) g_str_equal, (GDestroyNotify) g_free,
+ (GDestroyNotify) g_free);
+ picojson::object::const_iterator it;
+ for (it = object.begin(); it != object.end(); ++it) {
+ IdentityFilterItem item;
+ item.FromJSON(it->first, picojson::value(it->second));
+ g_hash_table_insert(filters, g_strdup(item.key_.c_str()),
+ g_strdup(item.value_.c_str()));
+ }
+ return filters;
+}
+
+void SSOIdentity::PostResultCb(SignonIdentity* self, const GError* error,
+ gpointer user_data) {
+ SSOAsyncOp* async_op = reinterpret_cast<SSOAsyncOp*>(user_data);
+ SSOIdentity* identity = reinterpret_cast<SSOIdentity*>(
+ async_op->user_data());
+ if (error) {
+ async_op->PostError(error->message, identity->jsid());
+ delete async_op;
+ return;
+ }
+ async_op->PostResult(identity->jsid());
+ delete async_op;
+}
+
+void SSOIdentity::StoreCb(SignonIdentity* self, guint32 id, const GError* error,
+ gpointer user_data) {
+ SSOAsyncOp* async_op = reinterpret_cast<SSOAsyncOp*>(user_data);
+ SSOIdentity* identity = reinterpret_cast<SSOIdentity*>(
+ async_op->user_data());
+ if (error) {
+ async_op->PostError(error->message, identity->jsid());
+ delete async_op;
+ return;
+ }
+ identity->set_identity_id(id);
+ picojson::value::object resp;
+ resp["identityId"] = picojson::value(static_cast<double>(
+ identity->identity_id()));
+ async_op->PostResult(picojson::value(resp), identity->jsid());
+ delete async_op;
+}
+
+void SSOIdentity::VerifyUserCb(SignonIdentity* self, gboolean valid,
+ const GError* error, gpointer user_data) {
+ SSOAsyncOp* async_op = reinterpret_cast<SSOAsyncOp*>(user_data);
+ SSOIdentity* identity = reinterpret_cast<SSOIdentity*>(
+ async_op->user_data());
+ if (error) {
+ async_op->PostError(error->message, identity->jsid());
+ delete async_op;
+ return;
+ }
+ picojson::value::object resp;
+ resp["valid"] = picojson::value(static_cast<bool>(valid));
+ async_op->PostResult(picojson::value(resp), identity->jsid());
+ delete async_op;
+}
+
+void SSOIdentity::SignedoutSignalCb(gpointer self, gpointer user_data) {
+ SSOIdentity* identity = reinterpret_cast<SSOIdentity*>(user_data);
+ SSOAsyncOp op(identity->instance_, 0, identity);
+ picojson::value::object info;
+ info["info"] = picojson::value("signedout");
+ op.PostInfo(picojson::value(info), identity->jsid());
+}
+
+void SSOIdentity::RemovedSignalCb(gpointer self, gpointer user_data) {
+ SSOIdentity* identity = reinterpret_cast<SSOIdentity*>(user_data);
+ SSOAsyncOp op(identity->instance_, 0, identity);
+ picojson::value::object info;
+ info["info"] = picojson::value("removed");
+ op.PostInfo(picojson::value(info), identity->jsid());
+}
+
+SSOIdentity::SSOIdentity(common::Instance* instance, SignonIdentity* identity,
+ int identity_id, int jsid)
+ : instance_(instance), identity_(identity), identity_id_(identity_id),
+ jsid_(jsid) {
+ if (identity_) {
+ g_signal_connect(identity_, "signout",
+ G_CALLBACK(&SSOIdentity::SignedoutSignalCb), this);
+ g_signal_connect(identity_, "removed",
+ G_CALLBACK(&SSOIdentity::RemovedSignalCb), this);
+ }
+}
+
+SSOIdentity::~SSOIdentity() {
+ if (identity_) {
+ g_object_unref(identity_);
+ identity_ = NULL;
+ }
+}
+
+void SSOIdentity::HandleStartSession(const picojson::value& value) {
+ GError* error = NULL;
+ std::string method = value.get("method").to_str();
+ SignonAuthSession* session = signon_identity_create_session(identity_,
+ method.c_str(), &error);
+ SSOAsyncOp op(instance_, new picojson::value(value), this);
+ if (error) {
+ op.PostError(error->message, jsid());
+ g_clear_error(&error);
+ return;
+ }
+ SSOAuthSessionPtr sess_ptr = AddAuthSession(session, method,
+ static_cast<int>(value.get("sessionJSId").get<double>()));
+ op.PostResult(sess_ptr->ToJSON(), jsid());
+}
+
+void SSOIdentity::HandleDestroySession(const picojson::value& value) {
+ sessions_.erase(static_cast<int>(value.get("sessionJSId").get<double>()));
+}
+
+void SSOIdentity::HandleRequestCredentialsUpdate(const picojson::value& value) {
+ signon_identity_request_credentials_update(identity_,
+ reinterpret_cast<const gchar*>(value.get("message").to_str().c_str()),
+ &SSOIdentity::PostResultCb,
+ new SSOAsyncOp(instance_, new picojson::value(value), this));
+}
+
+void SSOIdentity::HandleStore(const picojson::value& value,
+ const std::string& appcontext) {
+ SSOIdentityInfo info(NULL);
+ info.FromJSON(value.get("info"), appcontext);
+ signon_identity_store_credentials_with_info(identity_,
+ reinterpret_cast<const SignonIdentityInfo*>(info.info()),
+ &SSOIdentity::StoreCb,
+ new SSOAsyncOp(instance_, new picojson::value(value), this));
+}
+
+void SSOIdentity::HandleAddReference(const picojson::value& value) {
+ signon_identity_add_reference(identity_,
+ reinterpret_cast<const gchar*>(value.get("reference").to_str().c_str()),
+ &SSOIdentity::PostResultCb,
+ new SSOAsyncOp(instance_, new picojson::value(value), this));
+}
+
+void SSOIdentity::HandleRemoveReference(const picojson::value& value) {
+ signon_identity_remove_reference(identity_,
+ reinterpret_cast<const gchar*>(value.get("reference").to_str().c_str()),
+ &SSOIdentity::PostResultCb,
+ new SSOAsyncOp(instance_, new picojson::value(value), this));
+}
+
+void SSOIdentity::HandleVerifyUser(const picojson::value& value) {
+ picojson::object obj;
+ obj["message"] = value.get("message");
+ GVariant* args = ArgsToVariant(obj);
+ signon_identity_verify_user(identity_, args, &SSOIdentity::VerifyUserCb,
+ new SSOAsyncOp(instance_, new picojson::value(value), this));
+}
+
+void SSOIdentity::HandleVerifyUserPrompt(const picojson::value& value) {
+ GVariant* args = ArgsToVariant(value.get<picojson::object>());
+ signon_identity_verify_user(identity_, args, &SSOIdentity::VerifyUserCb,
+ new SSOAsyncOp(instance_, new picojson::value(value), this));
+}
+
+void SSOIdentity::HandleRemove(const picojson::value& value) {
+ signon_identity_remove(identity_, &SSOIdentity::PostResultCb,
+ new SSOAsyncOp(instance_, new picojson::value(value), this));
+}
+
+void SSOIdentity::HandleSignOut(const picojson::value& value) {
+ signon_identity_signout(identity_, &SSOIdentity::PostResultCb,
+ new SSOAsyncOp(instance_, new picojson::value(value), this));
+}
+
+SSOAuthSessionPtr SSOIdentity::AddAuthSession(SignonAuthSession* session,
+ const std::string& method, int jsid) {
+ SSOAuthSessionPtr authsession_ptr;
+ std::map<int, SSOAuthSessionPtr>::const_iterator it = sessions_.find(jsid);
+ if (it != sessions_.end()) {
+ authsession_ptr = it->second;
+ } else {
+ authsession_ptr = std::make_shared<SSOAuthSession>(instance_, session,
+ method, jsid);
+ sessions_.insert(std::make_pair(jsid, authsession_ptr));
+ }
+ return authsession_ptr;
+}
+
+SSOAuthSessionPtr SSOIdentity::GetAuthSessionPtr(int jsid) const {
+ SSOAuthSessionPtr authsession_ptr;
+ std::map<int, SSOAuthSessionPtr>::const_iterator it = sessions_.find(jsid);
+ if (it != sessions_.end())
+ authsession_ptr = it->second;
+ return authsession_ptr;
+}
+
+GVariant* SSOIdentity::ArgsToVariant(const picojson::object& obj) {
+ GVariantBuilder builder;
+ g_variant_builder_init(&builder, G_VARIANT_TYPE_VARDICT);
+ picojson::object::const_iterator it;
+ for (it = obj.begin(); it != obj.end(); ++it) {
+ std::string key = it->first;
+ picojson::value val = it->second;
+ g_variant_builder_add(&builder, "{sv}", key.c_str(), val.to_str().c_str());
+ }
+ return g_variant_builder_end(&builder);
+}
--- /dev/null
+// Copyright (c) 2014 Intel Corporation. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef SSO_SSO_IDENTITY_H_
+#define SSO_SSO_IDENTITY_H_
+
+#include <libgsignon-glib/signon-identity.h>
+#include <libgsignon-glib/signon-identity-info.h>
+
+#include <map>
+#include <string>
+#include <utility>
+
+#include "common/picojson.h"
+#include "common/utils.h"
+#include "sso/sso_auth_session.h"
+#include "sso/sso_identity_info.h"
+
+namespace common {
+
+class Instance;
+
+} // namespace common
+
+typedef enum {
+ USER_PROMPT_POLICY_DEFAULT,
+ USER_PROMPT_POLICY_REQUEST_PASSWORD,
+ USER_PROMPT_POLICY_NO_USER_INTERACTION,
+ USER_PROMPT_POLICY_VALIDATION
+} UserPromptPolicy;
+
+class IdentityFilterItem {
+ public:
+ IdentityFilterItem();
+ ~IdentityFilterItem();
+
+ static GHashTable* FromJSONValueArray(const picojson::object& object);
+
+ private:
+ std::string key_;
+ std::string value_;
+
+ void FromJSON(const std::string& key, const picojson::value& value);
+};
+
+class SSOIdentity {
+ public:
+ SSOIdentity(common::Instance* instance, SignonIdentity* identity,
+ int identity_id, int jsid);
+ virtual ~SSOIdentity();
+
+ int jsid() const { return jsid_; }
+ int identity_id() const { return identity_id_; }
+ void set_identity_id(int id) { identity_id_ = id; }
+
+ SSOAuthSessionPtr GetAuthSessionPtr(int jsid) const;
+
+ void HandleStartSession(const picojson::value& value);
+ void HandleDestroySession(const picojson::value& value);
+ void HandleRequestCredentialsUpdate(const picojson::value& value);
+ void HandleStore(const picojson::value& value, const std::string& appcontext);
+ void HandleAddReference(const picojson::value& value);
+ void HandleRemoveReference(const picojson::value& value);
+ void HandleVerifyUser(const picojson::value& value);
+ void HandleVerifyUserPrompt(const picojson::value& value);
+ void HandleRemove(const picojson::value& value);
+ void HandleSignOut(const picojson::value& value);
+
+ private:
+ static void PostResultCb(SignonIdentity* self, const GError* error,
+ gpointer user_data);
+ static void StoreCb(SignonIdentity* self, guint32 id, const GError* error,
+ gpointer user_data);
+ static void VerifyUserCb(SignonIdentity* self, gboolean valid,
+ const GError* error, gpointer user_data);
+ static void SignedoutSignalCb(gpointer self, gpointer user_data);
+ static void RemovedSignalCb(gpointer self, gpointer user_data);
+ GVariant* ArgsToVariant(const picojson::object& obj);
+ SSOAuthSessionPtr AddAuthSession(SignonAuthSession* session,
+ const std::string& method, int jsid);
+
+ common::Instance* instance_;
+ SignonIdentity* identity_;
+ std::map<int, SSOAuthSessionPtr> sessions_;
+ int jsid_;
+ int identity_id_;
+
+ DISALLOW_COPY_AND_ASSIGN(SSOIdentity);
+};
+typedef std::shared_ptr<SSOIdentity> SSOIdentityPtr;
+
+#endif // SSO_SSO_IDENTITY_H_
--- /dev/null
+// Copyright (c) 2014 Intel Corporation. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "sso/sso_identity_info.h"
+
+#include <libgsignon-glib/signon-security-context.h>
+
+SecurityContext::SecurityContext() {
+}
+
+SecurityContext::~SecurityContext() {
+}
+
+void SecurityContext::FromJSON(const picojson::value& value) {
+ if (value.contains("sysContext"))
+ sys_context_ = value.get("sysContext").to_str();
+ if (value.contains("appContext"))
+ app_context_ = value.get("appContext").to_str();
+}
+
+picojson::value SecurityContext::ToJSON() const {
+ picojson::value::object object;
+ object["sys_context"] = picojson::value(sys_context_);
+ object["app_context"] = picojson::value(app_context_);
+ return picojson::value(object);
+}
+
+bool SecurityContext::ContainsData() const {
+ return (!sys_context_.empty() || !app_context_.empty());
+}
+
+ACLEntry::ACLEntry() {
+}
+
+ACLEntry::~ACLEntry() {
+}
+
+void ACLEntry::FromJSON(const picojson::value& value) {
+ if (value.contains("securityContext"))
+ security_context_.FromJSON(value.get("securityContext"));
+ if (value.contains("method"))
+ method_ = value.get("method").to_str();
+ if (value.contains("mechanisms"))
+ mechanisms_ = SSOUtils::FromJSONArrayToStringVector(
+ value.get("mechanisms").get<picojson::array>());
+}
+
+picojson::value ACLEntry::ToJSON() const {
+ picojson::value::object object;
+ if (security_context_.ContainsData())
+ object["security_context"] = security_context_.ToJSON();
+ if (!method_.empty())
+ object["method"] = picojson::value(method_);
+ if (!mechanisms_.empty())
+ object["mechanisms"] = picojson::value(
+ SSOUtils::FromStringVectorToJSONArray(
+ (const std::vector<std::string>&) mechanisms_));
+ return picojson::value(object);
+}
+
+std::vector<ACLEntry> ACLEntry::FromJSONValueArray(
+ const picojson::array& array) {
+ std::vector<ACLEntry> acl;
+ picojson::array::const_iterator it;
+ for (it = array.begin(); it != array.end(); ++it) {
+ ACLEntry entry;
+ entry.FromJSON(*it);
+ acl.push_back(entry);
+ }
+ return acl;
+}
+
+picojson::value ACLEntry::ToJSONValueArray(
+ const std::vector<ACLEntry>& entries) {
+ picojson::array array;
+ std::vector<ACLEntry>::const_iterator it;
+ for (it = entries.begin(); it != entries.end(); ++it) {
+ ACLEntry entry = *it;
+ if (entry.ContainsData())
+ array.push_back(entry.ToJSON());
+ }
+ return picojson::value(array);
+}
+
+bool ACLEntry::ContainsData() const {
+ return (security_context_.ContainsData() ||
+ !method_.empty() ||
+ !mechanisms_.empty());
+}
+
+void SSOIdentityInfo::AddMethodMechanisms(gpointer method, gpointer mechanisms,
+ gpointer user_data) {
+ ACLEntry* entry = reinterpret_cast<ACLEntry*>(user_data);
+ entry->set_method(std::string(reinterpret_cast<const gchar*>(method)));
+ entry->set_mechanisms(SSOUtils::FromStringArrayToStringVector(
+ reinterpret_cast<const gchar* const*>(mechanisms)));
+}
+
+std::vector<ACLEntry> SSOIdentityInfo::GetACL(SignonIdentityInfo* info) const {
+ std::vector<ACLEntry> acl;
+ SignonSecurityContextList* info_acl =
+ signon_identity_info_get_access_control_list(info);
+ if (!info_acl)
+ return acl;
+
+ for (info_acl = g_list_first(info_acl);
+ info_acl != NULL;
+ info_acl = g_list_next(info_acl)) {
+ const SignonSecurityContext* context =
+ reinterpret_cast<const SignonSecurityContext*>(info_acl->data);
+ const gchar* sysctx = signon_security_context_get_system_context(context);
+ SecurityContext ctx;
+ if (sysctx)
+ ctx.set_sys_context(sysctx);
+
+ const gchar* appctx = signon_security_context_get_application_context(
+ context);
+ if (appctx)
+ ctx.set_app_context(appctx);
+ ACLEntry entry;
+ entry.set_security_context(ctx);
+
+ GHashTable* methods = signon_identity_info_get_methods(info);
+ if (methods)
+ g_hash_table_foreach(methods, &SSOIdentityInfo::AddMethodMechanisms,
+ &entry);
+ if (sysctx || appctx || methods)
+ acl.push_back(entry);
+ }
+ return acl;
+}
+
+SecurityContext SSOIdentityInfo::GetOwner(SignonIdentityInfo* info) const {
+ const SignonSecurityContext* context = signon_identity_info_get_owner(info);
+ SecurityContext ctx;
+ if (context) {
+ ctx.set_app_context(context->app_ctx);
+ ctx.set_sys_context(context->sys_ctx);
+ }
+ return ctx;
+}
+
+SSOIdentityInfo::SSOIdentityInfo(SignonIdentityInfo* info)
+ : info_(0) {
+ if (info)
+ info_ = signon_identity_info_copy(info);
+}
+
+SSOIdentityInfo::~SSOIdentityInfo() {
+ if (info_) {
+ signon_identity_info_free(info_);
+ info_ = NULL;
+ }
+}
+
+void SSOIdentityInfo::FromJSON(const picojson::value& value,
+ const std::string& appcontext) {
+ if (info_)
+ signon_identity_info_free(info_);
+ info_ = signon_identity_info_new();
+ if (value.contains("type"))
+ signon_identity_info_set_identity_type(info_,
+ static_cast<SignonIdentityType>(value.get("type").get<double>()));
+
+ if (value.contains("username"))
+ signon_identity_info_set_username(info_,
+ value.get("username").to_str().c_str());
+
+ if (value.contains("secret"))
+ signon_identity_info_set_secret(info_, value.get("secret").to_str().c_str(),
+ value.get("storeSecret").get<bool>());
+
+ if (value.contains("caption"))
+ signon_identity_info_set_caption(info_,
+ value.get("caption").to_str().c_str());
+
+ if (value.contains("realms")) {
+ gchar** strv = SSOUtils::FromJSONArrayToStringArray(
+ value.get("realms").get<picojson::array>());
+ if (strv) {
+ signon_identity_info_set_realms(info_,
+ reinterpret_cast<const gchar* const*>(strv));
+ g_strfreev(strv);
+ }
+ }
+
+ if (value.contains("owner")) {
+ SecurityContext ctx;
+ ctx.FromJSON(value.get("owner"));
+ if (ctx.app_context().empty())
+ ctx.set_app_context(appcontext);
+ if (ctx.ContainsData()) {
+ signon_identity_info_set_owner_from_values(info_,
+ ctx.sys_context().c_str(), ctx.app_context().c_str());
+ }
+ }
+
+ if (value.contains("accessControlList")) {
+ std::vector<ACLEntry> acl = ACLEntry::FromJSONValueArray(
+ value.get("accessControlList").get<picojson::array>());
+ std::vector<ACLEntry>::const_iterator it;
+ for (it = acl.begin(); it != acl.end(); ++it) {
+ ACLEntry entry = *it;
+ if (!entry.method().empty() && !entry.mechanisms().empty()) {
+ gchar** mechs = SSOUtils::FromStringVectorToStringArray(
+ entry.mechanisms());
+ if (mechs) {
+ signon_identity_info_set_method(info_, entry.method().c_str(),
+ reinterpret_cast<const gchar* const*>(mechs));
+ g_strfreev(mechs);
+ }
+ }
+ if (entry.security_context().ContainsData()) {
+ SignonSecurityContext* sc = signon_security_context_new_from_values(
+ entry.security_context().sys_context().c_str(),
+ entry.security_context().app_context().c_str());
+ signon_identity_info_access_control_list_append(info_, sc);
+ }
+ }
+ }
+}
+
+picojson::value SSOIdentityInfo::ToJSON() const {
+ picojson::value::object object;
+ if (!info_)
+ return picojson::value(object);
+
+ object["id"] = picojson::value(
+ static_cast<double>(signon_identity_info_get_id(info_)));
+
+ SignonIdentityType type = signon_identity_info_get_identity_type(info_);
+ object["type"] = picojson::value(static_cast<double>(type));
+
+ const gchar* str = signon_identity_info_get_username(info_);
+ if (str)
+ object["username"] = picojson::value(std::string(str));
+
+ object["store_secret"] = picojson::value(
+ static_cast<bool>(signon_identity_info_get_storing_secret(info_)));
+
+ str = signon_identity_info_get_caption(info_);
+ if (str)
+ object["caption"] = picojson::value(std::string(str));
+
+ const gchar* const* strv = signon_identity_info_get_realms(info_);
+ if (strv)
+ object["realms"] = picojson::value(
+ SSOUtils::FromStringArrayToJSONArray(strv));
+
+ SecurityContext owner = GetOwner(info_);
+ if (!owner.app_context().empty() || !owner.sys_context().empty())
+ object["owner"] = owner.ToJSON();
+
+ std::vector<ACLEntry> acl = GetACL(info_);
+ if (!acl.empty())
+ object["access_control_list"] = ACLEntry::ToJSONValueArray(acl);
+
+ return picojson::value(object);
+}
--- /dev/null
+// Copyright (c) 2014 Intel Corporation. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef SSO_SSO_IDENTITY_INFO_H_
+#define SSO_SSO_IDENTITY_INFO_H_
+
+#include <libgsignon-glib/signon-identity-info.h>
+
+#include <memory>
+#include <string>
+#include <vector>
+
+#include "common/picojson.h"
+#include "common/utils.h"
+#include "sso/sso_utils.h"
+
+class SecurityContext {
+ public:
+ SecurityContext();
+ ~SecurityContext();
+
+ const std::string& sys_context() const { return sys_context_; }
+ void set_sys_context(const std::string& sc) { sys_context_ = sc; }
+ const std::string& app_context() const { return app_context_; }
+ void set_app_context(const std::string& ac) { app_context_ = ac; }
+
+ void FromJSON(const picojson::value& value);
+ picojson::value ToJSON() const;
+
+ bool ContainsData() const;
+
+ private:
+ std::string sys_context_;
+ std::string app_context_;
+};
+
+class ACLEntry {
+ public:
+ ACLEntry();
+ ~ACLEntry();
+
+ const SecurityContext& security_context() const { return security_context_; }
+ void set_security_context(const SecurityContext& ctx) {
+ security_context_ = ctx;
+ }
+ const std::string& method() const { return method_; }
+ void set_method(const std::string& method) { method_ = method; }
+ const std::vector<std::string>& mechanisms() const { return mechanisms_; }
+ void set_mechanisms(const std::vector<std::string>& mechs) {
+ mechanisms_ = mechs;
+ }
+
+ static std::vector<ACLEntry> FromJSONValueArray(const picojson::array& array);
+ static picojson::value ToJSONValueArray(const std::vector<ACLEntry>& entries);
+ bool ContainsData() const;
+
+ private:
+ SecurityContext security_context_;
+ std::string method_;
+ std::vector<std::string> mechanisms_;
+
+ void FromJSON(const picojson::value& value);
+ picojson::value ToJSON() const;
+};
+
+class SSOIdentityInfo {
+ public:
+ explicit SSOIdentityInfo(SignonIdentityInfo* info);
+ virtual ~SSOIdentityInfo();
+
+ void FromJSON(const picojson::value& value, const std::string& appcontext);
+ picojson::value ToJSON() const;
+
+ SignonIdentityInfo* info() const { return info_; }
+
+ private:
+ SecurityContext GetOwner(SignonIdentityInfo* info) const;
+ std::vector<ACLEntry> GetACL(SignonIdentityInfo* info) const;
+ static void AddMethodMechanisms(gpointer method, gpointer mechanisms,
+ gpointer user_data);
+
+ SignonIdentityInfo* info_;
+
+ DISALLOW_COPY_AND_ASSIGN(SSOIdentityInfo);
+};
+typedef std::shared_ptr<SSOIdentityInfo> SSOIdentityInfoPtr;
+
+#endif // SSO_SSO_IDENTITY_INFO_H_
--- /dev/null
+// Copyright (c) 2014 Intel Corporation. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "sso/sso_instance.h"
+
+#include <sstream>
+#include <string>
+
+#include "common/picojson.h"
+#include "sso/sso_async_op.h"
+#include "sso/sso_auth_service.h"
+
+SSOInstance::SSOInstance() {
+ std::string id_str = common::Extension::GetRuntimeVariable("app_id", 64);
+ std::istringstream buf(id_str);
+ picojson::value id_val;
+ picojson::parse(id_val, buf);
+ sso_auth_service_ = new SSOAuthService(this, id_val.get<std::string>());
+}
+
+SSOInstance::~SSOInstance() {
+ delete sso_auth_service_;
+}
+
+SSOAuthService* SSOInstance::GetService(const picojson::value& v) const {
+ SSOAuthService* service = 0;
+ int jsid = static_cast<int>(v.get("serviceJSId").get<double>());
+ if (sso_auth_service_->jsid() == -1) {
+ sso_auth_service_->set_jsid(jsid);
+ service = sso_auth_service_;
+ } else if (jsid == sso_auth_service_->jsid()) {
+ service = sso_auth_service_;
+ }
+ return service;
+}
+
+SSOIdentityPtr SSOInstance::GetIdentity(const picojson::value& v) const {
+ int jsid = static_cast<int>(v.get("identityJSId").get<double>());
+ return sso_auth_service_->GetIdentityPtr(jsid);
+}
+
+SSOAuthSessionPtr SSOInstance::GetAuthSession(const picojson::value& v) const {
+ int jsid = static_cast<int>(v.get("sessionJSId").get<double>());
+ return sso_auth_service_->GetAuthSessionPtr(jsid);
+}
+
+void SSOInstance::PostError(const picojson::value& v, const std::string& msg) {
+ SSOAsyncOp op(this, new picojson::value(v), 0);
+ op.PostError(msg.c_str(), -1);
+}
+
+void SSOInstance::HandleAuthServiceMessage(const std::string& cmd,
+ const picojson::value& v) {
+ SSOAuthService* service = GetService(v);
+ if (!service) {
+ PostError(v, "Invalid Service Object");
+ return;
+ }
+
+ if (cmd == "queryMethods") {
+ service->HandleQueryMethods(v);
+ } else if (cmd == "queryMechanisms") {
+ service->HandleQueryMechanisms(v);
+ } else if (cmd == "queryIdentities") {
+ service->HandleQueryIdentities(v);
+ } else if (cmd == "getIdentity") {
+ service->HandleGetIdentity(v);
+ } else if (cmd == "destroyIdentity") {
+ service->HandleDestroyIdentity(v);
+ } else if (cmd == "clear") {
+ service->HandleClear(v);
+ } else {
+ std::cerr << "Received unknown message: " << cmd << "\n";
+ }
+}
+
+void SSOInstance::HandleIdentityMessage(const std::string& cmd,
+ const picojson::value& v) {
+ SSOIdentityPtr identity = GetIdentity(v);
+ if (!identity) {
+ PostError(v, "Invalid Identity Object");
+ return;
+ }
+
+ if (cmd == "startSession") {
+ identity->HandleStartSession(v);
+ } else if (cmd == "destroySession") {
+ identity->HandleDestroySession(v);
+ } else if (cmd == "requestCredentialsUpdate") {
+ identity->HandleRequestCredentialsUpdate(v);
+ } else if (cmd == "store") {
+ identity->HandleStore(v, sso_auth_service_->appcontext());
+ } else if (cmd == "addReference") {
+ identity->HandleAddReference(v);
+ } else if (cmd == "removeReference") {
+ identity->HandleRemoveReference(v);
+ } else if (cmd == "verifyUser") {
+ identity->HandleVerifyUser(v);
+ } else if (cmd == "verifyUserPrompt") {
+ identity->HandleVerifyUserPrompt(v);
+ } else if (cmd == "remove") {
+ identity->HandleRemove(v);
+ } else if (cmd == "signout") {
+ identity->HandleSignOut(v);
+ } else {
+ std::cerr << "Received unknown message: " << cmd << "\n";
+ }
+}
+
+void SSOInstance::HandleAuthSessionMessage(const std::string& cmd,
+ const picojson::value& v) {
+ SSOAuthSessionPtr session = GetAuthSession(v);
+ if (!session) {
+ PostError(v, "Invalid AuthSession Object");
+ return;
+ }
+
+ if (cmd == "queryAvailableMechanisms") {
+ session->HandleQueryAvailableMechanisms(v);
+ } else if (cmd == "challenge") {
+ session->HandleChallenge(v);
+ } else if (cmd == "cancel") {
+ session->HandleCancel(v);
+ } else {
+ std::cerr << "Received unknown message: " << cmd << "\n";
+ }
+}
+
+void SSOInstance::HandleMessage(const char* message) {
+ picojson::value v;
+
+ std::string err;
+ picojson::parse(v, message, message + strlen(message), &err);
+ if (!err.empty()) {
+ return;
+ }
+ std::string cmd = v.get("asyncOpCmd").to_str();
+ if (cmd == "queryMethods" ||
+ cmd == "queryMechanisms" ||
+ cmd == "queryIdentities" ||
+ cmd == "getIdentity" ||
+ cmd == "destroyIdentity" ||
+ cmd == "clear") {
+ HandleAuthServiceMessage(cmd, v);
+ } else if (cmd == "startSession" ||
+ cmd == "requestCredentialsUpdate" ||
+ cmd == "store" ||
+ cmd == "addReference" ||
+ cmd == "removeReference" ||
+ cmd == "verifyUser" ||
+ cmd == "verifyUserPrompt" ||
+ cmd == "remove" ||
+ cmd == "signout") {
+ HandleIdentityMessage(cmd, v);
+ } else if (cmd == "queryAvailableMechanisms" ||
+ cmd == "challenge" ||
+ cmd == "cancel") {
+ HandleAuthSessionMessage(cmd, v);
+ } else {
+ std::cerr << "Received unknown message: " << cmd << "\n";
+ }
+}
+
+void SSOInstance::HandleSyncMessage(const char* message) {
+ picojson::value::object obj;
+ picojson::value v;
+ std::string err;
+ picojson::parse(v, message, message + strlen(message), &err);
+ if (!err.empty()) {
+ obj["synOpErrorMsg"] = picojson::value("Unable to parse message");
+ SendSyncReply(picojson::value(obj).serialize().c_str());
+ return;
+ }
+
+ std::string cmd = v.get("syncOpCmd").to_str();
+ SSOAuthService* service = 0;
+ if (cmd == "createIdentity") {
+ service = GetService(v);
+ if (service)
+ service->HandleCreateIdentity(v);
+ else
+ obj["synOpErrorMsg"] = picojson::value("Invalid Service Object");
+ } else {
+ obj["synOpErrorMsg"] = picojson::value("Unknown sync command");
+ }
+ SendSyncReply(picojson::value(obj).serialize().c_str());
+}
--- /dev/null
+// Copyright (c) 2014 Intel Corporation. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef SSO_SSO_INSTANCE_H_
+#define SSO_SSO_INSTANCE_H_
+
+#include <string>
+#include <thread> // NOLINT
+
+#include "common/extension.h"
+#include "sso/sso_auth_session.h"
+#include "sso/sso_identity.h"
+
+class SSOAuthService;
+
+class SSOInstance: public common::Instance {
+ public:
+ SSOInstance();
+ virtual ~SSOInstance();
+
+ private:
+ // common::Instance implementation.
+ virtual void HandleMessage(const char* msg);
+ virtual void HandleSyncMessage(const char* msg);
+
+ SSOAuthService* GetService(const picojson::value& v) const;
+ SSOIdentityPtr GetIdentity(const picojson::value& v) const;
+ SSOAuthSessionPtr GetAuthSession(const picojson::value& v) const;
+
+ void HandleAuthServiceMessage(const std::string& cmd,
+ const picojson::value& v);
+ void HandleIdentityMessage(const std::string& cmd, const picojson::value& v);
+ void HandleAuthSessionMessage(const std::string& cmd,
+ const picojson::value& v);
+ void PostError(const picojson::value& v, const std::string& msg);
+
+ SSOAuthService* sso_auth_service_;
+};
+
+#endif // SSO_SSO_INSTANCE_H_
--- /dev/null
+// Copyright (c) 2014 Intel Corporation. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "sso/sso_utils.h"
+
+#include <glib.h>
+
+SSOUtils::SSOUtils() {
+}
+
+SSOUtils::~SSOUtils() {
+}
+
+picojson::value SSOUtils::FromStringToJSONValue(const char* string) {
+ return string ? picojson::value(string) : picojson::value();
+}
+
+picojson::array SSOUtils::FromStringArrayToJSONArray(
+ const char* const* strings) {
+ picojson::array array;
+ while (*strings) {
+ array.push_back(picojson::value(*strings++));
+ }
+ return array;
+}
+
+char** SSOUtils::FromJSONArrayToStringArray(const picojson::array& array) {
+ char** res = reinterpret_cast<char**>(g_malloc0(
+ sizeof(char*) * (array.size() + 1)));
+ std::vector<picojson::value>::const_iterator it;
+ gint i = 0;
+ for (it = array.begin(); it != array.end(); ++it) {
+ picojson::value val = *it;
+ res[i++] = g_strdup(val.to_str().c_str());
+ }
+ return res;
+}
+
+picojson::array SSOUtils::FromStringVectorToJSONArray(
+ const std::vector<std::string>& vector) {
+ picojson::array array;
+ std::vector<std::string>::const_iterator it;
+ for (it = vector.begin(); it != vector.end(); ++it) {
+ array.push_back(picojson::value(*it));
+ }
+ return array;
+}
+
+std::vector<std::string> SSOUtils::FromJSONArrayToStringVector(
+ const picojson::array& array) {
+ std::vector<std::string> res;
+ picojson::array::const_iterator it;
+ for (it = array.begin(); it != array.end(); ++it) {
+ picojson::value val = *it;
+ res.push_back(val.to_str());
+ }
+ return res;
+}
+
+std::vector<std::string> SSOUtils::FromStringArrayToStringVector(
+ const char* const* strings) {
+ std::vector<std::string> vec;
+ if (strings) {
+ while (*strings)
+ vec.push_back(*strings++);
+ }
+ return vec;
+}
+
+char** SSOUtils::FromStringVectorToStringArray(
+ const std::vector<std::string>& vector) {
+ char** res = reinterpret_cast<char**>(g_malloc0(
+ sizeof(char*) * (vector.size() + 1)));
+ gint i = 0;
+ std::vector<std::string>::const_iterator it;
+ for (it = vector.begin(); it != vector.end(); ++it) {
+ res[i++] = g_strdup((*it).c_str());
+ }
+ return res;
+}
--- /dev/null
+// Copyright (c) 2014 Intel Corporation. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef SSO_SSO_UTILS_H_
+#define SSO_SSO_UTILS_H_
+
+#include <string>
+#include <vector>
+
+#include "common/picojson.h"
+
+class SSOUtils {
+ public:
+ SSOUtils();
+ ~SSOUtils();
+
+ static picojson::value FromStringToJSONValue(const char* string);
+ static picojson::array FromStringArrayToJSONArray(
+ const char* const* strings);
+ static char** FromJSONArrayToStringArray(const picojson::array& array);
+ static picojson::array FromStringVectorToJSONArray(
+ const std::vector<std::string>& vector);
+ static std::vector<std::string> FromJSONArrayToStringVector(
+ const picojson::array& array);
+ static std::vector<std::string> FromStringArrayToStringVector(
+ const char* const* strings);
+ static char** FromStringVectorToStringArray(
+ const std::vector<std::string>& vector);
+};
+
+#endif // SSO_SSO_UTILS_H_
'dependencies': [
'audiosystem/audiosystem.gyp:*',
'vehicle/vehicle.gyp:*',
+ 'sso/sso.gyp:*',
],
}],
],