def sms(main_number): phone_num = main_number module = Atom('Auth') client_id = [] # client_id = [] :: [] | binary(), dev_key = phone_num # dev_key = [] :: [] | binary(), user_id = [] # user_id = [] :: [] | binary(), phone = phone_num # phone = [] :: [] | binary(), token = [] # token = [] :: [] | binary(), sms_code = '903182' # type = [] :: [] | atom(), type_r = Atom('verify') # sms_code = [] :: [] | binary(), attempts = [] # attempts = [] :: [] | integer(), services = [] # services = [] :: list(atom()), settings = [('Feature', "id_DEFAULT_LANGUAGE", "DEFAULT_LANGUAGE", "English:en", "LANGUAGE_SETTING")] push = [] # push = [] :: [] | binary(), os = [] # os = [] :: [] | atom() | ios | android | web, created = [] # created = [] :: [] | integer() | binary(), last_online = [] # last_online = [] :: [] | integer()}) request_f = (module, client_id, dev_key, user_id, phone, token, type_r, sms_code, attempts, services, settings, push, os, created, last_online) request = bert.encode(request_f) # log.info('='*5 + 'REQUEST' + '='*5 + '\r\n'+ str(request_f)+'\r\n') log.debug("Send sms verify") return request
def login(main_number): phone_num = main_number feature = Atom('Feature') module = Atom('Auth') client_id = "reg_" + phone_num # client_id = [] :: [] | binary(), dev_key = phone_num # dev_key = [] :: [] | binary(), user_id = [] # user_id = [] :: [] | binary(), phone = phone_num # phone = [] :: [] | binary(), token = [] # token = [] :: [] | binary(), sms_code = [] # type = [] :: [] | atom(), type_r = Atom('reg') # sms_code = [] :: [] | binary(), attempts = [] # attempts = [] :: [] | integer(), services = [] # services = [] :: list(atom()), # settings = [] :: [] | list(#'Feature'{}), settings = [(feature, phone_num + "__152775413346297", "AppVersion", "0.2.95", "AUTH_DATA"), (feature, phone_num + "__152775413346297", "OS", "iOS 11.3", "AUTH_DATA"), (feature, phone_num + "__152775413346297", "DeviceModel", "simulator/sandbox", "AUTH_DATA")] push = [] # push = [] :: [] | binary(), os = [] # os = [] :: [] | atom() | ios | android | web, created = [] # created = [] :: [] | integer() | binary(), last_online = [] # last_online = [] :: [] | integer()}) request_f = (module, client_id, dev_key, user_id, phone, token, type_r, sms_code, attempts, services, settings, push, os, created, last_online) request = bert.encode(request_f) # log.info('='*5 + 'REQUEST' + '='*5 + '\r\n' + str(request_f)+'\r\n') log.debug("Send Auth/check") return request
def delete_user(phone_number): Profile = Atom('Profile') remove = Atom('remove') user_delete_f = (Profile, phone_number, [], [], [], [], [], [], remove) print('=' * 5 + 'REQUEST' + '=' * 5 + '\r\n' + str(user_delete_f) + '\r\n') user_delete = bert.encode(user_delete_f) return user_delete
def patch_group(room_id, room_name): module = Atom('Room') room_id = room_id # id = [] :: [] | binary(), name = room_name # name = [] :: [] | binary(), links = [] description = [] # description = [] :: [] | binary(), settings = [] # settings = [] :: list(), members = [] # members = [] :: list(#'Member'{}), admins = [] # admins = [] :: list(#'Member'{}), data = [] # data = [] :: [] | list(#'Desc'{}), room_type = [] # type = [] :: [] | atom() | group | channel, tos = [] # tos = [] :: [] | binary(), tos_update = [] # tos_update = 0 :: [] | integer(), unread = [] # unread = 0 :: [] | integer(), mentions = [] # mentions = [] :: [] | list(integer()), readers = [] # readers = [] :: list(integer()), last_msg = [] # last_msg = [] :: [] | #'Message'{}, update = [] # update = 0 :: [] | integer(), created = [] # created = 0 :: [] | integer(), room_status = Atom('patch') # status = [] :: [] | create | leave| add | remove | patch | get | delete | last_msg}). request_f = (module,room_id,name,links,description,settings,members,admins,data,room_type, tos,tos_update,unread,mentions,readers,last_msg,update,created,room_status) request = bert.encode(request_f) # log.info('='*5 + 'REQUEST' + '='*5 + '\r\n'+ str(request_f)+'\r\n') log.debug("Send group creation request") return request
def parser(client, payload, main_number): data = bert.decode(bytes(payload)) if data[0] == Atom("Profile"): contacts = data[3][0][6] for field in contacts: if field[0] == Atom('Contact') and field[1].split( b'_')[0] == string_to_bytes(main_number): log.debug('Main profile found') global user_id user_id = field[1] print(user_id) for field in data: if field and list == type(field): for room in field[0]: if room and list == type(room) and room[0][0] == Atom( 'Room'): global room_id room_id = room[-1][1] print(room_id) client.publish(topic="events/1//api/anon//", payload=bytearray(history_group(user_id, room_id)), qos=2, retain=False) if data[0] == Atom('Message') and data[-1] == Atom('clear'): log.debug("Verify history removed") for field in data: if field and list == type(field) and tuple == type(field[0]): Verify.equals(b'History was removed', field[0][3], 'No history removed') client.disconnect()
def get_profile(): module = Atom('Profile') phone_id = '12566018988' settings = [] status = Atom('get') request_f = (module,phone_id,settings,settings,settings,settings,settings,settings,status) request = bert.encode(request_f) print('='*5 + 'REQUEST' + '='*5 + '\r\n'+ str(request_f)+'\r\n') return request
def on_message(self, client, userdata, msg): log.info('='*5 + 'RESPONSE' + '='*5 + '\r\n'+ str(bert.decode(bytes(msg.payload))) + '\r\n') for node in (bert.decode(bytes(msg.payload))): if node == (Atom('ok'), Atom('sms_sent')): client.publish(topic="events/1//api/anon//", payload=bytearray(sms(self.my_number)), qos=2, retain=False) if re.findall(r"\(Atom\('ok2'\), Atom\('login'\)", str(node)): self.clien = str(node[2][0].decode("utf-8")) self.pswd = str(node[2][1].decode("utf-8")) log.info('Got client {} and password {}'.format(self.clien, self.pswd)) client.disconnect()
def ban_user(): module = Atom('Friend') phone_id = '8613777322455_544' # phone_id = [] :: [] | binary(), friend_id = '380998681837_437' # friend_id = [] :: [] | binary(), settings = [] # settings = [] :: list(#'Feature'{}), status = Atom('ban') # status = [] :: [] | ban | unban # | request | confirm | update request_f = (module, phone_id, friend_id, settings, status) request = bert.encode(request_f) print('=' * 5 + 'REQUEST' + '=' * 5 + '\r\n' + str(request_f) + '\r\n') return request
def ignore_request(): module = Atom('Friend') phone_id = '12566018988_727' # phone_id = [] :: [] | binary(), friend_id = '51997259024_549' # friend_id = [] :: [] | binary(), settings = [] # settings = [] :: list(#'Feature'{}), status = Atom('ignore') # status = [] :: [] | ban | unban # | request | confirm | update request_f = (module,phone_id,friend_id,settings,status) request = bert.encode(request_f) print('='*5 + 'REQUEST' + '='*5 + '\r\n'+ str(request_f)+'\r\n') return request
def history_schedule(): model = Atom('History') user_id = '38000000001_13825' # roster_id = [] :: [] | binary(), history_type = Atom('act') name = 'publish' # name = <<"publish">> :: [] | binary(), dt = '38000000001_13825' # data = []:: binary() | integer() | list(term())}) action = Atom('get') size = [] # size = 0 :: [] | integer(), entity_id = [] # entity_id = 0 :: [] | integer(), data = [] # data = [] :: list(#'Message'{}) | list(#'Job'{}), request_f = (model,user_id,(history_type,name,dt),size,entity_id,data,action) request = bert.encode(request_f) print('='*5 + 'REQUEST' + '='*5 + '\r\n'+ str(request_f)+'\r\n') return request
def history_group(user_id, group_id): model = Atom('History') user_id = user_id # roster_id = [] :: [] | binary(), history_type = Atom('muc') group_id = group_id # group_id = [] :: [] | binary(), size = [] # size = 0 :: [] | integer(), entity_id = [] # entity_id = 0 :: [] | integer(), data = [] # data = [] :: list(#'Message'{}) | list(#'Job'{}), action = Atom('delete') request_f = (model,user_id,(history_type,group_id),size,entity_id,data,action) request = bert.encode(request_f) # log.debug('='*5 + 'REQUEST' + '='*5 + '\r\n'+ str(request_f)+'\r\n') log.debug('Clear group chat history request') return request
def history_p2p(): model = Atom('History') user_id = '8613777322455_544' # roster_id = [] :: [] | binary(), history_type = Atom('p2p') from_r = '12566018988_541' # from = [] :: [] | binary(), to_r = '51997259024_542' # to = [] :: [] | binary() action = Atom('get') size = -15 # size = 0 :: [] | integer(), entity_id = 20483 # entity_id = 0 :: [] | integer(), data = [] # data = [] :: list(#'Message'{}) | list(#'Job'{}), request_f = (model,user_id,(history_type,from_r,to_r),size,entity_id,data,action) request = bert.encode(request_f) print('='*5 + 'REQUEST' + '='*5 + '\r\n'+ str(request_f)+'\r\n') return request
def room(**data): module = Atom('Room') expected = [ 'room_id', 'name', 'links', 'description', 'settings', 'members', 'admins', 'data', 'room_type', 'tos', 'tos_update', 'unread', 'mentions', 'readers', 'last_msg', 'update', 'created', 'room_status' ] actual = data my_dict = {} for i in expected: if i in actual.keys(): my_dict.update({i: actual[i]}) else: my_dict.update({i: []}) request_f = (module, my_dict['room_id'], my_dict['name'], my_dict['links'], my_dict['description'], my_dict['settings'], my_dict['members'], my_dict['admins'], my_dict['data'], my_dict['room_type'], my_dict['tos'], my_dict['tos_update'], my_dict['unread'], my_dict['mentions'], my_dict['readers'], my_dict['last_msg'], my_dict['update'], my_dict['created'], my_dict['room_status']) request = bert.encode(request_f) log.info('=' * 5 + 'REQUEST' + '=' * 5 + '\r\n' + str(request_f) + '\r\n') return request
async def download(self, bundle): vault = self.vault assert vault is not None assert self.stream is not None self.logger.info('Downloading %s', bundle) # download key and file await self.write_term('download', bundle.store_hash) response = await self.read_term() if len(response) == 3: server_info = rewrite_atoms_dict(response[1]) server_info.update(**rewrite_atoms_dict(response[2])) url = None elif len(response) == 2 and isinstance( response[1], tuple) and response[1][0] == Atom('url'): response_obj = response[1] url = response_obj[1].decode() server_info = rewrite_atoms_dict(response_obj[2]) server_info.update(**rewrite_atoms_dict(response_obj[3])) else: raise Exception('xx') content_hash = server_info['content_hash'].decode() metadata = server_info['metadata'] file_size = server_info['size'] assert type(file_size) == int if url: self.logger.debug( 'Downloading content ({} bytes) from URL: {}'.format( file_size, url)) else: self.logger.debug( 'Downloading content ({} bytes) from stream.'.format( file_size)) # read content hash self.logger.debug('Content hash: %s', content_hash) await bundle.write_encrypted_metadata(Once(metadata)) await bundle.load_key() if url: stream_source = URLReader(url) else: stream_source = TrioStreamReader(self.stream) >> Limit(file_size) hash_ok = await vault.crypt_engine.write_encrypted_stream( bundle, stream_source, assert_hash=content_hash) if not hash_ok: # alert server of hash mismatch await self.write_term('invalid_content_hash', bundle.store_hash, vault.revision)
def convert_bert(self, item): bert_type = item[1] if bert_type == "nil": return None elif bert_type == "string": return item[3].decode(Atom(item[2])) elif bert_type == "dict": return dict((self.convert(k), self.convert(v)) for k, v in item[2]) elif bert_type in ("true", True): return True elif bert_type in ("false", False): return False elif bert_type == "time": return utc_to_datetime(item[2] * 1000000 + item[3], item[4]) elif bert_type == "regex": flags = 0 if 'extended' in item[3]: flags |= re.VERBOSE if 'caseless' in item[3]: flags |= re.IGNORECASE if 'multiline' in item[3]: flags |= re.MULTILINE if 'dotall' in item[3]: flags |= re.DOTALL return re.compile(item[2], flags) raise NotImplementedError("Unknown BERT type %s" % item[1])
def on_message(self, client, userdata, msg): print(msg.topic) print(bert.decode(bytes(msg.payload))) for node in (bert.decode(bytes(msg.payload))): if node == (Atom('ok'), Atom('sms_sent')): client.publish(topic="events/1//api/anon//", payload=bytearray(sms), qos=2, retain=False) elif re.findall(r"\(Atom\('ok2'\), Atom\('login'\)", str(node)): global psw global clie clie = str(node[2][0].decode("utf-8")) psw = str(node[2][1].decode("utf-8")) client.disconnect()
class BERTTestCase(unittest.TestCase): bert_tests = [ # nil (None, ("bert", "nil")), # nested nil ([None, (None, )], [("bert", "nil"), (("bert", "nil"), )]), # unicode (u"Mitä kuuluu", ('bert', 'string', Atom('UTF-8'), u"Mitä kuuluu".encode('utf-8'))), # dict ({ 'foo': 'bar' }, ('bert', 'dict', [('foo', 'bar')])), # empty dict ({}, ('bert', 'dict', [])), # nested dict ({ 'foo': { 'baz': 'bar' } }, ('bert', 'dict', [('foo', ('bert', 'dict', [('baz', 'bar')]))])), # empty tuple (tuple(), tuple()), # true (True, ('bert', 'true')), # false (False, ('bert', 'false')), # time (datetime.datetime.utcfromtimestamp(123 * 1000000 + 456).replace(microsecond=789), ('bert', 'time', 123, 456, 789)), # regex (re.compile('^c(a)t$', re.I | re.X), ('bert', 'regex', '^c(a)t$', (Atom('extended'), Atom('caseless')))), # other ([1, 2.0, ("foo", "bar")], [1, 2.0, ("foo", "bar")]), ] def testDecode(self): convert = BERTDecoder().convert for python, bert in self.bert_tests: self.failUnlessEqual(python, convert(bert)) def testEncode(self): convert = BERTEncoder().convert for python, bert in self.bert_tests: self.failUnlessEqual(bert, convert(python))
def desc_model(mime, payload, data): desc_module = Atom('Desc') desc_id = 'Autotest_desc_id' + str(time.time()).split('.')[0] desc_mime = mime desc_payload = payload parentid = [] data = data return desc_module, desc_id, desc_mime, desc_payload, parentid, data
def parser(client, payload, threadNumber): data = bert.decode(bytes(payload)) for node in data: if node == (Atom('ok'), Atom('sms_sent')): client.publish(topic="events/1//api/anon//", payload=bytearray(sms(threadNumber)), qos=2, retain=False) if node == Atom('Profile') and data[8] == 'remove': print('User {} deleted'.format(str(threadNumber))) client.disconnect() if node == Atom('Profile') and data[8] == 'init': client.publish(topic="events/1//api/anon//", payload=bytearray(delete_user(threadNumber)), qos=2, retain=False)
async def upload_identity(self, identity: Identity, description: str): self.logger.debug('Uploading my public key to server') # upload public key and fingerprint await self.write_term('add_user_key', identity.export_public_key(), identity.get_fingerprint(), description) response = await self.read_term() if response[0] == Atom('user_key_added'): raise UnexpectedResponseException()
async def write_term(self, *term): '''write a BERT tuple''' assert self.stream is not None if BINARY_DEBUG: self.logger.debug('[WRITE] Unserialized: %s', term) packet = bert.encode((Atom(term[0]), ) + term[1:]) packet_length = len(packet) assert packet_length > 0 if BINARY_DEBUG: self.logger.debug('[WRITE] Serialized: %s', packet) await self.stream.send_all(struct.pack('!I', packet_length) + packet)
def update_username(): model = Atom('Roster') user_id = 544 # id = [] :: [] | integer(), first_name = [] # names = [] :: [] | binary(), last_name = [] # surnames = [] :: [] | binary(), email = [] # email = [] :: [] | binary(), my_username = '******' # nick = [] :: [] | binary(), user_list = [] # userlist = [] :: list(#'Contact'{}), room_list = [] # roomlist = [] :: list(#'Room'{}), favorite = [] # favorite = [] :: list(#'ExtendedStar'{}), tags = [] # tags = [] :: list(#'Tag'{}), phone = [] # phone = [] :: [] | binary(), avatar = [] # avatar = [] :: [] | binary(), update = [] # update = 0 :: [] | integer(), status = Atom('nick') # status = [] :: [] | get | create | del | remove | nick | add | update # | list | patch | last_msg request_f = (model,user_id,first_name,last_name,email,my_username,user_list,room_list,favorite, tags,phone,avatar,update,status) request = bert.encode(request_f) print('='*5 + 'REQUEST' + '='*5 + '\r\n'+ str(request_f)+'\r\n') return request
def parser(client, payload, number, friend_phone): data = bert.decode(bytes(payload)) for node in data: if node == Atom('Profile') and data[8] == 'init': roas = (bert.decode(bytes(payload))[3]) user_id = roas[0][1] client.publish(topic="events/1//api/anon//", payload=bytearray(search(user_id, friend_phone)), qos=2, retain=False)
def act(**kwargs): module = Atom('act') expected = ['name', 'data'] actual = kwargs my_dict = {} for i in expected: if i in actual.keys(): my_dict.update({i: actual[i]}) else: my_dict.update({i: []}) return module, my_dict['name'], my_dict['data']
def p2p(**data): module = Atom('p2p') expected = ['from_user', 'to'] actual = data my_dict = {} for i in expected: if i in actual.keys(): my_dict.update({i: actual[i]}) else: my_dict.update({i: []}) request_f = (module, my_dict['from_user'], my_dict['to']) return request_f
def parser(client, payload, main_number): data = bert.decode(bytes(payload)) for node in data: if node == Atom('Profile') and data[8] == 'init': roster = (bert.decode(bytes(payload))[3]) user_id = roster[0][1] my = main_number + '_' + str(user_id) contacts = data[3][0][6] for field in contacts: if field[0] == Atom('Contact') and field[-1] == Atom('authorization'): client.publish(topic="events/1//api/anon//", payload=bytearray( friend(my_id=my, friend_id=field[1], status=Atom('confirm'))), qos=2, retain=False) if data == (Atom('io'), (Atom('error'), Atom('invalid_data')), b''): log.error("Something going wrong") client.disconnect() raise InvalidData("Invalid data response") if data == (Atom('io'), (Atom('error'), Atom('permission_denied')), b''): log.error("Something going wrong") client.disconnect() raise PermissionDenied("No permission")
async def read_term(self, assert_ok=True): '''reads a BERT tuple, asserts that first item is "ok"''' assert self.stream is not None pl_read = (await self.stream.receive_some(4)) if len(pl_read) != 4: raise ConnectionResetException() pl_tuple = struct.unpack('!I', pl_read) packet_length = pl_tuple[0] assert packet_length > 0 packet = b'' while len(packet) < packet_length: buf = await self.stream.receive_some(packet_length - len(packet)) if len(buf) == 0: raise ConnectionResetException() packet += buf if BINARY_DEBUG: logger.debug('[READ] Serialized: %s', packet) decoded = bert.decode(packet) if BINARY_DEBUG: self.logger.debug('[READ] Unserialized: %s', decoded) if assert_ok and decoded[0] != Atom('ok'): if decoded[0] == Atom('error'): if len(decoded) > 1 and decoded[1] == Atom('sync_required'): raise SyncRequired() else: raise ServerError(decoded[1:]) else: raise UnsuccessfulResponse(decoded) return decoded
def feature(**data): module = Atom('Feature') expected = ['id', 'key', 'value', 'group'] actual = data my_dict = {} for i in expected: if i in actual.keys(): my_dict.update({i: actual[i]}) else: my_dict.update({i: []}) request_f = (module, my_dict['id'], my_dict['key'], my_dict['value'], my_dict['group']) return request_f
def friend(**data): module = Atom('Friend') expected = ['my_id', 'friend_id', 'settings', 'status'] actual = data my_dict = {} for i in expected: if i in actual.keys(): my_dict.update({i: actual[i]}) else: my_dict.update({i: []}) request_f = (module, my_dict['my_id'], my_dict['friend_id'], my_dict['settings'], my_dict['status']) by_phone = bert.encode(request_f) return by_phone
def search(**data): module = Atom('Search') expected = ['user_id', 'ref', 'field', 'type_r', 'value', 'status'] actual = data my_dict = {} for i in expected: if i in actual.keys(): my_dict.update({i: actual[i]}) else: my_dict.update({i: []}) request_f = (module, my_dict['user_id'], my_dict['ref'], my_dict['field'], my_dict['type_r'], my_dict['value'], my_dict['status']) by_phone = bert.encode(request_f) # log.info('='*5 + 'REQUEST' + '='*5 + '\r\n'+ str(by_phone_f)+'\r\n') log.debug("Search by number {}".format(str(my_dict['value']))) return by_phone