work on UI friends manager
This commit is contained in:
parent
bcb0af2e54
commit
4f39c5792a
@ -21,10 +21,12 @@ from gevent.pywsgi import WSGIServer, WSGIHandler
|
|||||||
from gevent import Timeout
|
from gevent import Timeout
|
||||||
import flask, cgi, uuid
|
import flask, cgi, uuid
|
||||||
from flask import request, Response, abort, send_from_directory
|
from flask import request, Response, abort, send_from_directory
|
||||||
import sys, random, threading, hmac, hashlib, base64, time, math, os, json, socket
|
import sys, random, threading, hmac, base64, time, os, json, socket
|
||||||
import core
|
import core
|
||||||
from onionrblockapi import Block
|
from onionrblockapi import Block
|
||||||
import onionrutils, onionrexceptions, onionrcrypto, blockimporter, onionrevents as events, logger, config, onionr
|
import onionrutils, onionrexceptions, onionrcrypto, blockimporter, onionrevents as events, logger, config
|
||||||
|
from httpapi import friendsapi
|
||||||
|
import onionr
|
||||||
|
|
||||||
class FDSafeHandler(WSGIHandler):
|
class FDSafeHandler(WSGIHandler):
|
||||||
'''Our WSGI handler. Doesn't do much non-default except timeouts'''
|
'''Our WSGI handler. Doesn't do much non-default except timeouts'''
|
||||||
@ -250,7 +252,7 @@ class API:
|
|||||||
'''
|
'''
|
||||||
# assert isinstance(onionrInst, onionr.Onionr)
|
# assert isinstance(onionrInst, onionr.Onionr)
|
||||||
# configure logger and stuff
|
# configure logger and stuff
|
||||||
onionr.Onionr.setupConfig('data/', self = self)
|
#onionr.Onionr.setupConfig('data/', self = self)
|
||||||
|
|
||||||
self.debug = debug
|
self.debug = debug
|
||||||
self._core = onionrInst.onionrCore
|
self._core = onionrInst.onionrCore
|
||||||
@ -262,7 +264,7 @@ class API:
|
|||||||
self.bindPort = bindPort
|
self.bindPort = bindPort
|
||||||
|
|
||||||
# Be extremely mindful of this. These are endpoints available without a password
|
# Be extremely mindful of this. These are endpoints available without a password
|
||||||
self.whitelistEndpoints = ('site', 'www', 'onionrhome', 'board', 'boardContent', 'sharedContent', 'mail', 'mailindex')
|
self.whitelistEndpoints = ('site', 'www', 'onionrhome', 'board', 'boardContent', 'sharedContent', 'mail', 'mailindex', 'friends', 'friendsindex')
|
||||||
|
|
||||||
self.clientToken = config.get('client.webpassword')
|
self.clientToken = config.get('client.webpassword')
|
||||||
self.timeBypassToken = base64.b16encode(os.urandom(32)).decode()
|
self.timeBypassToken = base64.b16encode(os.urandom(32)).decode()
|
||||||
@ -276,6 +278,7 @@ class API:
|
|||||||
self.pluginResponses = {} # Responses for plugin endpoints
|
self.pluginResponses = {} # Responses for plugin endpoints
|
||||||
self.queueResponse = {}
|
self.queueResponse = {}
|
||||||
onionrInst.setClientAPIInst(self)
|
onionrInst.setClientAPIInst(self)
|
||||||
|
app.register_blueprint(friendsapi.friends)
|
||||||
|
|
||||||
@app.before_request
|
@app.before_request
|
||||||
def validateRequest():
|
def validateRequest():
|
||||||
@ -315,6 +318,14 @@ class API:
|
|||||||
@app.route('/mail/', endpoint='mailindex')
|
@app.route('/mail/', endpoint='mailindex')
|
||||||
def loadMailIndex():
|
def loadMailIndex():
|
||||||
return send_from_directory('static-data/www/mail/', 'index.html')
|
return send_from_directory('static-data/www/mail/', 'index.html')
|
||||||
|
|
||||||
|
@app.route('/friends/<path:path>', endpoint='friends')
|
||||||
|
def loadContacts(path):
|
||||||
|
return send_from_directory('static-data/www/friends/', path)
|
||||||
|
|
||||||
|
@app.route('/friends/', endpoint='friendsindex')
|
||||||
|
def loadContacts():
|
||||||
|
return send_from_directory('static-data/www/friends/', 'index.html')
|
||||||
|
|
||||||
@app.route('/board/<path:path>', endpoint='boardContent')
|
@app.route('/board/<path:path>', endpoint='boardContent')
|
||||||
def boardContent(path):
|
def boardContent(path):
|
||||||
|
@ -171,7 +171,8 @@ class OnionrCommunicatorDaemon:
|
|||||||
# Validate new peers are good format and not already in queue
|
# Validate new peers are good format and not already in queue
|
||||||
invalid = []
|
invalid = []
|
||||||
for x in newPeers:
|
for x in newPeers:
|
||||||
if not self._core._utils.validateID(x) or x in self.newPeers:
|
x = x.strip()
|
||||||
|
if not self._core._utils.validateID(x) or x in self.newPeers or x == self._core.hsAddress:
|
||||||
invalid.append(x)
|
invalid.append(x)
|
||||||
for x in invalid:
|
for x in invalid:
|
||||||
newPeers.remove(x)
|
newPeers.remove(x)
|
||||||
@ -431,6 +432,8 @@ class OnionrCommunicatorDaemon:
|
|||||||
for address in peerList:
|
for address in peerList:
|
||||||
if not config.get('tor.v3onions') and len(address) == 62:
|
if not config.get('tor.v3onions') and len(address) == 62:
|
||||||
continue
|
continue
|
||||||
|
if address == self._core.hsAddress:
|
||||||
|
continue
|
||||||
if len(address) == 0 or address in tried or address in self.onlinePeers or address in self.cooldownPeer:
|
if len(address) == 0 or address in tried or address in self.onlinePeers or address in self.cooldownPeer:
|
||||||
continue
|
continue
|
||||||
if self.shutdown:
|
if self.shutdown:
|
||||||
|
@ -121,7 +121,6 @@ class Core:
|
|||||||
'''
|
'''
|
||||||
Hack to refresh some vars which may not be set on first start
|
Hack to refresh some vars which may not be set on first start
|
||||||
'''
|
'''
|
||||||
|
|
||||||
if os.path.exists(self.dataDir + '/hs/hostname'):
|
if os.path.exists(self.dataDir + '/hs/hostname'):
|
||||||
with open(self.dataDir + '/hs/hostname', 'r') as hs:
|
with open(self.dataDir + '/hs/hostname', 'r') as hs:
|
||||||
self.hsAddress = hs.read().strip()
|
self.hsAddress = hs.read().strip()
|
||||||
@ -597,10 +596,6 @@ class Core:
|
|||||||
conn = sqlite3.connect(self.blockDB, timeout=30)
|
conn = sqlite3.connect(self.blockDB, timeout=30)
|
||||||
c = conn.cursor()
|
c = conn.cursor()
|
||||||
|
|
||||||
# if unsaved:
|
|
||||||
# execute = 'SELECT hash FROM hashes WHERE dataSaved != 1 ORDER BY RANDOM();'
|
|
||||||
# else:
|
|
||||||
# execute = 'SELECT hash FROM hashes ORDER BY dateReceived ASC;'
|
|
||||||
execute = 'SELECT hash FROM hashes WHERE dateReceived >= ? ORDER BY dateReceived ASC;'
|
execute = 'SELECT hash FROM hashes WHERE dateReceived >= ? ORDER BY dateReceived ASC;'
|
||||||
args = (dateRec,)
|
args = (dateRec,)
|
||||||
rows = list()
|
rows = list()
|
||||||
|
48
onionr/httpapi/friendsapi/__init__.py
Normal file
48
onionr/httpapi/friendsapi/__init__.py
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
'''
|
||||||
|
Onionr - P2P Anonymous Storage Network
|
||||||
|
|
||||||
|
This file creates http endpoints for friend management
|
||||||
|
'''
|
||||||
|
'''
|
||||||
|
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 <https://www.gnu.org/licenses/>.
|
||||||
|
'''
|
||||||
|
import core
|
||||||
|
from onionrusers import contactmanager
|
||||||
|
from flask import Blueprint, Response, request, abort
|
||||||
|
|
||||||
|
friends = Blueprint('friends', __name__)
|
||||||
|
|
||||||
|
@friends.route('/friends/add/<pubkey>', methods=['POST'])
|
||||||
|
def add_friend(pubkey):
|
||||||
|
contactmanager.ContactManager(core.Core(), pubkey, saveUser=True).setTrust(1)
|
||||||
|
return 'success'
|
||||||
|
|
||||||
|
@friends.route('/friends/remove/<pubkey>', methods=['POST'])
|
||||||
|
def remove_friend(pubkey):
|
||||||
|
contactmanager.ContactManager(core.Core(), pubkey).setTrust(0)
|
||||||
|
return 'success'
|
||||||
|
|
||||||
|
@friends.route('/friends/setinfo/<pubkey>/<key>', methods=['POST'])
|
||||||
|
def set_info(pubkey, key):
|
||||||
|
data = request.form['data']
|
||||||
|
contactmanager.ContactManager(core.Core(), pubkey).set_info(key, data)
|
||||||
|
return 'success'
|
||||||
|
|
||||||
|
@friends.route('/friends/getinfo/<pubkey>/<key>')
|
||||||
|
def get_info(pubkey, key):
|
||||||
|
retData = contactmanager.ContactManager(core.Core(), pubkey).get_info(key)
|
||||||
|
if retData is None:
|
||||||
|
abort(404)
|
||||||
|
else:
|
||||||
|
return retData
|
@ -0,0 +1,5 @@
|
|||||||
|
{
|
||||||
|
"name" : "contactmanager",
|
||||||
|
"version" : "1.0",
|
||||||
|
"author" : "onionr"
|
||||||
|
}
|
39
onionr/static-data/default-plugins/contactmanager/main.py
Normal file
39
onionr/static-data/default-plugins/contactmanager/main.py
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
'''
|
||||||
|
Onionr - P2P Anonymous Storage Network
|
||||||
|
|
||||||
|
This is an interactive menu-driven CLI interface for Onionr
|
||||||
|
'''
|
||||||
|
'''
|
||||||
|
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 <https://www.gnu.org/licenses/>.
|
||||||
|
'''
|
||||||
|
|
||||||
|
plugin_name = 'contactmanager'
|
||||||
|
|
||||||
|
class OnionrContactManager:
|
||||||
|
def __init__(self, api):
|
||||||
|
return
|
||||||
|
|
||||||
|
def on_init(api, data = None):
|
||||||
|
'''
|
||||||
|
This event is called after Onionr is initialized, but before the command
|
||||||
|
inputted is executed. Could be called when daemon is starting or when
|
||||||
|
just the client is running.
|
||||||
|
'''
|
||||||
|
|
||||||
|
# Doing this makes it so that the other functions can access the api object
|
||||||
|
# by simply referencing the variable `pluginapi`.
|
||||||
|
pluginapi = api
|
||||||
|
ui = OnionrCLIUI(api)
|
||||||
|
#api.commands.register('interactive', ui.start)
|
||||||
|
return
|
21
onionr/static-data/www/friends/friends.js
Normal file
21
onionr/static-data/www/friends/friends.js
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
/*
|
||||||
|
Onionr - P2P Anonymous Storage Network
|
||||||
|
|
||||||
|
This file handles the UI for managing friends/contacts
|
||||||
|
|
||||||
|
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 <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
friendListDisplay = document.getElementById('friendList')
|
||||||
|
|
32
onionr/static-data/www/friends/index.html
Normal file
32
onionr/static-data/www/friends/index.html
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta charset='utf-8'>
|
||||||
|
<title>
|
||||||
|
Onionr
|
||||||
|
</title>
|
||||||
|
<link rel='stylesheet' href='/shared/style/modal.css'>
|
||||||
|
<link rel='stylesheet' href='/shared/main/style.css'>
|
||||||
|
<link rel='stylesheet' href='/friends/style.css'>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="shutdownNotice" class='overlay'>
|
||||||
|
<div>
|
||||||
|
<p>Your node will shutdown. Thank you for using Onionr.</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class='content'>
|
||||||
|
<img class='logo' src='/shared/onionr-icon.png' alt='onionr logo'>
|
||||||
|
<span class='logoText'>Onionr Web Control Panel</span>
|
||||||
|
<h2>Friend Manager</h2>
|
||||||
|
<form id='addFriend' action='/' method='POST'>
|
||||||
|
<label>Friend ID: <input type='text' name='addKey' placeholder='public key/ID' required></label>
|
||||||
|
<label>Set Alias: <input type='text' name='addAlias' placeholder='what to call them' required></label>
|
||||||
|
<input type='submit' value='Add Friend'>
|
||||||
|
</form>
|
||||||
|
<div id='friendList'></div>
|
||||||
|
</div>
|
||||||
|
<script src='/shared/misc.js'></script>
|
||||||
|
<script src='/friends/friends.js'></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
15
onionr/static-data/www/friends/style.css
Normal file
15
onionr/static-data/www/friends/style.css
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
h2, h3{
|
||||||
|
font-family: Arial, Helvetica, sans-serif;
|
||||||
|
}
|
||||||
|
|
||||||
|
form{
|
||||||
|
border: 1px solid black;
|
||||||
|
border-radius: 5px;
|
||||||
|
padding: 1em;
|
||||||
|
margin-right: 10%;
|
||||||
|
}
|
||||||
|
form label{
|
||||||
|
display: block;
|
||||||
|
margin-top: 0.5em;
|
||||||
|
margin-bottom: 0.5em;
|
||||||
|
}
|
@ -14,11 +14,12 @@
|
|||||||
<p>Your node will shutdown. Thank you for using Onionr.</p>
|
<p>Your node will shutdown. Thank you for using Onionr.</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<img class='logo' src='/shared/onionr-icon.png' alt='onionr logo'>
|
|
||||||
<span class='logoText'>Onionr Web Control Panel</span>
|
|
||||||
<div class='content'>
|
<div class='content'>
|
||||||
|
<img class='logo' src='/shared/onionr-icon.png' alt='onionr logo'>
|
||||||
|
<span class='logoText'>Onionr Web Control Panel</span>
|
||||||
|
<br><br>
|
||||||
<button id='shutdownNode'>Shutdown Node</button> <button id='refreshStats'>Refresh Stats</button>
|
<button id='shutdownNode'>Shutdown Node</button> <button id='refreshStats'>Refresh Stats</button>
|
||||||
<br><br><a class='idLink' href='/mail/'>Mail</a>
|
<br><br><a class='idLink' href='/mail/'>Mail</a> - <a class='idLink' href='/friends/'>Friend Manager</a>
|
||||||
<h2>Stats</h2>
|
<h2>Stats</h2>
|
||||||
<p>Uptime: <span id='uptime'></span></p>
|
<p>Uptime: <span id='uptime'></span></p>
|
||||||
<p>Last Received Connection: <span id='lastIncoming'>Unknown</span></p>
|
<p>Last Received Connection: <span id='lastIncoming'>Unknown</span></p>
|
||||||
|
@ -13,7 +13,6 @@ c = core.Core()
|
|||||||
|
|
||||||
class OnionrBlockTests(unittest.TestCase):
|
class OnionrBlockTests(unittest.TestCase):
|
||||||
def test_plaintext_insert(self):
|
def test_plaintext_insert(self):
|
||||||
return
|
|
||||||
message = 'hello world'
|
message = 'hello world'
|
||||||
c.insertBlock(message)
|
c.insertBlock(message)
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user