Open Media Library
This commit is contained in:
commit
2ee2bc178a
228 changed files with 85988 additions and 0 deletions
0
oml/node/__init__.py
Normal file
0
oml/node/__init__.py
Normal file
87
oml/node/api.py
Normal file
87
oml/node/api.py
Normal file
|
|
@ -0,0 +1,87 @@
|
|||
import settings
|
||||
from changelog import Changelog
|
||||
from user.models import User
|
||||
|
||||
import state
|
||||
from websocket import trigger_event
|
||||
|
||||
def api_pullChanges(app, remote_id, user_id=None, from_=None, to=None):
|
||||
if user_id and not from_ and not to:
|
||||
from_ = user_id
|
||||
user_id = None
|
||||
if user_id and from_ and not to:
|
||||
if isinstance(user_id, int):
|
||||
to = from_
|
||||
from_ = user_id
|
||||
user_id = None
|
||||
from_ = from_ or 0
|
||||
if user_id:
|
||||
return []
|
||||
if not user_id:
|
||||
user_id = settings.USER_ID
|
||||
qs = Changelog.query.filter_by(user_id=user_id)
|
||||
if from_:
|
||||
qs = qs.filter(Changelog.revision>=from_)
|
||||
if to:
|
||||
qs = qs.filter(Changelog.revision<to)
|
||||
state.nodes.queue('add', remote_id)
|
||||
return [c.json() for c in qs]
|
||||
|
||||
def api_pushChanges(app, user_id, changes):
|
||||
user = User.get(user_id)
|
||||
for change in changes:
|
||||
if not Changelog.apply_change(user, change):
|
||||
print 'FAILED TO APPLY CHANGE', change
|
||||
state.nodes.queue(user_id, 'pullChanges')
|
||||
return False
|
||||
return True
|
||||
|
||||
def api_requestPeering(app, user_id, username, message):
|
||||
user = User.get_or_create(user_id)
|
||||
if not user.info:
|
||||
user.info = {}
|
||||
if not user.peered:
|
||||
if user.pending == 'sent':
|
||||
user.info['message'] = message
|
||||
user.update_peering(True, username)
|
||||
else:
|
||||
user.pending = 'received'
|
||||
user.info['username'] = username
|
||||
user.info['message'] = message
|
||||
user.save()
|
||||
trigger_event('peering', user.json())
|
||||
return True
|
||||
return False
|
||||
|
||||
def api_acceptPeering(app, user_id, username, message):
|
||||
user = User.get(user_id)
|
||||
if user and user.pending == 'sent':
|
||||
if not user.info:
|
||||
user.info = {}
|
||||
user.info['username'] = username
|
||||
user.info['message'] = message
|
||||
user.update_peering(True, username)
|
||||
trigger_event('peering', user.json())
|
||||
return True
|
||||
return False
|
||||
|
||||
def api_rejectPeering(app, user_id, message):
|
||||
user = User.get(user_id)
|
||||
if user:
|
||||
if not user.info:
|
||||
user.info = {}
|
||||
user.info['message'] = message
|
||||
user.update_peering(False)
|
||||
trigger_event('peering', user.json())
|
||||
return True
|
||||
return False
|
||||
|
||||
def api_removePeering(app, user_id, message):
|
||||
user = User.get(user_id)
|
||||
if user:
|
||||
user.peered = False
|
||||
user.info['message'] = message
|
||||
user.save()
|
||||
trigger_event('peering', {'id': user.id, 'peered': user.peered})
|
||||
return True
|
||||
return False
|
||||
25
oml/node/gencert.py
Normal file
25
oml/node/gencert.py
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
import OpenSSL
|
||||
|
||||
key = OpenSSL.crypto.PKey()
|
||||
key.generate_key(OpenSSL.crypto.TYPE_RSA, 2048)
|
||||
|
||||
ca = OpenSSL.crypto.X509()
|
||||
ca.set_version(2)
|
||||
ca.set_serial_number(1)
|
||||
ca.get_subject().CN = "put_ed25519_key_here"
|
||||
ca.gmtime_adj_notBefore(0)
|
||||
ca.gmtime_adj_notAfter(24 * 60 * 60)
|
||||
ca.set_issuer(ca.get_subject())
|
||||
ca.set_pubkey(key)
|
||||
ca.add_extensions([
|
||||
OpenSSL.crypto.X509Extension("basicConstraints", True,
|
||||
"CA:TRUE, pathlen:0"),
|
||||
OpenSSL.crypto.X509Extension("keyUsage", True,
|
||||
"keyCertSign, cRLSign"),
|
||||
OpenSSL.crypto.X509Extension("subjectKeyIdentifier", False, "hash",
|
||||
subject=ca),
|
||||
OpenSSL.crypto.X509Extension("authorityKeyIdentifier", False, "keyid:always",issuer=ca)
|
||||
])
|
||||
ca.sign(key, "sha1")
|
||||
open("MyCertificate.crt.bin", "wb").write(OpenSSL.crypto.dump_certificate(OpenSSL.crypto.FILETYPE_ASN1, ca))
|
||||
|
||||
119
oml/node/server.py
Normal file
119
oml/node/server.py
Normal file
|
|
@ -0,0 +1,119 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# vi:si:et:sw=4:sts=4:ts=4
|
||||
|
||||
import os
|
||||
import sys
|
||||
import tornado
|
||||
from tornado.web import StaticFileHandler, Application, FallbackHandler
|
||||
from tornado.wsgi import WSGIContainer
|
||||
from tornado.httpserver import HTTPServer
|
||||
from tornado.ioloop import IOLoop, PeriodicCallback
|
||||
|
||||
import settings
|
||||
|
||||
import directory
|
||||
import utils
|
||||
import state
|
||||
import user
|
||||
|
||||
import json
|
||||
from ed25519_utils import valid
|
||||
import api
|
||||
|
||||
class NodeHandler(tornado.web.RequestHandler):
|
||||
|
||||
def initialize(self, app):
|
||||
self.app = app
|
||||
|
||||
|
||||
def post(self):
|
||||
request = self.request
|
||||
if request.method == 'POST':
|
||||
'''
|
||||
API
|
||||
pullChanges [userid] from [to]
|
||||
pushChanges [index, change]
|
||||
requestPeering username message
|
||||
acceptPeering username message
|
||||
rejectPeering message
|
||||
removePeering message
|
||||
|
||||
ping responds public ip
|
||||
'''
|
||||
key = str(request.headers['X-Ed25519-Key'])
|
||||
sig = str(request.headers['X-Ed25519-Signature'])
|
||||
data = request.body
|
||||
content = {}
|
||||
if valid(key, data, sig):
|
||||
action, args = json.loads(data)
|
||||
print 'action', action, args
|
||||
if action == 'ping':
|
||||
content = {
|
||||
'ip': request.remote_addr
|
||||
}
|
||||
else:
|
||||
with self.app.app_context():
|
||||
if action in (
|
||||
'requestPeering', 'acceptPeering', 'rejectPeering', 'removePeering'
|
||||
) or user.models.User.get(key):
|
||||
content = getattr(api, 'api_' + action)(self.app, key, *args)
|
||||
else:
|
||||
print 'PEER', key, 'IS UNKNOWN SEND 403'
|
||||
self.set_status(403)
|
||||
content = {
|
||||
'status': 'not peered'
|
||||
}
|
||||
content = json.dumps(content)
|
||||
sig = settings.sk.sign(content, encoding='base64')
|
||||
self.set_header('X-Ed25519-Signature', sig)
|
||||
self.write(content)
|
||||
self.finish()
|
||||
|
||||
def get(self):
|
||||
self.write('Open Media Library')
|
||||
self.finish()
|
||||
|
||||
class ShareHandler(tornado.web.RequestHandler):
|
||||
|
||||
def initialize(self, app):
|
||||
self.app = app
|
||||
|
||||
def get(self, id):
|
||||
with self.app.app_context():
|
||||
import item.models
|
||||
i = item.models.Item.get(id)
|
||||
if not i:
|
||||
self.set_status(404)
|
||||
self.finish()
|
||||
path = i.get_path()
|
||||
mimetype = {
|
||||
'epub': 'application/epub+zip',
|
||||
'pdf': 'application/pdf',
|
||||
'txt': 'text/plain',
|
||||
}.get(path.split('.')[-1], None)
|
||||
self.set_header('Content-Type', mimetype)
|
||||
print 'GET file', id
|
||||
with open(path, 'rb') as f:
|
||||
while 1:
|
||||
data = f.read(16384)
|
||||
if not data:
|
||||
break
|
||||
self.write(data)
|
||||
self.finish()
|
||||
|
||||
|
||||
def start(app):
|
||||
http_server = tornado.web.Application([
|
||||
(r"/get/(.*)", ShareHandler, dict(app=app)),
|
||||
(r".*", NodeHandler, dict(app=app)),
|
||||
])
|
||||
|
||||
#tr = WSGIContainer(node_app)
|
||||
#http_server= HTTPServer(tr)
|
||||
http_server.listen(settings.server['node_port'], settings.server['node_address'])
|
||||
host = utils.get_public_ipv4()
|
||||
state.online = directory.put(settings.sk, {
|
||||
'host': host,
|
||||
'port': settings.server['node_port']
|
||||
})
|
||||
return http_server
|
||||
19
oml/node/utils.py
Normal file
19
oml/node/utils.py
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
import socket
|
||||
import requests
|
||||
from urlparse import urlparse
|
||||
|
||||
def get_public_ipv6():
|
||||
host = ('2a01:4f8:120:3201::3', 25519)
|
||||
s = socket.socket(socket.AF_INET6, socket.SOCK_DGRAM)
|
||||
s.connect(host)
|
||||
ip = s.getsockname()[0]
|
||||
s.close()
|
||||
return ip
|
||||
|
||||
def get_public_ipv4():
|
||||
host = ('10.0.3.1', 25519)
|
||||
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
|
||||
s.connect(host)
|
||||
ip = s.getsockname()[0]
|
||||
s.close()
|
||||
return ip
|
||||
Loading…
Add table
Add a link
Reference in a new issue