diff options
author | Ruben Pollan <meskio@sindominio.net> | 2016-08-04 19:04:09 +0200 |
---|---|---|
committer | Kali Kaneko (leap communications) <kali@leap.se> | 2016-09-01 01:41:16 -0400 |
commit | 50a258d45e851a865801da9d888037b5869a3489 (patch) | |
tree | 39a797a6ffa7b0d90037ce0497621c96e90dcb2f /src/leap/bitmask/core/web | |
parent | 720ac7cab46f57971c71d2d2aec8235a47a53582 (diff) |
[feat] add web/js core API
Implements http REST API for the core and bitmask.js generic library to
use this API. For events it uses long polling.
- Resolves: #8265
Diffstat (limited to 'src/leap/bitmask/core/web')
-rw-r--r-- | src/leap/bitmask/core/web/bitmask.js | 257 | ||||
-rw-r--r-- | src/leap/bitmask/core/web/index.html | 73 | ||||
-rw-r--r-- | src/leap/bitmask/core/web/root.py | 0 |
3 files changed, 290 insertions, 40 deletions
diff --git a/src/leap/bitmask/core/web/bitmask.js b/src/leap/bitmask/core/web/bitmask.js new file mode 100644 index 0000000..39e677f --- /dev/null +++ b/src/leap/bitmask/core/web/bitmask.js @@ -0,0 +1,257 @@ +// bitmask.js +// Copyright (C) 2016 LEAP +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. + +/** + * bitmask object + * + * Contains all the bitmask API mapped by sections + * - user. User management like login, creation, ... + * - mail. Email service control. + * - keys. Keyring operations. + * - events. For registering to events. + * + * Every function returns a Promise that will be triggered once the request is + * finished or will fail if there was any error. Errors are always user readable + * strings. + */ +var bitmask = function(){ + var event_handlers = {}; + + function call(command) { + var url = '/API/' + command.slice(0, 2).join('/'); + var data = JSON.stringify(command.slice(2)); + + return new Promise(function(resolve, reject) { + var req = new XMLHttpRequest(); + req.open('POST', url); + + req.onload = function() { + if (req.status == 200) { + parseResponse(req.response, resolve, reject); + } + else { + reject(Error(req.statusText)); + } + }; + + req.onerror = function() { + reject(Error("Network Error")); + }; + + req.send(data); + }); + }; + + function parseResponse(raw_response, resolve, reject) { + var response = JSON.parse(raw_response); + if (response.error === null) { + resolve(response.result); + } else { + reject(response.error); + } + }; + + function event_polling() { + call(['events', 'poll']).then(function(response) { + if (response !== null) { + evnt = response[0]; + content = response[1]; + if (evnt in event_handlers) { + event_handlers[evnt](evnt, content); + } + } + event_polling(); + }, function(error) { + setTimeout(event_polling, 5000); + }); + }; + event_polling(); + + function private_str(priv) { + if (priv) { + return 'private' + } + return 'public' + }; + + return { + /** + * uids are of the form user@provider.net + */ + user: { + /** + * Check wich user is active + * + * @return {Promise<string>} The uid of the active user + */ + active: function() { + return call(['user', 'active']); + }, + + /** + * Register a new user + * + * @param {string} uid The uid to be created + * @param {string} password The user password + */ + create: function(uid, password) { + return call(['user', 'create', uid, password]); + }, + + /** + * Login + * + * @param {string} uid The uid to log in + * @param {string} password The user password + */ + auth: function(uid, password) { + return call(['user', 'authenticate', uid, password]); + }, + + /** + * Logout + * + * @param {string} uid The uid to log out. + * If no uid is provided the active user will be used + */ + logout: function(uid) { + if (typeof uid !== 'string') { + uid = ""; + } + return call(['user', 'logout', uid]); + } + }, + + mail: { + /** + * Check the status of the email service + * + * @return {Promise<string>} User readable status + */ + status: function() { + return call(['mail', 'status']); + }, + + /** + * Get the token of the active user. + * + * This token is used as password to authenticate in the IMAP and SMTP services. + * + * @return {Promise<string>} The token + */ + get_token: function() { + return call(['mail', 'get-token']); + } + }, + + /** + * A KeyObject have the following attributes: + * - address {string} the email address for wich this key is active + * - fingerprint {string} the fingerprint of the key + * - length {number} the size of the key bits + * - private {bool} if the key is private + * - uids {[string]} the uids in the key + * - key_data {string} the key content + * - validation {string} the validation level which this key was found + * - expiry_date {string} date when the key expires + * - refreshed_at {string} date of the last refresh of the key + * - audited_at {string} date of the last audit (unused for now) + * - sign_used {bool} if has being used to checking signatures + * - enc_used {bool} if has being used to encrypt + */ + keys: { + /** + * List all the keys in the keyring + * + * @param {boolean} priv Should list private keys? + * If it's not provided the public ones will be listed. + * + * @return {Promise<[KeyObject]>} List of keys in the keyring + */ + list: function(priv) { + return call(['keys', 'list', private_str(priv)]); + }, + + /** + * Export key + * + * @param {string} address The email address of the key + * @param {boolean} priv Should get the private key? + * If it's not provided the public one will be fetched. + * + * @return {Promise<KeyObject>} The key + */ + exprt: function(address, priv) { + return call(['keys', 'export', address, private_str(priv)]); + }, + + /** + * Insert key + * + * @param {string} address The email address of the key + * @param {string} rawkey The key material + * @param {string} validation The validation level of the key + * If it's not provided 'Fingerprint' level will be used. + * + * @return {Promise<KeyObject>} The key + */ + insert: function(address, rawkey, validation) { + if (typeof validation !== 'string') { + validation = 'Fingerprint'; + } + return call(['keys', 'insert', address, validation, rawkey]); + }, + + /** + * Delete a key + * + * @param {string} address The email address of the key + * @param {boolean} priv Should get the private key? + * If it's not provided the public one will be deleted. + * + * @return {Promise<KeyObject>} The key + */ + del: function(address, priv) { + return call(['keys', 'delete', address, private_str(priv)]); + } + }, + + events: { + /** + * Register func for an event + * + * @param {string} evnt The event to register + * @param {function} func The function that will be called on each event. + * It has to be like: function(event, content) {} + * Where content will be a list of strings. + */ + register: function(evnt, func) { + event_handlers[evnt] = func; + return call(['events', 'register', evnt]) + }, + + /** + * Unregister from an event + * + * @param {string} evnt The event to unregister + */ + unregister: function(evnt) { + delete event_handlers[evnt]; + return call(['events', 'unregister', evnt]) + } + } + }; +}(); diff --git a/src/leap/bitmask/core/web/index.html b/src/leap/bitmask/core/web/index.html index 9490eca..6ac9b29 100644 --- a/src/leap/bitmask/core/web/index.html +++ b/src/leap/bitmask/core/web/index.html @@ -2,53 +2,44 @@ <html> <head> <title>Bitmask WebSockets Endpoint</title> + <script src="bitmask.js"></script> <script type="text/javascript"> - var sock = null; var ellog = null; window.onload = function() { - ellog = document.getElementById('log'); - var wsuri; - if (window.location.protocol === "file:") { - wsuri = "ws://127.0.0.1:8080/ws"; - } else { - wsuri = "ws://" + window.location.hostname + ":8080/bitmask"; - } - - if ("WebSocket" in window) { - sock = new WebSocket(wsuri); - } else if ("MozWebSocket" in window) { - sock = new MozWebSocket(wsuri); - } else { - log("Browser does not support WebSocket!"); - window.location = "http://autobahn.ws/unsupportedbrowser"; - } - - if (sock) { - sock.onopen = function() { - log("Connected to " + wsuri); - } - - sock.onclose = function(e) { - log("Connection closed (wasClean = " + e.wasClean + ", code = " + e.code + ", reason = '" + e.reason + "')"); - sock = null; - } + bitmask.events.register("KEYMANAGER_KEY_FOUND", event_handler); + }; - sock.onmessage = function(e) { - log("[res] " + e.data + '\n'); - } - } + function login() { + var email = document.getElementById('email').value; + var password = document.getElementById('password').value; + bitmask.user.auth(email, password).then(function(response) { + log("We are logged in: "); + for (k in response) { + log(" " + k + ": " + response[k]); + } + }, function(error) { + log("Some error ocurred: " + error); + }); }; - function send() { - var msg = document.getElementById('message').value; - if (sock) { - sock.send(msg); - log("[cmd] " + msg); - } else { - log("Not connected."); + function logout() { + bitmask.user.logout().then(function(response) { + log("We are logged out: "); + for (k in response) { + log(" " + k + ": " + response[k]); + } + }, function(error) { + log("Some error ocurred: " + error); + }); + }; + + function event_handler(evnt, content) { + log("Event: " + evnt); + for (i in content) { + log(" " + content[i]); } }; @@ -62,9 +53,11 @@ <h1>Bitmask Control Panel</h1> <noscript>You must enable JavaScript</noscript> <form> - <p>Command: <input id="message" type="text" size="50" maxlength="50" value="status"></p> + <p>Email address: <input id="email" type="text" size="50" maxlength="50" value="user@mail.bitmask.net"></p> + <p>Password: <input id="password" type="password" size="50" maxlength="50" ></p> </form> - <button onclick='send();'>Send Command</button> + <button onclick='login();'>Log In</button> + <button onclick='logout();'>Log Out</button> <pre id="log" style="height: 20em; overflow-y: scroll; background-color: #faa;"></pre> </body> </html> diff --git a/src/leap/bitmask/core/web/root.py b/src/leap/bitmask/core/web/root.py deleted file mode 100644 index e69de29..0000000 --- a/src/leap/bitmask/core/web/root.py +++ /dev/null |