def __new__(cls, id=None, doc=None, spec=None, fields=None, upsert=False, **kwargs): from pritunl import utils fields = fields or cls.fields mongo_object = object.__new__(cls) mongo_object.changed = set() mongo_object.unseted = set() mongo_object.id = id mongo_object.loaded_fields = fields if id or doc or spec: mongo_object.exists = True try: mongo_object.load(doc=doc, spec=spec, fields=fields) except NotFound: if not upsert: return None mongo_object.exists = False if not id: mongo_object.id = database.ObjectId() else: mongo_object.exists = False mongo_object.id = database.ObjectId() return mongo_object
def publish(channels, message, extra=None, transaction=None): if cache.has_cache: return cache.publish(channels, message, extra=extra) collection = mongo.get_collection('messages') doc = { 'message': message, 'timestamp': utils.now(), } if extra: for key, val in list(extra.items()): doc[key] = val # ObjectId must be set by server and ObjectId order must match $natural # order. Docs sent in order on client are not guaranteed to match $natural # order on server. Nonce is added to force an insert from upsert where # insert is not supported. # When using inserts manipulate=False must be set to prevent pymongo # from setting ObjectId locally. if transaction: tran_collection = transaction.collection(collection.name_str) if isinstance(channels, str): doc['channel'] = channels tran_collection.update({ 'nonce': database.ObjectId(), }, { '$set': doc, }, upsert=True) else: for channel in channels: doc_copy = doc.copy() doc_copy['channel'] = channel tran_collection.bulk().find({ 'nonce': database.ObjectId(), }).upsert().update({ '$set': doc_copy, }) tran_collection.bulk_execute() else: if isinstance(channels, str): doc['channel'] = channels collection.insert(doc, manipulate=False) else: docs = [] for channel in channels: doc_copy = doc.copy() doc_copy['channel'] = channel docs.append(doc_copy) collection.insert(docs, manipulate=False)
def link_state_delete(): if settings.app.demo_mode: return utils.demo_blocked() auth_token = flask.request.headers.get('Auth-Token', None) auth_timestamp = flask.request.headers.get('Auth-Timestamp', None) auth_nonce = flask.request.headers.get('Auth-Nonce', None) auth_signature = flask.request.headers.get('Auth-Signature', None) if not auth_token or not auth_timestamp or not auth_nonce or \ not auth_signature: return flask.abort(406) auth_token = auth_token[:256] auth_timestamp = auth_timestamp[:64] auth_nonce = auth_nonce[:32] auth_signature = auth_signature[:512] try: if abs(int(auth_timestamp) - int(utils.time_now())) > \ settings.app.auth_time_window: return flask.abort(408) except ValueError: return flask.abort(405) host = link.get_host(database.ObjectId(auth_token)) if not host: return flask.abort(404) auth_string = '&'.join([ auth_token, auth_timestamp, auth_nonce, flask.request.method, flask.request.path, ]) if len(auth_string) > AUTH_SIG_STRING_MAX_LEN: return flask.abort(413) auth_test_signature = base64.b64encode( hmac.new(host.secret.encode(), auth_string.encode(), hashlib.sha512).digest()).decode() if not utils.const_compare(auth_signature, auth_test_signature): return flask.abort(401) nonces_collection = mongo.get_collection('auth_nonces') try: nonces_collection.insert({ 'token': auth_token, 'nonce': auth_nonce, 'timestamp': utils.now(), }) except pymongo.errors.DuplicateKeyError: return flask.abort(409) host.set_inactive() return utils.jsonify({})
def json_object_hook_handler(obj): obj_data = obj.get('$obj') if obj_data: object_type, obj_data = obj_data if object_type == 'oid': return database.ObjectId(obj_data) elif object_type == 'date': return datetime.datetime.fromtimestamp(obj_data / 1000., bson.tz_util.utc) return obj
def __init__(self, priority=None, retry=None, **kwargs): mongo.MongoObject.__init__(self) self.ttl = settings.mongo.queue_ttl self.type = self.type self.reserve_id = self.reserve_id self.runner_id = database.ObjectId() self.claimed = False self.queue_com = QueueCom() self.keep_alive_thread = None if priority is not None: self.priority = priority if retry is not None: self.retry = retry
def __init__(self, lock_id=None, priority=None, ttl=None, **kwargs): mongo.MongoObject.__init__(self) self.ttl = settings.mongo.tran_ttl if lock_id is not None: self.lock_id = lock_id if self.lock_id is None: self.lock_id = database.ObjectId() if priority is not None: self.priority = priority if ttl is not None: self.ttl = ttl if self.actions: actions_json = zlib.decompress(self.actions) self.action_sets = json.loads( actions_json, object_hook=utils.json_object_hook_handler) else: self.action_sets = []
def publish(channels, message, extra=None, cap=50, ttl=300): if isinstance(channels, str): channels = [channels] for channel in channels: doc = { '_id': database.ObjectId(), 'message': message, 'timestamp': utils.now(), } if extra: for key, val in list(extra.items()): doc[key] = val doc = json.dumps(doc, default=utils.json_default) pipe = _client.pipeline() pipe.lpush(channel, doc) pipe.ltrim(channel, 0, cap) if ttl: pipe.expire(channel, ttl) pipe.publish(channel, doc) pipe.execute()
def link_state_put(): if settings.app.demo_mode: return utils.demo_blocked() auth_token = flask.request.headers.get('Auth-Token', None) auth_timestamp = flask.request.headers.get('Auth-Timestamp', None) auth_nonce = flask.request.headers.get('Auth-Nonce', None) auth_signature = flask.request.headers.get('Auth-Signature', None) if not auth_token or not auth_timestamp or not auth_nonce or \ not auth_signature: return flask.abort(406) auth_token = auth_token[:256] auth_timestamp = auth_timestamp[:64] auth_nonce = auth_nonce[:32] auth_signature = auth_signature[:512] try: if abs(int(auth_timestamp) - int(utils.time_now())) > \ settings.app.auth_time_window: return flask.abort(408) except ValueError: return flask.abort(405) host = link.get_host(database.ObjectId(auth_token)) if not host: return flask.abort(404) auth_string = '&'.join([ auth_token, auth_timestamp, auth_nonce, flask.request.method, flask.request.path, ]) if len(auth_string) > AUTH_SIG_STRING_MAX_LEN: return flask.abort(413) auth_test_signature = base64.b64encode( hmac.new(host.secret.encode(), auth_string.encode(), hashlib.sha512).digest()).decode() if not utils.const_compare(auth_signature, auth_test_signature): return flask.abort(401) nonces_collection = mongo.get_collection('auth_nonces') try: nonces_collection.insert({ 'token': auth_token, 'nonce': auth_nonce, 'timestamp': utils.now(), }) except pymongo.errors.DuplicateKeyError: return flask.abort(409) host.load_link() host.version = flask.request.json.get('version') host.public_address = flask.request.json.get('public_address') host.local_address = flask.request.json.get('local_address') host.address6 = flask.request.json.get('address6') if flask.request.json.get('hosts'): host.hosts = flask.request.json.get('hosts') if host.hosts_hist: host.hosts_hist.insert(0, flask.request.json.get('hosts')) host.hosts_hist = host.hosts_hist[:6] else: host.hosts_hist = [flask.request.json.get('hosts')] else: host.hosts = None host.hosts_hist = None state, active = host.get_state() if active: host.location.status = flask.request.json.get('status') or None host.location.commit('status') data = json.dumps(state, default=lambda x: str(x)) data += (16 - len(data) % 16) * '\x00' iv = os.urandom(16) key = hashlib.sha256(host.secret.encode()).digest() cipher = Cipher(algorithms.AES(key), modes.CBC(iv), backend=default_backend()).encryptor() enc_data = base64.b64encode( cipher.update(data.encode()) + cipher.finalize()) enc_signature = base64.b64encode( hmac.new(host.secret.encode(), enc_data, hashlib.sha512).digest()).decode() resp = flask.Response(response=enc_data, mimetype='application/base64') resp.headers.add('Cache-Control', 'no-cache, no-store, must-revalidate') resp.headers.add('Pragma', 'no-cache') resp.headers.add('Expires', 0) resp.headers.add('Cipher-IV', base64.b64encode(iv)) resp.headers.add('Cipher-Signature', enc_signature) return resp
def json_opt_oid(key): val = flask.request.json.get(key) return None if val is None else database.ObjectId(val)
def json_oid(key): return database.ObjectId(flask.request.json[key])
def __init__(self, run_id=None, **kwargs): mongo.MongoObject.__init__(self) self.type = self.type self.runner_id = database.ObjectId()