#367 Allow limiting the users/groups to execute just particular raw_configs.
Merged 4 years ago by lsedlar. Opened 4 years ago by jkaluza.
jkaluza/odcs raw-config-key-auth  into  master

file modified
+19 -3
@@ -92,6 +92,17 @@ 

      which the compose must be finished, otherwise the compose is marked as

      ``failed``.

  

+ For example:

+ 

+ .. sourcecode:: none

+ 

+     RAW_CONFIG_URLS = {

+         "releng_fedora": {

+             "url": "https://pagure.io/pungi-fedora.git",

+             "config_filename": "fedora.conf"

+         }

+     }

+ 

  

  Enabling ``pungi-config-validate``

  -------------------------------------
@@ -144,13 +155,18 @@ 

  ---------------------------------------------------------

  

  This is done by setting the ``raw_config`` source_type in

- the ``allowed_clients`` ODCS option like this:

+ the ``allowed_clients`` as well as particular ``raw_config_keys`` in

+ the ODCS option like this:

  

  

  .. sourcecode:: none

  

      allowed_clients = {

-         "some_username": {"source_types": ["raw_config", ...]}

+         "some_username": {

+             "source_types": ["raw_config", ...],

+             "raw_config_keys": ["releng_fedora", ...]

+         }

      }

  

- 

+ If ``raw_config_keys`` is not specified, the user/group is able to generate

+ any ``raw_config`` compose.

@@ -40,7 +40,12 @@ 

      """

      for attr in attrs:

          if attr not in ret_attrs:

-             ret_attrs[attr] = getattr(conf, "allowed_%s" % attr, [])

+             # If raw_config_keys is not set, it means all the `raw_config_urls` keys

+             # are allowed for this client.

+             if attr == "raw_config_keys":

+                 ret_attrs[attr] = conf.raw_config_urls.keys()

+             else:

+                 ret_attrs[attr] = getattr(conf, "allowed_%s" % attr, [])

      return ret_attrs

  

  
@@ -96,6 +101,7 @@ 

        - sources - compose.source

        - arches - compose.arches

        - compose_types - compose.compose_type

+       - raw_config_keys - compose.source.split("#")[0]

  

      The decision whether the user is allowed or not is done based on

      conf.allowed_clients value.
@@ -133,6 +139,11 @@ 

              elif isinstance(values, six.string_types):

                  # `arches` and `sources` are white-space separated lists.

                  values = values.split(" ")

+             elif values is None:

+                 # If value is not set, it means it is not available for this compose

+                 # type and we need to skip its check later. Set the values to empty

+                 # list to do that.

+                 values = []

  

              for value in values:

                  allowed_values = attrs[name]

file modified
+10 -2
@@ -204,10 +204,16 @@ 

          else:

              sigkeys = old_compose.sigkeys

  

+         # Get the raw_config_key if this compose is RAW_CONFIG.

+         raw_config_key = None

+         if old_compose.source_type == PungiSourceType.RAW_CONFIG:

+             raw_config_key = old_compose.source.split("#")[0]

+ 

          raise_if_input_not_allowed(

              source_types=old_compose.source_type, sources=old_compose.source,

              results=old_compose.results, flags=old_compose.flags,

-             arches=old_compose.arches, compose_types=compose_type)

+             arches=old_compose.arches, compose_types=compose_type,

+             raw_config_keys=raw_config_key)

  

          has_to_create_a_copy = (

              old_compose.state in (COMPOSE_STATES['removed'], COMPOSE_STATES['failed']) or
@@ -318,6 +324,7 @@ 

              raise ValueError(err)

  

          # Validate `source` based on `source_type`.

+         raw_config_key = None

          if source_type == PungiSourceType.RAW_CONFIG:

              if len(source) > 1:

                  raise ValueError(
@@ -336,6 +343,7 @@ 

                  raise ValueError(

                      'Source "%s" does not exist in server configuration.' %

                      source_name)

+             raw_config_key = source_name

          elif source_type == PungiSourceType.MODULE:

              for module_str in source:

                  nsvc = module_str.split(":")
@@ -436,7 +444,7 @@ 

          raise_if_input_not_allowed(

              source_types=source_type, sources=source, results=results,

              flags=flags, arches=arches, compose_types=compose_type,

-             target_dirs=target_dir)

+             target_dirs=target_dir, raw_config_keys=raw_config_key)

  

          compose = Compose.create(

              db.session, self._get_compose_owner(), source_type, source,

file modified
+74 -1
@@ -121,7 +121,11 @@ 

                  'dev3': {

                      'source_types': ['tag'],

                      'target_dirs': ["releng-private"]

-                 }

+                 },

+                 'dev4': {

+                     'source_types': ['raw_config'],

+                     'raw_config_keys': ["pungi_cfg2"]

+                 },

              }

          }

          patched_admins = {'groups': ['admin'], 'users': ['root']}
@@ -703,6 +707,43 @@ 

          c = db.session.query(Compose).filter(Compose.id == 3).one()

          self.assertEqual(c.reused_id, None)

  

+     def test_submit_build_resurrection_not_allowed_raw_config_key(self):

+         self.c1.state = COMPOSE_STATES["removed"]

+         self.c1.reused_id = 1

+         self.c1.source_type = 5

+         self.c1.source = "pungi_cfg#hash"

+         db.session.commit()

+ 

+         with self.test_request_context(user='dev4'):

+             flask.g.oidc_scopes = [

+                 '{0}{1}'.format(conf.oidc_base_namespace, 'renew-compose')

+             ]

+ 

+             rv = self.client.patch('/api/1/composes/1')

+             data = json.loads(rv.get_data(as_text=True))

+ 

+         self.assertEqual(

+             data["message"],

+             "User dev4 not allowed to operate with compose with raw_config_keys=pungi_cfg.")

+ 

+     def test_submit_build_resurrection_allowed_raw_config_key(self):

+         self.c1.state = COMPOSE_STATES["removed"]

+         self.c1.reused_id = 1

+         self.c1.source_type = 5

+         self.c1.source = "pungi_cfg2#hash"

+         db.session.commit()

+ 

+         with self.test_request_context(user='dev4'):

+             flask.g.oidc_scopes = [

+                 '{0}{1}'.format(conf.oidc_base_namespace, 'renew-compose')

+             ]

+ 

+             rv = self.client.patch('/api/1/composes/1')

+             data = json.loads(rv.get_data(as_text=True))

+ 

+         self.assertEqual(data['id'], 3)

+         self.assertEqual(data['state_name'], 'wait')

+ 

      def test_submit_build_resurrection_failed(self):

          self.c1.state = COMPOSE_STATES["failed"]

          self.c1.reused_id = 1
@@ -824,6 +865,38 @@ 

              data['message'],

              'User dev2 not allowed to operate with compose with compose_types=production.')

  

+     @patch.object(odcs.server.config.Config, 'raw_config_urls',

+                   new={"pungi_cfg": "http://localhost/pungi.conf#%s"})

+     def test_submit_build_not_allowed_raw_config_key(self):

+         with self.test_request_context(user='dev4'):

+             flask.g.oidc_scopes = [

+                 '{0}{1}'.format(conf.oidc_base_namespace, 'new-compose')

+             ]

+ 

+             rv = self.client.post('/api/1/composes/', data=json.dumps(

+                 {'source': {'type': 'raw_config', 'source': 'pungi_cfg#hash'},

+                  'compose_type': 'production'}))

+             data = json.loads(rv.get_data(as_text=True))

+ 

+         self.assertEqual(

+             data['message'],

+             'User dev4 not allowed to operate with compose with raw_config_keys=pungi_cfg.')

+ 

+     @patch.object(odcs.server.config.Config, 'raw_config_urls',

+                   new={"pungi_cfg2": "http://localhost/pungi.conf#%s"})

+     def test_submit_build_allowed_raw_config_key(self):

+         with self.test_request_context(user='dev4'):

+             flask.g.oidc_scopes = [

+                 '{0}{1}'.format(conf.oidc_base_namespace, 'new-compose')

+             ]

+ 

+             rv = self.client.post('/api/1/composes/', data=json.dumps(

+                 {'source': {'type': 'raw_config', 'source': 'pungi_cfg2#hash'},

+                  'compose_type': 'production'}))

+             data = json.loads(rv.get_data(as_text=True))

+ 

+         self.assertEqual(data["source"], "pungi_cfg2#hash")

+ 

      def test_submit_build_unknown_source_type(self):

          with self.test_request_context(user='dev'):

              flask.g.oidc_scopes = [

This commit adds new raw_config_keys option to allowed_clients
and allowed_groups options to configure allowed raw_config
composes for this user/group.

If not set, the current behaviour is respected and any raw_config
compose can be generated.

Typo here: keyes → keys

Other than the merge conflict it looks good to me.

rebased onto 69ade86

4 years ago

Pull-Request has been merged by lsedlar

4 years ago