def test_client_object_versioning(backend): new_id = "indicator--%s" % uuid.uuid4() new_bundle = copy.deepcopy(API_OBJECTS_2) new_bundle["objects"][0]["id"] = new_id resp = backend.add_objects("trustgroup1", "91a7b528-80eb-42ed-a74d-c6fbd5a26116", new_bundle, common.format_datetime(common.get_timestamp())) for i in range(0, 5): new_bundle = copy.deepcopy(API_OBJECTS_2) new_bundle["objects"][0]["id"] = new_id new_bundle["objects"][0]["modified"] = common.format_datetime( common.get_timestamp()) resp = backend.add_objects( "trustgroup1", "91a7b528-80eb-42ed-a74d-c6fbd5a26116", new_bundle, common.format_datetime(common.get_timestamp())) time.sleep(1) objs = backend.get_objects("trustgroup1", "91a7b528-80eb-42ed-a74d-c6fbd5a26116", { "match[id]": new_id, "match[version]": "all" }, ("id", "type", "version")) assert objs["objects"][0]["id"] == new_id assert objs["objects"][-1]["modified"] == new_bundle["objects"][0][ "modified"] objs = backend.get_objects("trustgroup1", "91a7b528-80eb-42ed-a74d-c6fbd5a26116", { "match[id]": new_id, "match[version]": "first" }, ("id", "type", "version")) assert objs["objects"][0]["id"] == new_id assert objs["objects"][0]["modified"] == "2017-01-27T13:49:53.935Z" objs = backend.get_objects("trustgroup1", "91a7b528-80eb-42ed-a74d-c6fbd5a26116", { "match[id]": new_id, "match[version]": "last" }, ("id", "type", "version")) assert objs["objects"][0]["id"] == new_id assert objs["objects"][0]["modified"] == new_bundle["objects"][0][ "modified"] objs = backend.get_objects("trustgroup1", "91a7b528-80eb-42ed-a74d-c6fbd5a26116", { "match[id]": new_id, "match[version]": "2017-01-27T13:49:53.935Z" }, ("id", "type", "version")) assert objs["objects"][0]["id"] == new_id assert objs["objects"][0]["modified"] == "2017-01-27T13:49:53.935Z" resp2 = backend.get_status("trustgroup1", resp["id"]) assert resp2["success_count"] == 1 mani = backend.get_object_manifest("trustgroup1", "91a7b528-80eb-42ed-a74d-c6fbd5a26116", {"match[id]": new_id}, ("id", "type", "version")) assert mani[0]["id"] == new_id assert filter( lambda obj: obj["id"] == new_bundle["objects"][0]["modified"], mani[0]["versions"]) is not None
def add_auth_data_from_file(client, data): # Insert the new user. db = client['auth'] users = db['users'] api_keys = db['api_keys'] timestamp = get_timestamp() data['user']['created'] = format_datetime(timestamp) data['api_key']['created'] = format_datetime(timestamp) users.insert_one(data['user']) api_keys.insert_one(data['api_key'])
def _update_manifest(self, new_obj, api_root, collection_id): api_info = self._get(api_root) collections = api_info.get("collections", []) for collection in collections: if "id" in collection and collection_id == collection["id"]: for entry in collection["manifest"]: if new_obj["id"] == entry["id"]: if "modified" in new_obj: entry["versions"].append(new_obj["modified"]) # If the new_obj is there, and it has no modified # property, then it is immutable, and there is nothing # to do. break else: if "modified" in new_obj: version = new_obj["modified"] else: version = new_obj["created"] collection["manifest"].append( {"id": new_obj["id"], "date_added": format_datetime(get_timestamp()), "versions": [version], "media_types": ["application/vnd.oasis.stix+json; version=2.0"]} ) # media_types hardcoded for now... # quit once you have found the collection that needed updating break
def get_or_add_objects(api_root, id_): # TODO: Check if user has access to read or write objects in collection - right now just check for permissions on the collection. if not collection_exists(api_root, id_): abort(404) if request.method == "GET": if permission_to_read(api_root, id_): objects = current_app.medallion_backend.get_objects(api_root, id_, request.args, ("id", "type", "version")) if objects: return Response(response=flask.json.dumps(objects), status=200, mimetype=MEDIA_TYPE_STIX_V20) else: abort(404) else: abort(403) elif request.method == "POST": if permission_to_write(api_root, id_): # Can't I get this from the request itself? request_time = common.format_datetime(common.get_timestamp()) status = current_app.medallion_backend.add_objects(api_root, id_, request.get_json(force=True), request_time) return Response(response=flask.json.dumps(status), status=202, mimetype=MEDIA_TYPE_TAXII_V20) else: abort(403)
def add_api_key_for_user(client, email): api_key = str(uuid.uuid4()).replace('-', '') timestamp = get_timestamp() api_key_obj = { "_id": api_key, "user_id": email, "created": format_datetime(timestamp), "last_used_at": "", "last_used_from": "" } # Check that the user exists. If the user exists, insert the new api_key, and update the corresponding user. db = client['auth'] users = db['users'] user = users.find_one({"_id": email}) if user: # Add an api key and print it. api_keys = db['api_keys'] api_keys.insert_one(api_key_obj) print("new api key: {} added for email: {}".format(api_key, email)) else: print( "no user with email: {} was found in the database.".format(email))
def _update_manifest(self, new_obj, api_root, _collection_id): # TODO: Handle if mongodb is not available api_root_db = self.client[api_root] manifest_info = api_root_db["manifests"] entry = manifest_info.find_one({ "_collection_id": _collection_id, "id": new_obj["id"] }) if entry: if "modified" in new_obj: entry["versions"].append(new_obj["modified"]) manifest_info.update_one( { "collection_id": _collection_id, "id": new_obj["id"] }, {"$set": { "versions": entry["versions"] }}) # if the new_obj is there, and it has no modified property, then it is immutable, and there is nothing to do. else: version = new_obj.get('modified', new_obj['created']) manifest_info.insert_one({ "id": new_obj["id"], "_collection_id": _collection_id, "date_added": format_datetime(get_timestamp()), "versions": [version], # hardcoded for now "media_types": ["application/vnd.oasis.stix+json; version=2.0"] })
def _update_manifest(self, new_obj, api_root, collection_id): api_info = self._get(api_root) collections = api_info.get("collections", []) for collection in collections: if "id" in collection and collection_id == collection["id"]: for entry in collection["manifest"]: if entry["id"] == new_obj["id"]: # only called when modified is different entry["versions"].append(new_obj["modified"]) return collection["manifest"].append({"id": new_obj["id"], "date_added": format_datetime(get_timestamp()), "versions": [new_obj["modified"]], # hardcoded for nowmed "media_types": ["application/vnd.oasis.stix+json; version=2.0"]})
def _update_manifest(self, new_obj, api_root, collection_id): # TODO: Handle if mongodb is not available api_root_db = self.client[api_root] manifest_info = api_root_db["manifests"] entry = manifest_info.find_one({"collection_id": collection_id, "id": new_obj["id"]}) if entry: entry["versions"].append(new_obj["modified"]) manifest_info.update_one({"collection_id": collection_id, "id": new_obj["id"]}, {"$set": {"versions": entry["versions"]}}) return manifest_info.insert_one({"id": new_obj["id"], "collection_id": collection_id, "date_added": format_datetime(get_timestamp()), "versions": [new_obj["modified"]], # hardcoded for now "media_types": ["application/vnd.oasis.stix+json; version=2.0"] })
def get_object_manifest(self, api_root, id_, filter_args, allowed_filters, start_index, page_size): api_root_db = self.client[api_root] manifest_info = api_root_db["manifests"] full_filter = MongoDBFilter(filter_args, {"_collection_id": id_}, allowed_filters, start_index, page_size) total, objects_found = full_filter.process_filter( manifest_info, allowed_filters, None) if objects_found: for obj in objects_found: if obj: obj.pop("_id", None) obj.pop("_collection_id", None) obj.pop("_type", None) # format date_added which is an ISODate object obj['date_added'] = format_datetime(obj['date_added']) return total, objects_found
def test_saving_data_file(backend): new_bundle = copy.deepcopy(API_OBJECTS_2) new_id = "indicator--%s" % uuid.uuid4() new_bundle["objects"][0]["id"] = new_id with tempfile.NamedTemporaryFile() as f: backend.add_objects("trustgroup1", "91a7b528-80eb-42ed-a74d-c6fbd5a26116", new_bundle, common.format_datetime(common.get_timestamp())) backend.save_data_to_file(f.name) assert os.path.isfile(f.name) init({"backend": {"type": "memory", "data_file": f.name}, "users": []}) backend2 = get_backend() obj = backend2.get_object("trustgroup1", "91a7b528-80eb-42ed-a74d-c6fbd5a26116", new_id, None, ("version",)) assert obj["objects"][0]["id"] == new_id
def test_add_objects(backend): new_bundle = copy.deepcopy(API_OBJECTS_2) new_id = "indicator--%s" % uuid.uuid4() new_bundle["objects"][0]["id"] = new_id resp = backend.add_objects("trustgroup1", "91a7b528-80eb-42ed-a74d-c6fbd5a26116", new_bundle, common.format_datetime(common.get_timestamp())) objs = backend.get_objects("trustgroup1", "91a7b528-80eb-42ed-a74d-c6fbd5a26116", {"match[id]": new_id}, ("id", "type", "version")) assert objs["objects"][0]["id"] == new_id resp2 = backend.get_status("trustgroup1", resp["id"]) assert resp2["success_count"] == 1 mani = backend.get_object_manifest("trustgroup1", "91a7b528-80eb-42ed-a74d-c6fbd5a26116", {"match[id]": new_id}, ("id", "type", "version")) assert mani[0]["id"] == new_id
def _update_manifest(self, new_obj, api_root, _collection_id): api_root_db = self.client[api_root] manifest_info = api_root_db["manifests"] entry = manifest_info.find_one({ "_collection_id": _collection_id, "id": new_obj["id"] }) if entry: if "modified" in new_obj: entry["versions"].append(new_obj["modified"]) manifest_info.update_one( { "_collection_id": _collection_id, "id": new_obj["id"] }, { "$set": { "versions": sorted(entry["versions"], reverse=True) } }) # If the new_obj is there, and it has no modified property, # then it is immutable, and there is nothing to do. else: version = new_obj.get("modified", new_obj["created"]) manifest_info.insert_one({ "id": new_obj["id"], "_collection_id": _collection_id, "_type": new_obj["type"], "date_added": format_datetime(get_timestamp()), "versions": [version], "media_types": ["application/vnd.oasis.stix+json; version=2.0"] }) # media_types hardcoded for now...
def test_client_object_versioning(self): new_id = "indicator--%s" % uuid.uuid4() new_bundle = copy.deepcopy(API_OBJECTS_2) new_bundle["objects"][0]["id"] = new_id # ------------- BEGIN: add object section ------------- # post_header = copy.deepcopy(self.auth) post_header["Content-Type"] = MEDIA_TYPE_STIX_V20 post_header["Accept"] = MEDIA_TYPE_TAXII_V20 r_post = self.client.post( "/trustgroup1/collections/91a7b528-80eb-42ed-a74d-c6fbd5a26116/objects/", data=json.dumps(new_bundle), headers=post_header) status_response = self.load_json_response(r_post.data) self.assertEqual(r_post.status_code, 202) self.assertEqual(r_post.content_type, MEDIA_TYPE_TAXII_V20) for i in range(0, 5): new_bundle = copy.deepcopy(API_OBJECTS_2) new_bundle["objects"][0]["id"] = new_id new_bundle["objects"][0]["modified"] = common.format_datetime( common.get_timestamp()) r_post = self.client.post( "/trustgroup1/collections/91a7b528-80eb-42ed-a74d-c6fbd5a26116/objects/", data=json.dumps(new_bundle), headers=post_header) status_response = self.load_json_response(r_post.data) self.assertEqual(r_post.status_code, 202) self.assertEqual(r_post.content_type, MEDIA_TYPE_TAXII_V20) time.sleep(1) # ------------- END: add object section ------------- # # ------------- BEGIN: get object section 1 ------------- # get_header = copy.deepcopy(self.auth) get_header["Accept"] = MEDIA_TYPE_STIX_V20 r_get = self.client.get( "/trustgroup1/collections/91a7b528-80eb-42ed-a74d-c6fbd5a26116/objects/?match[id]=%s&match[version]=%s" % (new_id, "all"), headers=get_header) self.assertEqual(r_get.status_code, 200) self.assertEqual(r_get.content_type, MEDIA_TYPE_STIX_V20) objs = self.load_json_response(r_get.data) assert objs["objects"][0]["id"] == new_id assert objs["objects"][-1]["modified"] == new_bundle["objects"][0][ "modified"] # ------------- END: get object section 1 ------------- # # ------------- BEGIN: get object section 2 ------------- # r_get = self.client.get( "/trustgroup1/collections/91a7b528-80eb-42ed-a74d-c6fbd5a26116/objects/?match[id]=%s&match[version]=%s" % (new_id, "first"), headers=get_header) self.assertEqual(r_get.status_code, 200) self.assertEqual(r_get.content_type, MEDIA_TYPE_STIX_V20) objs = self.load_json_response(r_get.data) assert objs["objects"][0]["id"] == new_id assert objs["objects"][0]["modified"] == "2017-01-27T13:49:53.935Z" # ------------- END: get object section 2 ------------- # # ------------- BEGIN: get object section 3 ------------- # r_get = self.client.get( "/trustgroup1/collections/91a7b528-80eb-42ed-a74d-c6fbd5a26116/objects/?match[id]=%s&match[version]=%s" % (new_id, "last"), headers=get_header) self.assertEqual(r_get.status_code, 200) self.assertEqual(r_get.content_type, MEDIA_TYPE_STIX_V20) objs = self.load_json_response(r_get.data) assert objs["objects"][0]["id"] == new_id assert objs["objects"][0]["modified"] == new_bundle["objects"][0][ "modified"] # ------------- END: get object section 3 ------------- # # ------------- BEGIN: get object section 4 ------------- # r_get = self.client.get( "/trustgroup1/collections/91a7b528-80eb-42ed-a74d-c6fbd5a26116/objects/?match[id]=%s&match[version]=%s" % (new_id, "2017-01-27T13:49:53.935Z"), headers=get_header) self.assertEqual(r_get.status_code, 200) self.assertEqual(r_get.content_type, MEDIA_TYPE_STIX_V20) objs = self.load_json_response(r_get.data) assert objs["objects"][0]["id"] == new_id assert objs["objects"][0]["modified"] == "2017-01-27T13:49:53.935Z" # ------------- END: get object section 4 ------------- # # ------------- BEGIN: get status section ------------- # r_get = self.client.get("/trustgroup1/status/%s/" % status_response["id"], headers=self.auth) self.assertEqual(r_get.status_code, 200) self.assertEqual(r_get.content_type, MEDIA_TYPE_TAXII_V20) status_response2 = self.load_json_response(r_get.data) assert status_response2["success_count"] == 1 # ------------- END: get status section ------------- # # ------------- BEGIN: get manifest section ------------- # r_get = self.client.get( "/trustgroup1/collections/91a7b528-80eb-42ed-a74d-c6fbd5a26116/manifest/?match[id]=%s" % new_id, headers=self.auth) self.assertEqual(r_get.status_code, 200) self.assertEqual(r_get.content_type, MEDIA_TYPE_TAXII_V20) manifests = self.load_json_response(r_get.data) assert manifests["objects"][0]["id"] == new_id assert any(version == new_bundle["objects"][0]["modified"] for version in manifests["objects"][0]["versions"])
def main(): uri = "mongodb://*****:*****@localhost:27017/" parser = argparse.ArgumentParser( 'medallion mongo-authdb script [OPTIONS]', description='Auth DB Utils') group = parser.add_mutually_exclusive_group() parser.add_argument('--uri', dest='uri', default=uri, help='Set the Mongo DB connection information') group.add_argument('-f', '--file', dest='file', help='Add a user with API key to the Auth DB') group.add_argument('-u', '--user', dest='user', action='store_true', help='Add a user to the Auth DB') group.add_argument('-k', '--apikey', dest='apikey', action='store_true', help='Add an API key to an existing user') args = parser.parse_args() client = make_connection(args.uri) if args.file is not None: with open(args.file, 'r') as i: data = json.load(i) add_auth_data_from_file(client, data) elif args.user: email = six.moves.input('email address : ').strip() password1 = six.moves.input('password : '******'verify password : '******'passwords were not the same') company_name = six.moves.input('company name : ').strip() contact_name = six.moves.input('contact name : ').strip() add_api_key = six.moves.input('add api key (y/n)? : ').strip() password_hash = generate_password_hash(password1) timestamp = get_timestamp() user = { "_id": email, "password": password_hash, "company_name": company_name, "contact_name": contact_name, "created": format_datetime(timestamp), "updated": format_datetime(timestamp), } add_user(client, user) if add_api_key.lower() == 'y': add_api_key_for_user(client, email) elif args.apikey: email = six.moves.input('email address : ') add_api_key_for_user(client, email)