Exemple #1
0
def verify_password(username_or_token, password):
    """Verify the user name and password.

    Instead of a user name an authentication token
    or an API token can be provided.
    This function is called by the
    @auth.login_required decorator.

    Args:
        username_or_token (str): The username or an authentication token
        password (str): The optional user password, not required in case of token

    Returns:
        bool: True if authorized or False if not

    """
    # first try to authenticate by token
    user = ActiniaUser.verify_auth_token(username_or_token)

    if not user:
        user = ActiniaUser.verify_api_key(username_or_token)

    if not user:
        # try to authenticate with username/password
        user = ActiniaUser(user_id=username_or_token)
        if not user.exists() or not user.verify_password(password):
            return False
    # Store the user globally
    g.user = user
    return True
    def delete(self, user_id):
        """Delete a specific user

        These methods work only if the
        authorized user has an admin role.

        Args:
            user_id (str): The unique name of the user

        Returns:
            flask.Response: A HTTP response with
                            JSON payload containing
                            the status and messages
        """
        user = ActiniaUser(user_id)

        if user.exists() != 1:
            return make_response(jsonify(SimpleResponseModel(
                status="error",
                message="Unable to delete user %s. User does not exist." % user_id
            )), 400)

        if user.delete() is True:
            return make_response(jsonify(SimpleResponseModel(
                status="success",
                message="User %s deleted" % user_id
            )), 200)

        return make_response(jsonify(SimpleResponseModel(
            status="error",
            message="Unable to delete user %s" % user_id
        )), 400)
    def get(self, user_id):
        """Return the credentials of a single user

        These methods work only if the
        authorized user has an admin role.

        Args:
            user_id (str): The unique name of the user

        Returns:
            flask.Response: A HTTP response with
                            JSON payload containing the credentials
                            of the user
        """
        user = ActiniaUser(user_id)

        if user.exists() != 1:
            return make_response(jsonify(SimpleResponseModel(
                status="error",
                message="User <%s> does not exist" % user_id
            )), 400)

        credentials = user.get_credentials()

        return make_response(jsonify(UserInfoResponseModel(
            status="success",
            permissions=credentials["permissions"],
            user_id=credentials["user_id"],
            user_role=credentials["user_role"],
            user_group=credentials["user_group"]
        )), 200)
Exemple #4
0
    def create_user(cls,
                    name="guest",
                    role="guest",
                    group="group",
                    password="******",
                    accessible_datasets=None,
                    process_num_limit=1000,
                    process_time_limit=6000):

        auth = bytes('%s:%s' % (name, password), "utf-8")

        # We need to create an HTML basic authorization header
        cls.auth_header[role] = Headers()
        cls.auth_header[role].add('Authorization',
                                  'Basic ' + base64.b64encode(auth).decode())

        # Make sure the user database is empty
        user = ActiniaUser(name)
        if user.exists():
            user.delete()
        # Create a user in the database
        user = ActiniaUser.create_user(name,
                                       group,
                                       password,
                                       user_role=role,
                                       accessible_datasets=accessible_datasets,
                                       process_num_limit=process_num_limit,
                                       process_time_limit=process_time_limit)
        user.add_accessible_modules(["uname", "sleep"])
        cls.users_list.append(user)

        return name, group, cls.auth_header[role]
Exemple #5
0
    def test_superadmin_termination(self):
        """Test the termination of one running resources from superadmin user
        """

        # Create a random test user id that are used for login as admin
        user_id = "horst" + str(randint(0, 10000000))
        user_group = self.user_group
        password = "******"

        # We need to create an HTML basic authorization header
        auth_header = Headers()
        auth = bytes('%s:%s' % (user_id, password), "utf-8")
        auth_header.add('Authorization',
                        'Basic ' + base64.b64encode(auth).decode())

        # Make sure the user database is empty
        user = ActiniaUser(user_id)
        if user.exists():
            user.delete()
        # Create a user in the database and reduce its credentials
        self.user = ActiniaUser.create_user(
            user_id,
            user_group,
            password,
            user_role="superadmin",
            accessible_datasets={
                "nc_spm_08": ["PERMANENT", "user1", "landsat", "test_mapset"],
                "ECAD": ["PERMANENT"]
            },
            process_num_limit=3,
            process_time_limit=100)

        # Start three processes that will be terminated
        rv = self.server.post(URL_PREFIX + '/custom_process/sleep',
                              headers=auth_header,
                              data=json_dumps(["20"]),
                              content_type="application/json")

        # Test guest termination error
        rv = self.server.delete(URL_PREFIX + '/resources/%s' % user_id,
                                headers=self.guest_auth_header)
        print(rv.data.decode())
        self.assertEqual(rv.status_code, 401,
                         "HTML status code is wrong %i" % rv.status_code)
        # self.assertEqual(rv.mimetype, "application/json", "Wrong mimetype %s" % rv.mimetype)

        # Test user termination error
        rv = self.server.delete(URL_PREFIX + '/resources/%s' % user_id,
                                headers=self.user_auth_header)
        print(rv.data.decode())
        self.assertEqual(rv.status_code, 401,
                         "HTML status code is wrong %i" % rv.status_code)
        # self.assertEqual(rv.mimetype, "application/json", "Wrong mimetype %s" % rv.mimetype)

        # Test admin termination error
        rv = self.server.delete(URL_PREFIX + '/resources/%s' % user_id,
                                headers=self.admin_auth_header)
        print(rv.data.decode())
        self.assertEqual(rv.status_code, 401,
                         "HTML status code is wrong %i" % rv.status_code)
        # self.assertEqual(rv.mimetype, "application/json", "Wrong mimetype %s" % rv.mimetype)

        # Test superadmin termination success
        rv = self.server.delete(URL_PREFIX + '/resources/%s' % user_id,
                                headers=self.root_auth_header)
        print(rv.data.decode())
        self.assertEqual(rv.status_code, 200,
                         "HTML status code is wrong %i" % rv.status_code)
        self.assertEqual(rv.mimetype, "application/json",
                         "Wrong mimetype %s" % rv.mimetype)

        # Wait for termination
        time.sleep(5)

        rv = self.server.get(URL_PREFIX + '/resources/%s' % user_id,
                             headers=auth_header)
        print(rv.data.decode())
        self.assertEqual(rv.status_code, 200,
                         "HTML status code is wrong %i" % rv.status_code)
        self.assertEqual(rv.mimetype, "application/json",
                         "Wrong mimetype %s" % rv.mimetype)

        resource_list = json_loads(rv.data)["resource_list"]
        self.assertTrue(len(resource_list) == 1)

        # Count return stats
        terminated = 0
        for resource in resource_list:
            terminated += int(resource["status"] == "terminated")
            print(resource["status"])

        self.assertTrue(terminated == 1)
Exemple #6
0
    def test_user_status_requests_1(self):
        """Resource list with 3 finished resources
        """

        # Create a random test user id that are used for login as admin
        user_id = "heinz" + str(randint(0, 10000000))
        user_group = self.user_group
        password = "******"

        # We need to create an HTML basic authorization header
        auth_header = Headers()
        auth = bytes('%s:%s' % (user_id, password), "utf-8")
        auth_header.add('Authorization',
                        'Basic ' + base64.b64encode(auth).decode())

        # Make sure the user database is empty
        user = ActiniaUser(user_id)
        if user.exists():
            user.delete()
        # Create a user in the database and reduce its credentials
        self.user = ActiniaUser.create_user(
            user_id,
            user_group,
            password,
            user_role="user",
            accessible_datasets={
                "nc_spm_08":
                ["PERMANENT", "user1", "landsat", "modis_lst", "test_mapset"],
                "ECAD": ["PERMANENT"]
            },
            process_num_limit=3,
            process_time_limit=2)

        # Create three successfully run resources
        rv = self.server.post(URL_PREFIX + '/custom_process/uname',
                              headers=auth_header,
                              data=json_dumps(["-a"]),
                              content_type="application/json")
        self.waitAsyncStatusAssertHTTP(rv, headers=self.admin_auth_header)

        rv = self.server.post(URL_PREFIX + '/custom_process/uname',
                              headers=auth_header,
                              data=json_dumps(["-a"]),
                              content_type="application/json")
        self.waitAsyncStatusAssertHTTP(rv, headers=self.admin_auth_header)

        rv = self.server.post(URL_PREFIX + '/custom_process/uname',
                              headers=auth_header,
                              data=json_dumps(["-a"]),
                              content_type="application/json")
        self.waitAsyncStatusAssertHTTP(rv, headers=self.admin_auth_header)

        rv = self.server.get(URL_PREFIX + '/resources/%s' % user_id,
                             headers=auth_header)
        # print(rv.data.decode())
        self.assertEqual(rv.status_code, 200,
                         "HTML status code is wrong %i" % rv.status_code)
        self.assertEqual(rv.mimetype, "application/json",
                         "Wrong mimetype %s" % rv.mimetype)

        resource_list = json_loads(rv.data)["resource_list"]

        pprint(resource_list)

        self.assertTrue(len(resource_list) == 3)

        # Count return stats
        finished = 0
        for resource in resource_list:
            finished += int(resource["status"] == "finished")
            # print(resource["status"])

        self.assertTrue(finished == 3)

        # Check the different resource list parameters
        rv = self.server.get(URL_PREFIX + '/resources/%s?num=1' % user_id,
                             headers=auth_header)
        self.assertTrue(len(json_loads(rv.data)["resource_list"]) == 1)

        rv = self.server.get(URL_PREFIX + '/resources/%s?num=2' % user_id,
                             headers=auth_header)
        self.assertTrue(len(json_loads(rv.data)["resource_list"]) == 2)

        rv = self.server.get(URL_PREFIX +
                             '/resources/%s?num=2&type=finished' % user_id,
                             headers=auth_header)
        self.assertTrue(len(json_loads(rv.data)["resource_list"]) == 2)

        rv = self.server.get(URL_PREFIX +
                             '/resources/%s?num=2&type=all' % user_id,
                             headers=auth_header)
        self.assertTrue(len(json_loads(rv.data)["resource_list"]) == 2)

        rv = self.server.get(URL_PREFIX + '/resources/%s?type=all' % user_id,
                             headers=auth_header)
        self.assertTrue(len(json_loads(rv.data)["resource_list"]) == 3)

        rv = self.server.get(URL_PREFIX +
                             '/resources/%s?type=finished' % user_id,
                             headers=auth_header)
        self.assertTrue(len(json_loads(rv.data)["resource_list"]) == 3)

        rv = self.server.get(URL_PREFIX +
                             '/resources/%s?type=terminated' % user_id,
                             headers=auth_header)
        self.assertTrue(len(json_loads(rv.data)["resource_list"]) == 0)

        rv = self.server.get(URL_PREFIX +
                             '/resources/%s?type=unknown' % user_id,
                             headers=auth_header)
        self.assertTrue(len(json_loads(rv.data)["resource_list"]) == 0)

        # Check permission access using the default users

        rv = self.server.get(URL_PREFIX + '/resources/%s' % user_id,
                             headers=self.guest_auth_header)
        # print(rv.data.decode())
        self.assertEqual(rv.status_code, 401,
                         "HTML status code is wrong %i" % rv.status_code)
        # self.assertEqual(rv.mimetype, "application/json", "Wrong mimetype %s" % rv.mimetype)

        rv = self.server.get(URL_PREFIX + '/resources/%s' % user_id,
                             headers=self.user_auth_header)
        # print(rv.data.decode())
        self.assertEqual(rv.status_code, 401,
                         "HTML status code is wrong %i" % rv.status_code)
        # self.assertEqual(rv.mimetype, "application/json", "Wrong mimetype %s" % rv.mimetype)

        rv = self.server.get(URL_PREFIX + '/resources/%s' % user_id,
                             headers=self.admin_auth_header)
        # print(rv.data.decode())
        self.assertEqual(rv.status_code, 200,
                         "HTML status code is wrong %i" % rv.status_code)
        # self.assertEqual(rv.mimetype, "application/json", "Wrong mimetype %s" % rv.mimetype)

        rv = self.server.get(URL_PREFIX + '/resources/%s' % user_id,
                             headers=self.root_auth_header)
        # print(rv.data.decode())
        self.assertEqual(rv.status_code, 200,
                         "HTML status code is wrong %i" % rv.status_code)
Exemple #7
0
    def test_user_status_requests_3(self):
        """Empty resource list test
        """

        # Create a random test user id that are used for login as admin
        user_id = "heinz" + str(randint(0, 10000000))
        user_group = "test"
        password = "******"

        # We need to create an HTML basic authorization header
        auth_header = Headers()
        auth = bytes('%s:%s' % (user_id, password), "utf-8")
        auth_header.add('Authorization',
                        'Basic ' + base64.b64encode(auth).decode())

        # Make sure the user database is empty
        user = ActiniaUser(user_id)
        if user.exists():
            user.delete()
        # Create a user in the database and reduce its credentials
        self.user = ActiniaUser.create_user(user_id, user_group, password)

        rv = self.server.get(URL_PREFIX + '/resources/%s' % user_id,
                             headers=auth_header)
        print(rv.data.decode())
        self.assertEqual(rv.status_code, 200,
                         "HTML status code is wrong %i" % rv.status_code)
        self.assertEqual(rv.mimetype, "application/json",
                         "Wrong mimetype %s" % rv.mimetype)

        resource_list = json_loads(rv.data)["resource_list"]
        self.assertTrue(len(resource_list) == 0)

        # Check permission access using the default users

        rv = self.server.get(URL_PREFIX + '/resources/%s' % user_id,
                             headers=self.guest_auth_header)
        print(rv.data.decode())
        self.assertEqual(rv.status_code, 401,
                         "HTML status code is wrong %i" % rv.status_code)
        # self.assertEqual(rv.mimetype, "application/json", "Wrong mimetype %s" % rv.mimetype)

        rv = self.server.get(URL_PREFIX + '/resources/%s' % user_id,
                             headers=self.user_auth_header)
        print(rv.data.decode())
        self.assertEqual(rv.status_code, 401,
                         "HTML status code is wrong %i" % rv.status_code)
        # self.assertEqual(rv.mimetype, "application/json", "Wrong mimetype %s" % rv.mimetype)

        rv = self.server.get(URL_PREFIX + '/resources/%s' % user_id,
                             headers=self.admin_auth_header)
        print(rv.data.decode())
        self.assertEqual(rv.status_code, 401,
                         "HTML status code is wrong %i" % rv.status_code)
        # self.assertEqual(rv.mimetype, "application/json", "Wrong mimetype %s" % rv.mimetype)

        rv = self.server.get(URL_PREFIX + '/resources/%s' % user_id,
                             headers=self.root_auth_header)
        print(rv.data.decode())
        self.assertEqual(rv.status_code, 200,
                         "HTML status code is wrong %i" % rv.status_code)
        self.assertEqual(rv.mimetype, "application/json",
                         "Wrong mimetype %s" % rv.mimetype)
    def test_create_delete_user(self):

        # Make sure the user database is empty
        user = ActiniaUser(self.user_id)
        if user.exists():
            print("Delete existing user")
            user.delete()

        # Create a new user
        user = ActiniaUser.create_user(self.user_id,
                                       self.user_group,
                                       self.password,
                                       user_role="admin",
                                       accessible_datasets={"nc_spm_08": ["PERMANENT", "user1"]},
                                       accessible_modules=["g.region", "g.mapset", "r.slope.aspect"],
                                       cell_limit=1000,
                                       process_num_limit=3,
                                       process_time_limit=30)

        print(user)

        self.assertEqual(user.get_role(), "admin")
        self.assertEqual(user.get_id(), self.user_id)
        self.assertEqual(user.get_group(), self.user_group)
        self.assertEqual(user.get_cell_limit(), 1000)
        self.assertEqual(user.get_process_num_limit(), 3)
        self.assertEqual(user.get_process_time_limit(), 30)

        datasets = user.get_accessible_datasets()
        modules = user.get_accessible_modules()

        self.assertTrue("nc_spm_08" in datasets)
        self.assertTrue("PERMANENT" in datasets["nc_spm_08"])
        self.assertTrue("g.region" in modules)

        token = user.generate_auth_token()
        user_2 = ActiniaUser.verify_auth_token(token)

        print(user_2)

        self.assertTrue(user_2.exists())
        self.assertEqual(user_2.get_role(), "admin")
        self.assertEqual(user_2.get_id(), self.user_id)
        self.assertEqual(user.get_group(), self.user_group)
        self.assertEqual(user_2.get_cell_limit(), 1000)
        self.assertEqual(user_2.get_process_num_limit(), 3)
        self.assertEqual(user_2.get_process_time_limit(), 30)

        datasets = user_2.get_accessible_datasets()
        modules = user_2.get_accessible_modules()

        self.assertTrue("nc_spm_08" in datasets)
        self.assertTrue("PERMANENT" in datasets["nc_spm_08"])
        self.assertTrue("g.region" in modules)

        api_key = user.generate_api_key()
        user_3 = ActiniaUser.verify_api_key(api_key)

        print(user_3)

        self.assertTrue(user_3.exists())
        self.assertEqual(user_3.get_role(), "admin")
        self.assertEqual(user_3.get_id(), self.user_id)
        self.assertEqual(user.get_group(), self.user_group)
        self.assertEqual(user_3.get_cell_limit(), 1000)
        self.assertEqual(user_3.get_process_num_limit(), 3)
        self.assertEqual(user_3.get_process_time_limit(), 30)

        datasets = user_3.get_accessible_datasets()
        modules = user_3.get_accessible_modules()

        self.assertTrue("nc_spm_08" in datasets)
        self.assertTrue("PERMANENT" in datasets["nc_spm_08"])
        self.assertTrue("g.region" in modules)

        self.assertTrue(user.delete())
        self.assertFalse(user_2.delete())
        self.assertFalse(user_3.delete())
    def test_create_update_user(self):
        """Test the creation and update of a user in the redis database
        """

        user = ActiniaUser(self.user_id)
        if user.exists():
            print("Delete existing user")
            user.delete()

        # Create a new user
        user = ActiniaUser.create_user(self.user_id,
                                       self.user_group,
                                       self.password,
                                       user_role="admin",
                                       accessible_datasets={"nc_spm_08": ["PERMANENT", "user1"]},
                                       accessible_modules=["g.region", "g.mapset", "r.slope.aspect"],
                                       cell_limit=1000,
                                       process_num_limit=3,
                                       process_time_limit=30)

        print(user)

        self.assertEqual(user.get_role(), "admin")
        self.assertEqual(user.get_id(), self.user_id)
        self.assertEqual(user.get_group(), self.user_group)
        self.assertEqual(user.get_cell_limit(), 1000)
        self.assertEqual(user.get_process_num_limit(), 3)
        self.assertEqual(user.get_process_time_limit(), 30)

        datasets = user.get_accessible_datasets()

        self.assertTrue("nc_spm_08" in datasets)
        self.assertTrue("PERMANENT" in datasets["nc_spm_08"])

        user = ActiniaUser(user_id=self.user_id)
        user.read_from_db()
        user.set_role("user")
        user.set_cell_limit(1000000)
        user.set_process_num_limit(10)
        user.set_process_time_limit(50)
        user.update()

        print(user)

        self.assertEqual(user.get_role(), "user")
        self.assertEqual(user.get_cell_limit(), 1000000)
        self.assertEqual(user.get_process_num_limit(), 10)
        self.assertEqual(user.get_process_time_limit(), 50)

        user = ActiniaUser(user_id=self.user_id)
        user.read_from_db()
        user.add_accessible_dataset("utm32n", ["PERMANENT"])
        user.add_accessible_modules(["i.vi", ])
        user.update()

        print(user)

        datasets = user.get_accessible_datasets()
        modules = user.get_accessible_modules()

        self.assertTrue("nc_spm_08" in datasets)
        self.assertTrue("PERMANENT" in datasets["nc_spm_08"])
        self.assertTrue("g.region" in modules)
        self.assertTrue("utm32n" in datasets)
        self.assertTrue("PERMANENT" in datasets["utm32n"])
        self.assertTrue("i.vi" in modules)

        user = ActiniaUser(user_id=self.user_id)
        user.read_from_db()
        user.remove_location("utm32n")
        user.remove_mapsets_from_location("nc_spm_08", ["user1", ])
        user.remove_accessible_modules(["i.vi", ])
        user.update()

        print(user)

        datasets = user.get_accessible_datasets()
        modules = user.get_accessible_modules()

        self.assertTrue("nc_spm_08" in datasets)
        self.assertTrue("PERMANENT" in datasets["nc_spm_08"])
        self.assertFalse("user1" in datasets["nc_spm_08"])
        self.assertTrue("g.region" in modules)
        self.assertFalse("utm32n" in datasets)
        self.assertFalse("i.vi" in modules)
Exemple #10
0
    def check_permissions(self, user_id):
        """Check the access rights of the user that calls this API call

        Permission:
            - guest and user roles can only access resources of the same user id
            - admin role are allowed to access resources of users with the same
              user group, except for superusers
            - superdamins role can access all resources

        Args:
            user_id:

        Returns:
            None if permissions granted, a error response if permissions are
            not fulfilled

        """
        # Superuser are allowed to do everything
        if self.user.has_superadmin_role() is True:
            return None

        # Check permissions for users and guests
        if self.user_role == "guest" or self.user_role == "user":
            if self.user_id != user_id:
                return make_response(
                    jsonify(
                        SimpleResponseModel(
                            status="error",
                            message=
                            "You do not have the permission to access this resource. "
                            "Wrong user.")), 401)
        new_user = ActiniaUser(user_id=user_id)

        # Check if the user exists
        if new_user.exists() != 1:
            return make_response(
                jsonify(
                    SimpleResponseModel(
                        status="error",
                        message="The user <%s> does not exist" % user_id)),
                400)

        # Check admin permissions
        if self.user_role == "admin":
            # Resources of superusers are not allowed to be accessed
            if new_user.has_superadmin_role() is True:
                return make_response(
                    jsonify(
                        SimpleResponseModel(
                            status="error",
                            message=
                            "You do not have the permission to access this resource. "
                            "Wrong user role.")), 401)
            # Only resources of the same user group are allowed to be accessed
            if new_user.get_group() != self.user_group:
                return make_response(
                    jsonify(
                        SimpleResponseModel(
                            status="error",
                            message=
                            "You do not have the permission to access this resource. "
                            "Wrong user group.")), 401)
        return None