Merge pull request #7609 from VJalili/cloudauthz_post

Add a PUT api for CloudAuthz
This commit is contained in:
John Chilton
2019-04-09 10:35:16 -04:00
committed by GitHub
3 changed files with 135 additions and 2 deletions
+61 -1
View File
@@ -1,10 +1,14 @@
"""
Manager and serializer for cloud authorizations (cloudauthzs).
Manager and (de)serializer for cloud authorizations (cloudauthzs).
"""
import logging
from galaxy import model
from galaxy.exceptions import (
InternalServerError,
MalformedId
)
from galaxy.managers import base
from galaxy.managers import sharable
@@ -61,3 +65,59 @@ class CloudAuthzsSerializer(base.ModelSerializer):
'last_activity': lambda i, k, **c: str(i.last_activity),
'create_time' : lambda i, k, **c: str(i.create_time)
})
class CloudAuthzsDeserializer(base.ModelDeserializer):
"""
Service object for validating and deserializing dictionaries that
update/alter cloudauthz configurations.
"""
model_manager_class = CloudAuthzManager
def add_deserializers(self):
super(CloudAuthzsDeserializer, self).add_deserializers()
self.deserializers.update({
'authn_id': self.deserialize_and_validate_authn_id,
'provider': self.default_deserializer,
'config': self.default_deserializer,
'deleted': self.default_deserializer
})
def deserialize_and_validate_authn_id(self, item, key, val, **context):
"""
Deserializes an authentication ID (authn_id), and asserts if the
current user can assume that authentication.
:type item: galaxy.model.CloudAuthz
:param item: an instance of cloudauthz
:type key: string
:param key: `authn_id` attribute of the cloudauthz object (i.e., the `item` param).
:type val: string
:param val: the value of `authn_id` attribute of the cloudauthz object (i.e., the `item` param).
:type context: dict
:param context: a dictionary object containing Galaxy `trans`.
:rtype: string
:return: decoded authentication ID.
"""
try:
decoded_authn_id = self.app.security.decode_id(val)
except Exception:
log.debug("cannot decode authz_id `" + str(val) + "`")
raise MalformedId("Invalid `authz_id` {}!".format(val))
trans = context.get("trans")
if trans is None:
log.debug("Not found expected `trans` when deserializing CloudAuthz.")
raise InternalServerError
try:
trans.app.authnz_manager.can_user_assume_authn(trans, decoded_authn_id)
except Exception as e:
raise e
return decoded_authn_id
+68 -1
View File
@@ -35,6 +35,7 @@ class CloudAuthzController(BaseAPIController):
super(CloudAuthzController, self).__init__(app)
self.cloudauthz_manager = cloudauthzs.CloudAuthzManager(app)
self.cloudauthz_serializer = cloudauthzs.CloudAuthzsSerializer(app)
self.cloudauthz_deserializer = cloudauthzs.CloudAuthzsDeserializer(app)
@expose_api
def index(self, trans, **kwargs):
@@ -68,13 +69,18 @@ class CloudAuthzController(BaseAPIController):
:type payload: dict
:param payload: A dictionary structure containing the following keys:
* provider: the cloud-based resource provider to which this configuration belongs to.
* config: a dictionary containing all the configuration required to request temporary credentials
from the provider.
from the provider. See the following page for details:
https://galaxyproject.org/cloud/authnz/
* authn_id: the (encoded) ID of a third-party authentication of a user. To have this ID, user must
have logged-in to this Galaxy server using third-party identity (e.g., Google), or has
associated his/her Galaxy account with a third-party OIDC-based identity. See this page:
https://galaxyproject.org/admin/authentication/
* description: [Optional] a brief description for this configuration.
:param kwargs: empty dict
:rtype: dict
@@ -183,3 +189,64 @@ class CloudAuthzController(BaseAPIController):
"ID: `{}`.".format(encoded_authz_id)))
raise InternalServerError('An unexpected error has occurred while responding to the DELETE request of the '
'cloudauthz API.' + str(e))
@expose_api
def update(self, trans, encoded_authz_id, payload, **kwargs):
"""
* PUT /api/cloud/authz/{encoded_authz_id}
Updates the values for the cloudauthz configuration with the given ``encoded_authz_id``.
With this API only the following attributes of a cloudauthz configuration
can be updated: `authn_id`, `provider`, `config`, `deleted`.
:type trans: galaxy.web.framework.webapp.GalaxyWebTransaction
:param trans: Galaxy web transaction
:type encoded_authz_id: string
:param encoded_authz_id: The encoded ID of the CloudAuthz record to be updated.
:type payload: dict
:param payload: A dictionary structure containing the attributes to modified with their new values.
It can contain any number of the following attributes:
* provider: the cloud-based resource provider
to which this configuration belongs to.
* authn_id: the (encoded) ID of a third-party authentication of a user.
To have this ID, user must have logged-in to this Galaxy server
using third-party identity (e.g., Google), or has associated
their Galaxy account with a third-party OIDC-based identity.
See this page: https://galaxyproject.org/admin/authentication/
Note: A user can associate a cloudauthz record with their own
authentications only. If the given authentication with authn_id
belongs to a different user, Galaxy will throw the
ItemAccessibilityException exception.
* config: a dictionary containing all the configuration required to
request temporary credentials from the provider.
See the following page for details:
https://galaxyproject.org/cloud/authnz/
* deleted: a boolean type marking the specified cloudauthz as (un)deleted.
"""
msg_template = "Rejected user `" + str(trans.user.id) + "`'s request to delete cloudauthz config because of {}."
try:
authz_id = self.decode_id(encoded_authz_id)
except Exception:
log.debug(msg_template.format("cannot decode authz_id `" + str(encoded_authz_id) + "`"))
raise MalformedId('Invalid `authz_id`!')
try:
cloudauthz_to_update = trans.app.authnz_manager.try_get_authz_config(trans.sa_session, trans.user.id, authz_id)
self.cloudauthz_deserializer.deserialize(cloudauthz_to_update, payload, trans=trans)
self.cloudauthz_serializer.serialize_to_view(cloudauthz_to_update, view='summary')
return self.cloudauthz_serializer.serialize_to_view(cloudauthz_to_update, view='summary')
except MalformedId as e:
raise e
except Exception as e:
log.exception(msg_template.format("exception while updating the cloudauthz record with "
"ID: `{}`.".format(encoded_authz_id)))
raise InternalServerError('An unexpected error has occurred while responding to the PUT request of the '
'cloudauthz API.' + str(e))
+6
View File
@@ -315,6 +315,12 @@ def populate_api_routes(webapp, app):
controller='cloudauthz',
conditions=dict(method=["DELETE"]))
webapp.mapper.connect('upload_cloudauthz_item',
'/api/cloud/authz/{encoded_authz_id}',
action='update',
controller="cloudauthz",
conditions=dict(method=["PUT"]))
webapp.mapper.connect('get_custom_builds_metadata',
'/api/histories/{id}/custom_builds_metadata',
controller='histories',