示例#1
0
 def setUp(self):
     self._db = Database(logger, True)
     new_api_key = binascii.hexlify(os.urandom(8)).decode('utf-8').upper()
     node_id = self._db.create_api_key(new_api_key)
     self.assertGreater(node_id, 0)
     self.api_key = new_api_key
     self.node_id = node_id
示例#2
0
class TestCreateAPIKey(unittest.TestCase):
    def setUp(self):
        self._db = Database(logger, True)

    def test_add_key(self):
        new_api_key = binascii.hexlify(os.urandom(8)).decode('utf-8').upper()
        result = self._db.create_api_key(new_api_key)
        self.assertGreater(result, 0)

    def test_invalid_api_key(self):
        result = self._db.create_api_key("invalid")
        self.assertEqual(result, -1)

    def test_custom_reset_interval(self):
        new_api_key = binascii.hexlify(os.urandom(8)).decode('utf-8').upper()
        result = self._db.create_api_key(new_api_key, next_reset_seconds=5000)
        self.assertGreater(result, 0)
        api_key_info = self._db.validate_api_key(new_api_key)
        lower_bounds = 4995
        higher_bounds = 5005
        self.assertGreater(api_key_info[3],
                           datetime.now() + timedelta(seconds=lower_bounds))
        self.assertLess(api_key_info[3],
                        datetime.now() + timedelta(seconds=higher_bounds))
        self.assertEqual(result, api_key_info[0])
示例#3
0
 def setUp(self) -> None:
     # my default development environment values
     dev = Environment("localhost", "localhost", "pico", "password",
                       "picoevent", "picoevent_test_db", 1000, 3600,
                       "localhost", "localhost")
     self._db = Database(env=dev)
     self._event_log = EventLog(self._db)
     self._event_type_ids = self._event_log.list_event_types()
示例#4
0
 def setUp(self):
     self._db = Database(logger, True)
     self._target_api_keys = random.randint(5, 100)
     self._api_keys = []
     for x in range(0, self._target_api_keys):
         new_api_key = binascii.hexlify(
             os.urandom(8)).decode('utf-8').upper()
         result = self._db.create_api_key(new_api_key)
         self.assertGreater(result, 0)
         self._api_keys.append(new_api_key)
示例#5
0
class TestCreateEventType(unittest.TestCase):
    def setUp(self):
        self._db = Database(logger, True)

    def test_create_event_type(self):
        result = self._db.create_event_type("Node Update Event")
        self.assertGreater(result, 0)

    def test_create_event_type_db_fault(self):
        result = self._db.create_event_type("a" * 60)
        self.assertEqual(-1, result)
示例#6
0
class TestListEventTypes(unittest.TestCase):
    def setUp(self):
        self._db = Database(logger, True)
        for each in DEFAULT_EVENTS:
            self._db.create_event_type(each)

    def test_list_event_types(self):
        event_types = self._db.list_event_types()
        all_events = []
        for event in event_types:
            all_events.append(event[1])
        result = set(DEFAULT_EVENTS) - set(all_events)
        self.assertEqual(0, len(result))
示例#7
0
class TestAdminLogin(unittest.TestCase):
    def setUp(self):
        self._db = Database(logger, True)

    def test_admin_login(self):
        result = self._db.login("admin", "test_password")
        self.assertIsNotNone(result)
        new_session_token = result[0]
        admin_user_id = result[1]
        admin_user = self._db.validate_session(new_session_token)
        self.assertEqual(admin_user.user_id, admin_user_id)
        self.assertEqual(admin_user.session_token, new_session_token)
        self.assertEqual(admin_user.email_address, "admin")
        self.assertEqual(admin_user.full_name, "Administrator")
示例#8
0
    def __init__(self, db=None, logger=None):
        self._cache = redis.Redis()
        if db:
            self._db = db
        else:
            self._db = Database(logger)
        self._logger = logger

        event_types = []
        for each in self.list_event_types():
            event_types.append(each[1])
        missing_events = set(DEFAULT_EVENTS) - set(event_types)
        for new_event in missing_events:
            self._db.create_event_type(new_event)
示例#9
0
class TestDatabaseNotFoundException(unittest.TestCase):
    MAX_EVENTS_LOGGED = 1000

    def setUp(self) -> None:
        self._db = Database(logger, True)
        self._mock_data = dict()
        total_events = random.randint(0, self.MAX_EVENTS_LOGGED)

        for each in DEFAULT_EVENTS:
            event_type_id = self._db.create_event_type(each)
            self.assertGreater(event_type_id,
                               0,
                               msg="Failed to create event type")
            mock_events = []
            now = datetime.now()
            for x in range(0, total_events):
                mock_event_data = {
                    "floatMock": random.random(),
                    "datetimeMock": random_later_datetime().isoformat(),
                    "integerMock": random.randint(0, 1500000),
                    "stringMock": "a" * random.randint(0, 1024)
                }

                new_mock_event = Event(0, event_type_id, each, mock_event_data,
                                       0, 1, now)
                mock_events.append(new_mock_event)
            self._mock_data[each] = mock_events

        event_type = random.choice(DEFAULT_EVENTS)
        mock_events = self._mock_data[event_type]
        event_type_id = None
        for each_mock in mock_events:
            if event_type_id is None:
                event_type_id = each_mock.event_type_id
            event_id = self._db.log_event(each_mock.event_data,
                                          each_mock.event_type_id,
                                          each_mock.node_id, each_mock.user_id)
            self.assertGreater(event_id, 0, msg="Failed to log event.")
            each_mock.event_id = event_id
        event_type_count = self._db.get_event_count(
            event_type_id=event_type_id)
        self.assertEqual(event_type_count, len(mock_events))
        logger.info("Events logged: {0} ({1})".format(event_type_count,
                                                      event_type))

    def test_lookupFailed(self):
        with self.assertRaises(DatabaseNotFoundException):
            self._db.get_event_data(self.MAX_EVENTS_LOGGED +
                                    self.MAX_EVENTS_LOGGED)
示例#10
0
def admin_create_api_key():
    with current_app.app_context():
        environment = Environment(current_app)

    session_token = request.form["token"]
    db = Database(logger=current_app.logger, env=environment)
    analyst_user = db.validate_session(session_token)
    if analyst_user and analyst_user.has_permission("create-api-key"):
        new_api_key = binascii.hexlify(os.urandom(8)).decode('utf-8').upper()
        result = db.create_api_key(new_api_key)
        if result == -1:
            flash("Could not create API key.", category="error")
        return redirect(url_for("admin.home", session_token=session_token))
    else:
        abort(403)
示例#11
0
 def change_administrator_password(self):
     _db = Database(self._logger, False, False, self._env)
     admin_uid = _db.admin_user_id
     if admin_uid > 0:
         new_password = input("New administrator password: "******"admin", new_password)
         except DatabaseException:
             print(
                 "Database exception: unable to reset administrators password."
             )
     else:
         print(
             "Invalid administrator user ID, database could be corrupted.")
         print(
             "Consider creating a new empty database and starting over.\n")
示例#12
0
def post_event(api_key):
    with current_app.app_context():
        environment = Environment(current_app)

    db = Database(logger=current_app.logger, env=environment)
    event_log = EventLog(db, logger=current_app.logger)
    try:
        node = event_log.get_api_key_object(api_key)
        event_log.update_quota(node)
        posted_data = request.get_json(force=True)
        if "event_type_id" in posted_data:
            event_type_id = int(posted_data["event_type_id"])
            if event_type_id in event_log.event_type_ids_as_set:
                node_id = node.node_id
                user_id = None
                if "user_id" in posted_data and posted_data["user_id"] is not None:
                    user_id = int(posted_data["user_id"])
                    del posted_data["user_id"]
                    if user_id <= 0:
                        raise ValueError("user_id must be positive or omitted")
                new_event = event_log.log_event(posted_data, event_type_id, user_id, node_id)
                return Response(json.dumps({"success": True, "event_id": new_event.event_id}))
    except APIKeyRateLimited:
        abort(420)
    except APIKeyInvalid:
        abort(404)
    except APIKeySuspended:
        abort(403)
示例#13
0
class TestListEventTypes(unittest.TestCase):
    def setUp(self) -> None:
        # my default development environment values
        dev = Environment("localhost", "localhost", "pico", "password",
                          "picoevent", "picoevent_test_db", 1000, 3600,
                          "localhost", "localhost")
        self._db = Database(env=dev)
        self._event_log = EventLog(self._db)
        self._event_type_ids = self._event_log.list_event_types()

    def test_listUnitTypes(self):
        new_api_key = binascii.hexlify(os.urandom(8)).decode('utf-8').upper()
        result = self._db.create_api_key(new_api_key,
                                         rate_limit_quota=15000,
                                         next_reset_seconds=5000)
        self.assertGreater(result, 0)
        rest_client = PicoEventRestClient.PicoEventRestClient(
            TEST_ENDPOINT, new_api_key)
        retrieved_event_types = rest_client.get_event_types()
        self.assertEqual(len(retrieved_event_types), len(self._event_type_ids))
        for x in range(0, len(retrieved_event_types)):
            event_type = self._event_type_ids[x]
            retrieved_event_type = retrieved_event_types[x]
            self.assertEqual(event_type[0], retrieved_event_type[0])
            self.assertEqual(event_type[1], retrieved_event_type[1])
示例#14
0
class TestListAPIKeys(unittest.TestCase):
    def setUp(self):
        self._db = Database(logger, True)
        self._target_api_keys = random.randint(5, 100)
        self._api_keys = []
        for x in range(0, self._target_api_keys):
            new_api_key = binascii.hexlify(
                os.urandom(8)).decode('utf-8').upper()
            result = self._db.create_api_key(new_api_key)
            self.assertGreater(result, 0)
            self._api_keys.append(new_api_key)

    def test_list_api_keys(self):
        all_api_keys = self._db.list_api_keys()
        self.assertEqual(self._target_api_keys, len(all_api_keys))
        for x in range(0, self._target_api_keys):
            self.assertEqual(all_api_keys[x][1], self._api_keys[x])
示例#15
0
def latest_events(limit, session_token):
    with current_app.app_context():
        environment = Environment(current_app)

    db = Database(logger=current_app.logger, env=environment, read_only=True)
    try:
        user = db.validate_session(session_token)
        # TODO: permissions
        event_log = EventLog(db, logger=current_app.logger)
        _latest_events = event_log.retrieve_events(limit=limit)
        json_array = []
        for each_event in _latest_events:
            json_array.append(str(each_event))
        return Response(json.dumps({"success": True,
                                    "count": len(json_array),
                                    "events": json_array}))
    except DatabaseException:
        abort(403)
示例#16
0
 def setUp(self):
     self._db = Database(logger, True)
     self._event_log = EventLog(self._db, logger)
     self._added_events = []
     x = 0
     for each_event in DEFAULT_EVENTS:
         event_type_id = self._event_log.add_event_type(each_event)
         self.assertGreater(event_type_id, 0)
         self._added_events.append(each_event)
         if x == 4:
             break
         x += 1
示例#17
0
    def setUp(self):
        self._db = Database(logger, True)
        self._mock_data = dict()
        now = datetime.now()
        for each in DEFAULT_EVENTS:
            event_type_id = self._db.create_event_type(each)
            self.assertGreater(event_type_id,
                               0,
                               msg="Failed to create event type")
            mock_events = []
            for x in range(0, random.randint(10, 50)):
                mock_event_data = {
                    "floatMock": random.random(),
                    "datetimeMock": random_later_datetime().isoformat(),
                    "integerMock": random.randint(0, 1500000),
                    "stringMock": "a" * random.randint(0, 1024)
                }

                new_mock_event = Event(0, event_type_id, each, mock_event_data,
                                       0, 1, now)
                mock_events.append(new_mock_event)
            self._mock_data[each] = mock_events
示例#18
0
class TestRateLimitQuota(unittest.TestCase):
    TEST_LIMIT = 500

    def setUp(self):
        self._db = Database(logger, True)
        new_api_key = binascii.hexlify(os.urandom(8)).decode('utf-8').upper()
        node_id = self._db.create_api_key(new_api_key)
        self.assertGreater(node_id, 0)
        self.api_key = new_api_key
        self.node_id = node_id

    def test_rateLimit(self):
        for x in range(0, self.TEST_LIMIT):
            self.assertTrue(self._db.update_quota(self.node_id))
        node_info = self._db.validate_api_key(self.api_key)
        self.assertEqual(node_info[0], self.node_id)
        self.assertEqual(node_info[4], self.TEST_LIMIT)
        next_reset = self._db.next_quota_reset
        self.assertTrue(self._db.reset_quota(self.node_id, next_reset))
        node_info = self._db.validate_api_key(self.api_key)
        self.assertEqual(node_info[0], self.node_id)
        self.assertEqual(0, node_info[4])
示例#19
0
def add_event_type(session_token):
    with current_app.app_context():
        environment = Environment(current_app)

    db = Database(logger=current_app.logger, env=environment)
    user_object = db.validate_session(session_token)
    if user_object and user_object.has_permission("add-event-type"):
        new_event_type = request.form["new_event_type"]
        if EVENT_TYPE_REGEX.match(new_event_type):
            new_event_type_id = db.create_event_type(new_event_type)
            if new_event_type_id:
                return Response(json.dumps({"new_event_type_id": new_event_type_id,
                                            "success": True}))
            else:
                return Response(json.dumps({"success": False,
                                            "error_message": "Could not add to database.",
                                            "error_code": 1}))
        else:
            return Response(json.dumps({"success": False,
                                        "error_message": "Invalid event type name.",
                                        "error_code": 2}))
    return Response(status=403)
示例#20
0
def login():
    with current_app.app_context():
        environment = Environment(current_app)

    input_data = request.get_json(True)

    username = input_data["username"]
    password = input_data["password"]

    db = Database(logger=current_app.logger, env=environment)
    try:
        result = db.login(username, password)
        session_token = result[0]
        return json.dumps({
            "success": True,
            "session_token": session_token.decode('utf-8')
        })
    except DatabaseException:
        flash("Invalid e-mail/password combination.", category="error")
        return json.dumps({
            "success": False,
            "error_msg": "Invalid e-mail/password combination."
        })
示例#21
0
def home(session_token):
    with current_app.app_context():
        environment = Environment(current_app)

    db = Database(logger=current_app.logger, env=environment)
    event_log = EventLog(db, current_app.logger)
    user = db.validate_session(session_token)
    if user:
        event_types = event_log.list_event_types()
        color_schema_css = ""
        color_schema = DefaultColorSchema()
        for x in range(0, len(event_types)):
            rgb = color_schema.rgb(x)
            css = "#event_row_id_{0} {{ background-color: rgb({1},{2},{3}); }}".format(
                x, rgb[0], rgb[1], rgb[2])
            color_schema_css += css + "\n"
        api_keys = event_log.list_api_keys()
        return render_template("admin_control_panel.jinja2",
                               session_token=session_token,
                               event_types=event_types,
                               api_keys=api_keys,
                               color_schema_css=color_schema_css)
    return redirect(url_for("admin_no_session"))
示例#22
0
def add_event_type():
    with current_app.app_context():
        environment = Environment(current_app)

    session_token = request.form['token']
    new_event_name = request.form['new_event_name']

    db = Database(logger=current_app.logger, env=environment)
    user = db.validate_session(session_token)
    if user and user.has_permission("add-event-type"):
        event_log = EventLog(db, current_app.logger)
        try:
            new_event_id = event_log.add_event_type(new_event_name)
            if new_event_id > 0:
                return redirect(
                    url_for("admin.home", session_token=session_token))
        except EventLogException:
            current_app.logger.error(
                "Event log exception on add_event_type: {0}".format(
                    new_event_name))
            flash("Event log/database exception on add_event_type function.",
                  "error")
            return redirect(url_for("admin.home", session_token=session_token))
    flash("Not authorized.", category="error")
示例#23
0
def list_event_types(api_key):
    with current_app.app_context():
        environment = Environment(current_app)

    db = Database(logger=current_app.logger, env=environment)
    event_log = EventLog(db, logger=current_app.logger)
    try:
        node = event_log.get_api_key_object(api_key)
        event_log.update_quota(node)
        output = json.dumps({"success": True, "event_types": event_log.list_event_types()})
        return output
    except APIKeyRateLimited:
        abort(420)
    except APIKeyInvalid:
        abort(404)
    except APIKeySuspended:
        abort(403)
示例#24
0
    def display_menu(self):
        if self._state == "USER_ADMIN":
            self._user_admin_mgr.main_menu()

        print("Console Administration Main Menu\n")
        try:
            test_db = Database(self._logger, True, False, self._env)
            del test_db
        except DatabaseException:
            print(
                "Warning: Test database does not exist or is not accessible with supplied credentials."
            )
        print("\n")
        x = 1
        for choice in ConsoleMainMenuManager.MAIN_MENU:
            print("{0}.) {1}".format(x, choice))
            x += 1
        choice = self.select_item(1, 3)
        if choice == 1:
            self.change_administrator_password()
        elif choice == 2:
            _db = Database(self._logger, False, False, self._env)
            # node_id, api_key, created, quota, next_reset, events_posted
            all_api_keys = _db.list_api_keys()
            del _db
            print(
                "Node ID\tAPI Key\tCreated\tQuota\tNext Reset\tEvents Posted")
            for each_key in all_api_keys:
                print("{0}\t{1}\t{2}\t{3}\t{4}\t{5}\t{6}".format(
                    each_key[0], each_key[1], each_key[2].isoformat(),
                    each_key[3], each_key[4], each_key[5]))
        elif choice == 3:
            print(
                "Would you like to set a custom quota reset interval for the new API key?"
            )
            custom_reset_seconds = None
            if self.confirm():
                day_seconds = 3600 * 24
                print(
                    "Choose a quota reset interval in seconds between 1 and {0}"
                    .format(day_seconds))
                custom_reset_seconds = self.select_item(1, day_seconds)
            print("Would you like to set a custom quota for the new API key?")
            custom_quota = None
            if self.confirm():
                print("Choose a custom quota between 100 and 50000")
                custom_quota = self.select_item(100, 50000)
            new_api_key = binascii.hexlify(
                os.urandom(8)).decode('utf-8').upper()
            _db = Database(self._logger, False, False, self._env)
            node_id = _db.create_api_key(new_api_key, custom_quota,
                                         custom_reset_seconds)
            if node_id > 0:
                api_key_info = _db.validate_api_key(new_api_key)
                print(
                    "New API Key {0} generated with a quota of {1}, next reset {1}."
                    .format(api_key_info[1], api_key_info[4], api_key_info[5]))
            else:
                print(
                    "Could not create a new API key, check log file for more info."
                )
            del _db
        elif choice == 4:
            print(
                "Reset quota (you will need the node id from the API key list)"
            )
            _db = Database(self._logger, False, False, self._env)
            all_node_ids = set()
            for each_api_key in _db.list_api_keys:
                all_node_ids.add(each_api_key[0])
            repeat = True
            node_id = None
            while repeat:
                user_input = int(input("Node ID: "))
                if user_input in all_node_ids:
                    node_id = user_input
                    break
                print(
                    "Node ID {0} not in the list of active API keys. Try again?"
                )
                repeat = self.confirm()
            if node_id:
                next_reset = _db.reset_quota
                print(
                    "Would you like to set a custom reset interval (default: 3600 seconds)"
                )
                if self.confirm():
                    day_seconds = 3600 * 24
                    print(
                        "Choose a quota reset interval in seconds between 1 and {0}"
                        .format(day_seconds))
                    next_reset = datetime.now() + timedelta(
                        seconds=self.select_item(1, day_seconds))
                _db.reset_quota(node_id, next_reset)
        elif choice == 5:
            self.user_admin_mode(self._user_id, self._session_token)
        else:
            print("Bye")
            sys.exit(0)
        input("Press Enter to continue")
示例#25
0
class EventLog:
    def __init__(self, db=None, logger=None):
        self._cache = redis.Redis()
        if db:
            self._db = db
        else:
            self._db = Database(logger)
        self._logger = logger

        event_types = []
        for each in self.list_event_types():
            event_types.append(each[1])
        missing_events = set(DEFAULT_EVENTS) - set(event_types)
        for new_event in missing_events:
            self._db.create_event_type(new_event)

    def deserialize_user_object(self, event: Event):
        if event.is_analyst():
            cached_user_data = self._cache.get("analyst:{0}".format(
                event.user_id))
            if cached_user_data:
                user_data = json.dumps(cached_user_data)
                new_analyst_user = AnalystUser(
                    user_data["user_id"], user_data["email_address"],
                    user_data["session_token"], user_data["full_name"],
                    user_data["permissions"], user_data["view_event_type_ids"])
                return new_analyst_user
        else:
            cached_user_data = self._cache.get("django:{0}".format(
                event.user_id))
            if cached_user_data:
                user_data = json.dumps(cached_user_data)
                new_django_user = DjangoUser(
                    user_data["user_id"], user_data["username"],
                    user_data["first_name"], user_data["last_name"],
                    user_data["email_address"],
                    datetime.datetime.strptime(user_data["created"],
                                               "%Y-%m-%dT%H:%M:%S%z"),
                    datetime.datetime.strptime(user_data["last_logged_in"],
                                               "%Y-%m-%dT%H:%M:%S%z"))
                return new_django_user

    def get_api_key_object(self, api_key: str) -> APIKey:
        try:
            node_data = self._db.validate_api_key(api_key)
            node = APIKey(node_data[0], api_key, node_data[1], node_data[2],
                          node_data[3], node_data[4], node_data[5])
            if node.suspended_event:
                raise APIKeySuspended
            if node.next_reset is None or node.next_reset < datetime.datetime.now(
            ):
                next_reset = datetime.datetime.now() + datetime.timedelta(
                    hours=1)
                node.next_reset = next_reset
                node.events_posted = 0
                self._db.reset_quota(node.node_id, next_reset)
            if node.events_posted >= node.quota:
                raise APIKeyRateLimited
            return node
        except DatabaseException:
            raise APIKeyInvalid

    def list_api_keys(self) -> list:
        output = []
        try:
            all_api_keys = self._db.list_api_keys()
        except DatabaseException:
            raise EventLogException
        for each_api_key in all_api_keys:
            new_api_key = APIKey(each_api_key[0], each_api_key[1],
                                 each_api_key[2], each_api_key[3],
                                 each_api_key[4], each_api_key[5],
                                 each_api_key[6])
            output.append(new_api_key)
        return output

    def add_event_type(self, new_event_type):
        self._cache.delete("event_types")
        new_event_type_id = self._db.create_event_type(new_event_type)
        if new_event_type_id > 0:
            return new_event_type_id
        raise EventLogException

    @property
    def event_type_ids_as_set(self) -> set:
        try:
            all_event_types = self.list_event_types()
            all_event_type_ids = []
            for each in all_event_types:
                all_event_type_ids.append(each[0])
            return set(all_event_type_ids)
        except EventLogException:
            raise EventLogException

    def list_event_types(self) -> list:
        event_types_cached = self._cache.get("event_types")
        if event_types_cached:
            event_types = json.loads(event_types_cached)
        else:
            event_types = self._db.list_event_types()
            self._cache.set("event_types", json.dumps(event_types))
        if len(event_types) == 1 and event_types[0][0] == -1:
            raise EventLogException
        return event_types

    def get_event_count(self,
                        user_id=None,
                        event_type_id=None,
                        since=None,
                        until=None):
        return self._db.get_event_count(user_id, event_type_id, since, until)

    def log_event(self,
                  event_data: dict,
                  event_type_id: int,
                  user_id: int = None,
                  node_id: int = None):
        event_id = self._db.log_event(event_data, event_type_id, user_id,
                                      node_id)
        if event_id:
            event_type = None
            for event in self.list_event_types():
                if event[0] == event_type_id:
                    event_type = event[1]
                    break
            if not event_type:
                raise EventLogException
            new_event = Event(event_id, event_type_id, event_type, event_data,
                              user_id, node_id,
                              datetime.datetime.now().isoformat())
            self._cache.set("event_id:{0}".format(event_id), str(new_event))
            return new_event
        raise EventLogException

    def get_event(self, event_id: int) -> Event:
        cached_event_data = self._cache.get("event_id:{0}".format(event_id))
        new_event = None
        if cached_event_data:
            cached_obj = json.loads(cached_event_data)
            new_event = Event(
                cached_obj["event_id"], cached_obj["event_type_id"],
                cached_obj["event_type"], cached_obj["event_data"],
                cached_obj["node_id"], cached_obj["user_id"],
                datetime.datetime.strptime(cached_obj["created"],
                                           "%Y-%m-%dT%H:%M:%S%z"))
        else:
            db_event_record = self._db.get_event_data(event_id)
            if db_event_record:
                # event_id, event_type_id, node_id, user_id, event_data, created, event_type.event_type
                new_event = Event(db_event_record[0], db_event_record[1],
                                  db_event_record[2],
                                  json.loads(db_event_record[4]),
                                  db_event_record[2], db_event_record[3],
                                  db_event_record[5])
        if new_event:
            return new_event
        else:
            raise EventLogException

    def retrieve_events(self,
                        user_id: int = None,
                        since: datetime = None,
                        until: datetime = None,
                        event_type_id: int = None,
                        node_id: int = None,
                        limit: int = 100):
        try:
            meta_data = self._db.retrieve_events(user_id, event_type_id,
                                                 node_id, since, until, limit)
            #  event_id, event_type_id, node_id, user_id, created
            output = []
            for row in meta_data:
                event_id = row[0]
                cache_key = "event_id:{0}".format(event_id)
                event_data = self._cache.get(cache_key)

                if event_data is None:
                    event_data = self._db.get_event_data(event_id)
                    new_event = Event(event_data[0],
                                      event_data[1], event_data[6],
                                      json.loads(event_data[4]), event_data[3],
                                      event_data[2], event_data[5])
                    self._cache.set(cache_key, str(new_event))
                    output.append(json.loads(str(new_event)))
                else:
                    output.append(json.loads(event_data))
            return output
        except DatabaseException:
            raise EventLogException

    def update_quota(self, node: APIKey):
        try:
            self._db.update_quota(node.node_id)
        except DatabaseException:
            if self._logger:
                self._logger.error(
                    "Failed to update API rate quota for node id: {0}".format(
                        node.node_id))
示例#26
0
 def setUp(self):
     self._db = Database(logger, True)
示例#27
0
class TestEventTypeIdLogging(unittest.TestCase):
    def setUp(self):
        self._db = Database(logger, True)
        self._mock_data = dict()
        now = datetime.now()
        for each in DEFAULT_EVENTS:
            event_type_id = self._db.create_event_type(each)
            self.assertGreater(event_type_id,
                               0,
                               msg="Failed to create event type")
            mock_events = []
            for x in range(0, random.randint(10, 50)):
                mock_event_data = {
                    "floatMock": random.random(),
                    "datetimeMock": random_later_datetime().isoformat(),
                    "integerMock": random.randint(0, 1500000),
                    "stringMock": "a" * random.randint(0, 1024)
                }

                new_mock_event = Event(0, event_type_id, each, mock_event_data,
                                       0, 1, now)
                mock_events.append(new_mock_event)
            self._mock_data[each] = mock_events

    def test_logging(self):
        total_events_logged = 0
        event_type = random.choice(DEFAULT_EVENTS)
        mock_events = self._mock_data[event_type]
        event_type_id = None
        for each_mock in mock_events:
            if event_type_id is None:
                event_type_id = each_mock.event_type_id
            event_id = self._db.log_event(each_mock.event_data,
                                          each_mock.event_type_id,
                                          each_mock.node_id, each_mock.user_id)
            self.assertGreater(event_id, 0, msg="Failed to log event.")
            each_mock.event_id = event_id
        event_type_count = self._db.get_event_count(
            event_type_id=event_type_id)
        self.assertEqual(event_type_count, len(mock_events))
        logger.info("Events logged: {0} ({1})".format(event_type_count,
                                                      event_type))
        logger.info("Fetching events individually...")
        total_events_logged += event_type_count
        for each_mock in mock_events:
            db_event_data = self._db.get_event_data(each_mock.event_id)
            # DB: event_id, event_type_id, node_id, user_id, event_data, created, event_type.event_type
            self.assertEqual(db_event_data[1], each_mock.event_type_id)
            self.assertEqual(db_event_data[2], each_mock.node_id)
            self.assertEqual(db_event_data[3], each_mock.user_id)
            # db_event_data = json.loads(db_event_data[4])
            # self.assertEqual(each_mock.event_data["floatMock"], db_event_data["floatMock"])
            # self.assertEqual(db_event_data[6], each_event_type)
        logger.info("Retrieving all events of type in single query...")
        all_events_of_type = self._db.retrieve_events(
            event_type_id=event_type_id)
        mock_events_reversed = mock_events
        mock_events_reversed.reverse()
        # event_id, event_type_id, node_id, user_id, created
        for x in range(0, len(mock_events_reversed)):
            self.assertEqual(all_events_of_type[x][0],
                             mock_events_reversed[x].event_id)
            self.assertEqual(all_events_of_type[x][1],
                             mock_events_reversed[x].event_type_id)
            self.assertEqual(all_events_of_type[x][2],
                             mock_events_reversed[x].node_id)
            self.assertEqual(all_events_of_type[x][3],
                             mock_events_reversed[x].user_id)
        self.assertEqual(len(all_events_of_type), event_type_count)
        db_total_event_count = self._db.get_event_count()
        self.assertEqual(db_total_event_count, total_events_logged)
示例#28
0
 def __init__(self, environment, user_id, session_token, use_logger=None):
     self._db = Database(env=environment, logger=use_logger)
     self._session_token = session_token
     self._user_id = user_id
示例#29
0
class ConsoleUserManager(ConsoleMenu):
    MAIN_MENU_CHOICES = [
        "List Users", "Create User", "List Permissions for User",
        "Assign User Permission", "Revoke User Permission", "List Event Types",
        "Reset Password", "Back to Main Menu"
    ]

    def __init__(self, environment, user_id, session_token, use_logger=None):
        self._db = Database(env=environment, logger=use_logger)
        self._session_token = session_token
        self._user_id = user_id

    def main_menu(self):
        print("User Administration Menu\n")
        x = 1
        choices = ConsoleUserManager.MAIN_MENU_CHOICES
        for each in choices:
            print("{0}.) ".format(x) + each)
            x += 1

        choice = self.select_item(1, len(choices) + 1)

        if choice == 1:
            self.list_users()
        elif choice == 2:
            self.create_user()
        elif choice == 3:
            query_user_id = int(input("List permissions for user_id: "))
            self.list_permissions_for_user_id(query_user_id)
        elif choice == 4:
            query_user_id = int(
                input("Assign view-event-id permission for user_id: "))
            query_event_type_id = int(input("Event type id: "))
            self.assign_permission_for_user_id(query_user_id, "view",
                                               query_event_type_id)
        elif choice == 5:
            print("Not yet implemented.")
        elif choice == 6:
            event_types = db.list_event_types()
            print("ID\tEvent Type")
            for each_event in event_types:
                print("{0}\t{1}".format(each_event[0], each_event[1]))
        elif choice == 7:
            username = input("Reset password for user with email/username: "******"New password: "******"\nPress Enter to continue")
        self.main_menu()

    def reset_password(self, email, new_passwd):
        try:
            self._db.reset_password(email, new_passwd)
            print("Password successfully changed.")
        except DatabaseException:
            print("Database Exception: Could not change password.")

    def list_users(self):
        try:
            user_list = self._db.list_analyst_user_info()
            # user_id, email_address, full_name, last_logged_in
            print("User ID\tLogin/E-mail\tFull Name\tLast Logged In\n\n")
            for each_user in user_list:
                print("{0}\t{1}\t{2}\t{3}".format(each_user[0], each_user[1],
                                                  each_user[2], each_user[3]))
            print("\n\n")
        except DatabaseException:
            print("Database error.")

    def create_user(self, email=None, passwd=None, name=None):
        if email is None:
            email = input("E-mail address: ")
        if passwd is None:
            passwd = input("Password: "******"Name: ")

        try:
            new_user = self._db.create_user(email, passwd, name, "console")
            print("Created new user with ID: {0}".format(new_user[0]))
        except DatabaseException:
            print("Could not create a new user.")

    def list_permissions_for_user_id(self, uid):
        try:
            user_permissions = self._db.list_permissions_for_user_id(uid)
            print("ACL ID\tPermission\tEvent Type ID\tCreated\tRevoked\n")
            for each_permission in user_permissions:
                print("{0}\t{1}\t{2}\t{3}\t{4}".format(each_permission[0],
                                                       each_permission[2],
                                                       each_permission[1],
                                                       each_permission[6],
                                                       "NO"))
        except DatabaseException:
            print("Could not create a new user.")

    def assign_permission_for_user_id(self,
                                      uid,
                                      permission,
                                      event_type_id=None):
        if permission is "view-event-type" and event_type_id:
            event_type = None
            all_event_types = self._db.list_event_types()
            for each_event_type in all_event_types:
                if each_event_type[0] == event_type_id:
                    event_type = each_event_type[1]
                    break
            if event_type:
                logged_event_type_id = None
                for each_event_type in all_event_types:
                    if each_event_type[1] is "Add Permission":
                        logged_event_type_id = each_event_type[0]
                        break
                try:
                    event_id = self._db.log_event(
                        {
                            "assigned_by": "Administrator",
                            "ip_addr": "console",
                            "event_type": event_type,
                            "event_type_id": event_type_id
                        }, logged_event_type_id, 0, uid)
                    new_acl_id = self._db.assign_permission_for_user_id(
                        uid, permission, event_id, event_type_id)
                    print("Assigned new permission ID {0} to user_id {1}.".
                          format(new_acl_id, uid))
                except DatabaseException:
                    print("Could not assign a new permission.")

    def revoke_permission_for_user_id(self, uid, permission_id):
        pass
示例#30
0
        print(
            "Could not open the PicoEvent/config/config.json file for reading. Exiting."
        )
        sys.exit()

    logger = None
    if "console_logging_enabled" in config and config[
            "console_logging_enabled"]:
        if "console_log_file" in config:
            print("Logging to file: {0}".format(config["console_log_file"]))
            logger = setup_file_logging(config["console_log_file"])

    env = ConsoleEnvironment()

    context_manager = ConsoleMainMenuManager(env, logger)
    db = Database(env=env, logger=logger)
    session_id = None
    admin_user_id = -1

    def login_admin():
        attempts = 0
        while attempts < MAX_LOGIN_ATTEMPTS:
            password = input("admin password: "******"admin", password)
                return login_info[0]
            except DatabaseException:
                attempts += 1
                print(
                    "Login failed, try again. ({0} attempts remaining)".format(
                        MAX_LOGIN_ATTEMPTS - attempts))