From 1d57437ec0b87357504db0d50c2a921625f24edd Mon Sep 17 00:00:00 2001 From: Tanner Prestegard <tanner.prestegard@ligo.org> Date: Mon, 29 Oct 2018 13:09:54 -0500 Subject: [PATCH] Consolidate APIs into a single endpoint We now have a single API endpoint, /api/, which can handle all authentication methods directed to it. The /apibasic/ and /apiweb/ URLs will probably be maintained for legacy reasons, but will not include any additional logic (they will just be carbon-copies of /api/ under a different namespace). --- config/urls.py | 8 +- docs/user_docs/source/auth.rst | 23 ++-- docs/user_docs/source/lvem.rst | 4 +- docs/user_docs/source/rest.rst | 8 +- gracedb/api/backends.py | 11 +- gracedb/api/utils.py | 119 +++++++----------- gracedb/api/versioning.py | 17 ++- gracedb/events/buildVOEvent.py | 22 ++-- gracedb/events/permission_utils.py | 9 -- gracedb/events/views.py | 2 +- gracedb/superevents/buildVOEvent.py | 23 ++-- gracedb/superevents/mixins.py | 2 +- gracedb/superevents/models.py | 2 +- .../templates/gracedb/event_detail_script.js | 10 +- gracedb/templates/gracedb/index.html | 2 +- .../templates/profile/manage_password.html | 2 +- gracedb/templates/superevents/detail.html | 16 +-- gracedb/templates/superevents/file_list.html | 2 +- .../superevents/superevent_detail_script.js | 14 +-- 19 files changed, 129 insertions(+), 167 deletions(-) diff --git a/config/urls.py b/config/urls.py index 7b6630f1a..1d3db0dc0 100644 --- a/config/urls.py +++ b/config/urls.py @@ -55,10 +55,10 @@ urlpatterns = [ url(r'^search/$', search.views.search, name="mainsearch"), # API URLs - url(r'^apibasic/', include('api.urls', namespace="basic")), - url(r'^apiweb/', include('api.urls', namespace="shib")), - url(r'^api/', include('api.urls', namespace="x509")), - #url(r'^apinew/', include('api.urls')), # one place for all auth schemes + url(r'^api/', include('api.urls')), + # Legacy API URLs: can we get rid of these at some point? (TODO) + url(r'^apibasic/', include('api.urls', namespace='legacy_apibasic')), + url(r'^apiweb/', include('api.urls', namespace='legacy_apiweb')), # Uncomment the admin/doc line below and add 'django.contrib.admindocs' # to INSTALLED_APPS to enable admin documentation: diff --git a/docs/user_docs/source/auth.rst b/docs/user_docs/source/auth.rst index d39e13b72..216f05f6f 100644 --- a/docs/user_docs/source/auth.rst +++ b/docs/user_docs/source/auth.rst @@ -7,21 +7,17 @@ Authentication and Authorization Authentication methods ======================================== -GraceDB supports three different types of authentication methods depending -on the entry point: +GraceDB supports three different types of authentication methods depending on the entry point: -- **Web Interface**: ``gracedb.ligo.org/`` supports Shibboleth with +- **Web interface**: ``gracedb.ligo.org/`` supports Shibboleth with federated identities. -- **REST API**: The API has three entry points: - - **X509**: ``gracedb.ligo.org/api/`` - - **Shibboleth**: ``gracedb.ligo.org/apiweb/`` - - **Basic**: ``gracedb.ligo.org/apibasic/`` +- **REST API**: The API has a single entry point which can handle the following types of authentication: + - **Shibboleth** + - **X509** + - **Basic (password-based)** -The X509 URL listed above is the default for the Python client. But users -with robot Kerberos keytabs will want to point to the Shibboleth URL. -(The same URL can also be accessed with a web browser to browse the API.) -Similarly, LV-EM users accessing the API will want to point to the URL -for basic auth. +Unauthenticated, read-only access is also available for both the web interface and the API. +Only a limited set of information is available to unauthenticated users. GraceDB permissions ========================================= @@ -72,11 +68,10 @@ Shibbolized client as follows:: from ligo.gracedb.rest import GraceDb, HTTPError - SERVICE = "https://gracedb.ligo.org/apiweb/" + SERVICE = "https://gracedb.ligo.org/api/" SHIB_SESSION_ENDPOINT = "https://gracedb.ligo.org/Shibboleth.sso/Session" client = GraceDb(SERVICE, SHIB_SESSION_ENDPOINT) - client.initialize() try: r = client.ping() diff --git a/docs/user_docs/source/lvem.rst b/docs/user_docs/source/lvem.rst index 31c2b8fb5..fcce9ce14 100644 --- a/docs/user_docs/source/lvem.rst +++ b/docs/user_docs/source/lvem.rst @@ -71,7 +71,7 @@ client class is specially formulated for basic auth:: from ligo.gracedb.rest import GraceDbBasic, HTTPError - service_url = 'https://gracedb.ligo.org/apibasic/' + service_url = 'https://gracedb.ligo.org/api/' client = GraceDbBasic(service_url) try: @@ -108,7 +108,7 @@ This file can be retrieved in the following way:: out_filename = grace_id + '_' + filename # Instantiate the GraceDB client - service_url = 'https://gracedb.ligo.org/apibasic/' + service_url = 'https://gracedb.ligo.org/api/' client = GraceDbBasic(service_url) # Grab the file from the server and write it diff --git a/docs/user_docs/source/rest.rst b/docs/user_docs/source/rest.rst index 6b2c36fa6..3afc87075 100644 --- a/docs/user_docs/source/rest.rst +++ b/docs/user_docs/source/rest.rst @@ -83,7 +83,7 @@ response. If there is an error (such as an authentication failure), the status code and a response body in JSON. The ``json`` method on the response object simply decodes the JSON content. In this particular case, the response code should be 200 (meaning "OK") and the body contains a large dictionary -of information representing the `API Root resource <https://gracedb.ligo.org/apiweb/>`__. +of information representing the `API Root resource <https://gracedb.ligo.org/api/>`__. Most of the examples below will ignore the error handling shown here for the sake of brevity. @@ -143,9 +143,9 @@ out the chirp mass? The best way is to look at the structure of an example event in the *browseable* REST API. Here some example events from the different subclasses to demonstrate the structure of the event dictionaries. -- `Test gstlal MDC <https://gracedb.ligo.org/apiweb/events/T125738>`__ (a CBC event) -- `Test cWB MDC <https://gracedb.ligo.org/apiweb/events/T153811>`__ (a Burst event) -- `External Swift GRB <https://gracedb.ligo.org/apiweb/events/E160846>`__ (a GRB event) +- `Test gstlal MDC <https://gracedb.ligo.org/api/events/T125738>`__ (a CBC event) +- `Test cWB MDC <https://gracedb.ligo.org/api/events/T153811>`__ (a Burst event) +- `External Swift GRB <https://gracedb.ligo.org/api/events/E160846>`__ (a GRB event) Creating new events ==================================== diff --git a/gracedb/api/backends.py b/gracedb/api/backends.py index 952c35eb6..17d67f6b1 100644 --- a/gracedb/api/backends.py +++ b/gracedb/api/backends.py @@ -27,8 +27,8 @@ class GraceDbBasicAuthentication(BasicAuthentication): """ logger.debug("{0}: beginning auth attempt".format(self.__class__.__name__)) - # Make sure this request is directed to the basic auth API - if self.api_only and not is_api_request(request.path, 'basic'): + # Make sure this request is directed to the API + if self.api_only and not is_api_request(request.path): logger.debug("{0}: request not directed to basic auth API".format(self.__class__.__name__)) return None @@ -81,8 +81,8 @@ class GraceDbX509Authentication(BaseAuthentication): def authenticate(self, request): logger.debug("{0}: beginning auth attempt".format(self.__class__.__name__)) - # Make sure this request is directed to the basic auth API - if self.api_only and not is_api_request(request.path, 'x509'): + # Make sure this request is directed to the API + if self.api_only and not is_api_request(request.path): logger.debug("{0}: request not directed to x509 API".format(self.__class__.__name__)) return None @@ -149,8 +149,7 @@ class GraceDbShibAuthentication(BaseAuthentication): def authenticate(self, request): logger.debug("{0}: beginning auth attempt".format(self.__class__.__name__)) if (request._request.user.is_authenticated and - is_api_request(request.path, 'shib')): - + is_api_request(request.path)): logger.debug("{0}: user {1} already authenticated".format(self.__class__.__name__, request._request.user.username)) return (request._request.user, None) else: diff --git a/gracedb/api/utils.py b/gracedb/api/utils.py index 940a04b6e..f62d96f7b 100644 --- a/gracedb/api/utils.py +++ b/gracedb/api/utils.py @@ -1,105 +1,76 @@ import logging -from django.urls import resolve +from django.urls import resolve, reverse as django_reverse from rest_framework.settings import api_settings -from rest_framework.reverse import reverse as drf_reverse from core.urls import build_absolute_uri # Set up logger logger = logging.getLogger(__name__) -# some default values -AUTH_NAMESPACES = ['api', 'x509', 'shib', 'basic'] -DEFAULT_AUTH_NAMESPACE = 'api' +# Some default values +API_NAMESPACE = 'api' def api_reverse(viewname, args=None, kwargs=None, request=None, format=None, - **extra): + absolute_path=True, **extra): """ - Reverse which handles different API auth schemes and versions. If a - request is provided, we want to send back URLs which use the same - auth type and version as the user was using. If not, we send back - the "default" auth scheme (currently 'x509') and version ('default'). - - Standard usage: - api_reverse('events:event-list', request=request) + Usage: + # No request and no version in viewname uses default version + # Same for case when request points to a non-API url + api_reverse('api:events:event-list') api_reverse('events:event-list') + api_reverse('api:events:event-list', request=request) + api_reverse('events:event-list', request=request) + /api/events/ - Not sure if we would ever *want* to specify the auth and version - namespaces manually when a request is not provided, but if so, we - can. The following are OK, too: - api_reverse('default:events:event-list') - api_reverse('v1:events:event-list') - api_reverse('api:default:events:event-list') + # No request but with version in viewname uses the specified version + # Same for case when request points to a non-API url api_reverse('api:v1:events:event-list') - api_reverse('x509:default:events:event-list') - api_reverse('x509:v1:events:event-list') + api_reverse('api:v1:events:event-list', request=request) + /api/v1/events/ + api_reverse('v2:events:event-list') + api_reverse('v2:events:event-list', request=request) + /api/v2/events/ + + # Request pointing to an API URL uses the specified version in the + # viewname. If a version is not specified in the viewname, the version + # is determined from the request. + api_reverse('api:v1:events:event-list, request=request) + api_reverse('v1:events:event-list, request=request) + /api/v1/events/ (request.path is like /api/(any version)/*) + + api_reverse('api:events:event-list, request=request) + api_reverse('events:event-list, request=request) + /api/v2/events (request.path is like /api/v2/*) """ - namespaces = [] - if request: - resolver_match = resolve(request.path) - - # We have to be careful here because this function is sometimes used - # for requests whose path is not in the API. I.e., when web views - # try to serialize stuff (like EventLogToDict). The 'else' statement - # handles that case - if resolver_match.namespaces: - # We only add the *first* namespace because it specifies the auth - # namespace. The version namespace will be handled by the - # versioning class in this case. - namespaces.append(resolver_match.namespaces[0]) - else: - namespaces.append(DEFAULT_AUTH_NAMESPACE) - namespaces.append(api_settings.DEFAULT_VERSION) - else: - # Otherwise, we check the viewname and add in the auth and version - # namespaces as needed. Note that we have to add version namespaces (if - # the code doesn't specify them) because there is no request, so - # drf_reverse won't trigger the versioning class. - - # Split provided viewname to determine possible namespaces that are - # already included - possible_namespaces = viewname.split(':')[:-1] - - # Check if any auth namespaces were provided already; if not, - # set to default using app_name - if not any([v in possible_namespaces for v in AUTH_NAMESPACES]): - namespaces.append(DEFAULT_AUTH_NAMESPACE) - - # Check if any version namespaces were provided already; if not, - # set to default - if not any([v in possible_namespaces for v in - api_settings.ALLOWED_VERSIONS]): - namespaces.append(api_settings.DEFAULT_VERSION) - - # Join namespaces to viewname - viewname = ':'.join(namespaces + [viewname]) - - # Use rest_framework reverse to get url - url = drf_reverse(viewname, args, kwargs, request, format, **extra) - - # Use sites to build absolute url if request is not available - if request is None: + + # Prepend 'api:' if viewname doesn't start with it. + if not viewname.startswith(API_NAMESPACE + ':'): + viewname = API_NAMESPACE + ':' + viewname + + # Handle versioning. Nothing is done by the versioning_class if the + # viewname already has a version namespace. + versioning_class = api_settings.DEFAULT_VERSIONING_CLASS() + viewname = versioning_class.get_versioned_viewname(viewname, request) + + # Get URL + url = django_reverse(viewname, args=args, kwargs=kwargs, **extra) + if absolute_path: url = build_absolute_uri(url) - + return url -def is_api_request(request_path, namespace='x509'): +def is_api_request(request_path): """ Returns True/False based on whether the request is directed to the API - The namespace variable determines whether we should be testing for the - 'normal' API (x509 auth), basic auth API, or web API. - - These namespaces are specified in the root urlconf (config/urls.py). """ # This is hard-coded because things break if we try to import it from .urls api_app_name = 'api' resolver_match = resolve(request_path) - if (resolver_match.app_name == api_app_name and - resolver_match.namespace == namespace): + if (resolver_match.app_name == api_app_name): return True return False diff --git a/gracedb/api/versioning.py b/gracedb/api/versioning.py index a6299221b..92fd1ccca 100644 --- a/gracedb/api/versioning.py +++ b/gracedb/api/versioning.py @@ -11,8 +11,8 @@ class NestedNamespaceVersioning(versioning.NamespaceVersioning): def reverse(self, viewname, args=None, kwargs=None, request=None, format=None, **extra): - if request.version is not None: - viewname = self.get_versioned_viewname(viewname, request) + + viewname = self.get_versioned_viewname(viewname, request) return super(NestedNamespaceVersioning, self).reverse( viewname, args, kwargs, request, format, **extra ) @@ -24,17 +24,22 @@ class NestedNamespaceVersioning(versioning.NamespaceVersioning): viewname_only = viewname_parts[-1] # Get version - if request and request.version: + if request and hasattr(request, 'version'): version = request.version else: # The 'default_version' attribute is set by the BaseVersioning # class version = self.default_version - # Add version into namespaces - if version not in namespaces: + # Insert the version unless there are at least (version_nest_level) + # namespaces and the one at the (version_nest_level - 1)th index is + # an allowed version. + insert_version_namespace = True + if (len(namespaces) >= self.version_nest_level and + self.is_allowed_version(namespaces[self.version_nest_level - 1])): + insert_version_namespace = False + if insert_version_namespace: namespaces.insert(self.version_nest_level - 1, version) versioned_viewname = ':'.join(namespaces + [viewname_only]) return versioned_viewname - diff --git a/gracedb/events/buildVOEvent.py b/gracedb/events/buildVOEvent.py index 1721f8f88..511bf0484 100644 --- a/gracedb/events/buildVOEvent.py +++ b/gracedb/events/buildVOEvent.py @@ -291,24 +291,22 @@ def buildVOEvent(event, serial_number, voevent_type, request=None, skymap_filena g = Group('GW_SKYMAP', skymap_type) # shib urls. + # For some reason we use the web URL rather than the API. + # TODO: fix it. shib_fits_skymap_url = get_url(request, objid, "file-download", fits_name) if img_name: shib_png_skymap_url = get_url(request, objid, "file-download", img_name) - # x509 urls. Hafta specify the api namespace. + # API urls: even though we only have one API endpoint now, we still + # populate all of these different URLs. Maybe we can change this in the + # future (TODO). x509_fits_skymap_url = get_url(request, objid, - "x509:default:events:files", fits_name) + "api:default:events:files", fits_name) + basic_fits_skymap_url = x509_fits_skymap_url if img_name: - x509_png_skymap_url = get_url(request, objid, - "x509:default:events:files", img_name) - - # basic urls. Hafta specify the api namespace. - basic_fits_skymap_url = get_url(request, objid, - "basic:default:events:files", fits_name) - if img_name: - basic_png_skymap_url = get_url(request, objid, - "basic:default:events:files", img_name) - + x509_png_skymap_url = get_url(request, objid, + "api:default:events:files", img_name) + basic_png_skymap_url = x509_png_skymap_url # Add parameters to the skymap group g.add_Param(Param(name="skymap_fits_shib", diff --git a/gracedb/events/permission_utils.py b/gracedb/events/permission_utils.py index aade21c6d..8fc80065d 100644 --- a/gracedb/events/permission_utils.py +++ b/gracedb/events/permission_utils.py @@ -143,15 +143,6 @@ def is_external(user): else: return True -#------------------------------------------------------------------------------- -# A utility for determining whether a user is accessing the API through the -# basic auth entry point. -#------------------------------------------------------------------------------- -def is_basicapi_request(request): - if request.path.startswith("/apibasic/"): - return True - else: - return False #------------------------------------------------------------------------------- # A utility for determining whether an external user should have access to a diff --git a/gracedb/events/views.py b/gracedb/events/views.py index 9b459f452..3c9da215f 100644 --- a/gracedb/events/views.py +++ b/gracedb/events/views.py @@ -466,7 +466,7 @@ def view(request, event): #----------------------------------------------------------------------------------- # For tags. A new view function. We need this because the API one would want users # to have certs stored in their browser. -# XXX Get rid of this and use apiweb views instead? +# XXX Get rid of this and use api views instead? #----------------------------------------------------------------------------------- @event_and_auth_required diff --git a/gracedb/superevents/buildVOEvent.py b/gracedb/superevents/buildVOEvent.py index 5220d144b..5247c2592 100644 --- a/gracedb/superevents/buildVOEvent.py +++ b/gracedb/superevents/buildVOEvent.py @@ -273,18 +273,21 @@ def construct_voevent_file(superevent, voevent, request=None, # Skymaps. Create group and set particular fits and image file names g = Group('GW_SKYMAP', skymap_type) + # We have only one API now for all authorization types. + # But the VOEvents are still expected to contain # shib, x509, and basic API urls for fits skymap file - # Temp function for reversing superevent file detail API resource - file_abs_reverse = lambda ns, file_name: build_absolute_uri( - reverse(ns + ":default:superevents:superevent-file-detail", - args=[superevent.superevent_id, file_name]), request) - shib_fits_skymap_url = file_abs_reverse('shib', fits_name) - x509_fits_skymap_url = file_abs_reverse('x509', fits_name) - basic_fits_skymap_url = file_abs_reverse('basic', fits_name) + # TODO: figure out if we can change this functionality going forward + shib_fits_skymap_url = build_absolute_uri(reverse( + "api:default:superevents:superevent-file-detail", + args=[superevent.superevent_id, fits_name]), request) + x509_fits_skymap_url = shib_fits_skymap_url + basic_fits_skymap_url = shib_fits_skymap_url if img_name: - shib_png_skymap_url = file_abs_reverse('shib', img_name) - x509_png_skymap_url = file_abs_reverse('x509', img_name) - basic_png_skymap_url = file_abs_reverse('basic', img_name) + shib_png_skymap_url = build_absolute_uri(reverse( + "api:default:superevents:superevent-file-detail", + args=[superevent.superevent_id, img_name]), request) + x509_png_skymap_url = shib_png_skymap_url + basic_png_skymap_url = shib_png_skymap_url # Add parameters to the skymap group g.add_Param(Param(name="skymap_fits_shib", diff --git a/gracedb/superevents/mixins.py b/gracedb/superevents/mixins.py index 44cbd84c9..319a9a72b 100644 --- a/gracedb/superevents/mixins.py +++ b/gracedb/superevents/mixins.py @@ -165,7 +165,7 @@ class AdvocateSignoffMixin(ContextMixin): class ExposeHideMixin(ContextMixin): expose_perm_name = 'superevents.expose_superevent' hide_perm_name = 'superevents.hide_superevent' - form_url_view_name = 'shib:default:superevents:superevent-permissions' + form_url_view_name = 'api:default:superevents:superevent-permissions' def get_context_data(self, **kwargs): diff --git a/gracedb/superevents/models.py b/gracedb/superevents/models.py index bdd1c6f70..9e396fbb3 100644 --- a/gracedb/superevents/models.py +++ b/gracedb/superevents/models.py @@ -462,7 +462,7 @@ class Log(CleanSaveModel, LogBase, AutoIncrementModel): return os.path.join(self.superevent.datadir, self.versioned_filename) def fileurl(self): - return reverse("shib:default:superevents:superevent-file-detail", + return reverse("api:default:superevents:superevent-file-detail", args=[self.superevent.superevent_id, self.versioned_filename]) diff --git a/gracedb/templates/gracedb/event_detail_script.js b/gracedb/templates/gracedb/event_detail_script.js index 7f7268bd6..862465156 100644 --- a/gracedb/templates/gracedb/event_detail_script.js +++ b/gracedb/templates/gracedb/event_detail_script.js @@ -156,14 +156,14 @@ var hasImage = function(object) { } // some URLs. Usage of Django template syntax should be limited to here -var tagListUrl = '{% url "shib:default:tag-list" %}'; +var tagListUrl = '{% url "api:default:tag-list" %}'; var tagUrlPattern = '{% url "taglogentry" object.graceid "000" "temp" %}'; -var eventLogListUrl = '{% url "shib:default:events:eventlog-list" object.graceid %}'; +var eventLogListUrl = '{% url "api:default:events:eventlog-list" object.graceid %}'; var eventLogSaveUrl = '{% url "logentry" object.graceid "" %}'; -var embbEventLogListUrl = '{% url "shib:default:events:embbeventlog-list" object.graceid %}'; -var emObservationListUrl = '{% url "shib:default:events:emobservation-list" object.graceid %}'; +var embbEventLogListUrl = '{% url "api:default:events:embbeventlog-list" object.graceid %}'; +var emObservationListUrl = '{% url "api:default:events:emobservation-list" object.graceid %}'; var fileDownloadUrl = '{% url "file-download" object.graceid "FAKE_FILE_NAME" %}'; -var skymapJsonUrl = '{% url "shib:default:events:files" object.graceid "" %}'; +var skymapJsonUrl = '{% url "api:default:events:files" object.graceid "" %}'; var skymapViewerUrl = '{{ SKYMAP_VIEWER_SERVICE_URL }}'; // This little list determines the priority ordering of the digest sections. diff --git a/gracedb/templates/gracedb/index.html b/gracedb/templates/gracedb/index.html index 52b8380a1..3fa7618f6 100644 --- a/gracedb/templates/gracedb/index.html +++ b/gracedb/templates/gracedb/index.html @@ -81,7 +81,7 @@ follow-ups. </p> <!-- <li><a href="https://www.lsc-group.phys.uwm.edu/daswg/wiki/GraceDBER6">Recent changes</a> <font color="red">(IMPORTANT!) </font></li> --> <!-- <li><a href="https://gw-astronomy.org/wiki/LV_EM/ElectroMagneticBulletinBoard">Prototype EMBB description</a></li> --> <li><a href="https://wiki.ligo.org/Computing/DASWG/GraceDB">Project page on wiki.ligo.org</a></li> -<li><a href="{% url "shib:default:root" %}">Browseable REST API</a> +<li><a href="{% url "api:default:root" %}">Browseable REST API</a> <li><a href="https://gw-astronomy.org/wiki/LV_EM/TechInfo">LV-EM Technical Info</a></li> <li><a href="https://dcc.ligo.org/G1501296">Tutorial for operators and detector engineers</a></li> diff --git a/gracedb/templates/profile/manage_password.html b/gracedb/templates/profile/manage_password.html index 4c5698b38..d4098a3b6 100644 --- a/gracedb/templates/profile/manage_password.html +++ b/gracedb/templates/profile/manage_password.html @@ -6,7 +6,7 @@ {% block content %} -<p>Passwords generated here are intended only for scripted access to GraceDB by LV-EM users. Your password allows access to the <a href={% url "basic:default:root" %}>REST API</a>.</p> +<p>Passwords generated here are intended only for scripted access to the GraceDB <a href={% url "api:default:root" %}>REST API</a> by LV-EM users.</p> <p> Your username is: <b>{{ username }}</b></p> {% if has_password %} diff --git a/gracedb/templates/superevents/detail.html b/gracedb/templates/superevents/detail.html index c55f32ac2..088eb6714 100644 --- a/gracedb/templates/superevents/detail.html +++ b/gracedb/templates/superevents/detail.html @@ -57,7 +57,7 @@ {% if show_gw_status_form %} <div class="content-area"> -<form action="{% url "shib:default:superevents:superevent-confirm-as-gw" superevent.superevent_id %}" method="POST" id="confirm_as_gw_form"> +<form action="{% url "api:default:superevents:superevent-confirm-as-gw" superevent.superevent_id %}" method="POST" id="confirm_as_gw_form"> <input type="submit" value="Confirm this superevent as a GW" class="permButtonClass" disabled> </form> <div><b>Note:</b> this action is irreversible without manual intervention by an admin.</div> @@ -70,7 +70,7 @@ {#-- XXX This next bit is super hacky. #} {% if can_modify_permissions %} <div class="content-area"> -<form action="{% url "shib:default:superevents:superevent-permission-modify" superevent.superevent_id %}" method="POST" id="permissions_form"> +<form action="{% url "api:default:superevents:superevent-permission-modify" superevent.superevent_id %}" method="POST" id="permissions_form"> <input type="hidden" name="action" value="{{ permissions_action }}"> <input type="submit" value="{{ permissions_form_button_text }}" class="permButtonClass" disabled> </form> @@ -95,11 +95,11 @@ {# inputs are disabled here, enabled by jquery code on page load. Otherwise users who click quickly can activate the form before the jquery is fully loaded #} {% if operator_signoff_exists %} {% with operator_signoff_type|add:operator_signoff_instrument as typeinst %} - <input type="submit" formaction="{% url "shib:default:superevents:superevent-signoff-detail" superevent.superevent_id typeinst %}" value="Update signoff" class="searchButtonClass" id="update" disabled> - <input type="submit" formaction="{% url "shib:default:superevents:superevent-signoff-detail" superevent.superevent_id typeinst %}" value="Delete signoff" class="searchButtonClass" id="delete" disabled> + <input type="submit" formaction="{% url "api:default:superevents:superevent-signoff-detail" superevent.superevent_id typeinst %}" value="Update signoff" class="searchButtonClass" id="update" disabled> + <input type="submit" formaction="{% url "api:default:superevents:superevent-signoff-detail" superevent.superevent_id typeinst %}" value="Delete signoff" class="searchButtonClass" id="delete" disabled> {% endwith %} {% else %} - <input type="submit" value="Create signoff" class="searchButtonClass" formaction={% url "shib:default:superevents:superevent-signoff-list" superevent.superevent_id %} disabled> + <input type="submit" value="Create signoff" class="searchButtonClass" formaction={% url "api:default:superevents:superevent-signoff-list" superevent.superevent_id %} disabled> {% endif %} </td> </tr> @@ -129,11 +129,11 @@ {# inputs are disabled here, enabled by jquery code on page load. Otherwise users who click quickly can activate the form before the jquery is fully loaded #} {% if advocate_signoff_exists %} {% with advocate_signoff_type|add:advocate_signoff_instrument as typeinst %} - <input type="submit" formaction="{% url "shib:default:superevents:superevent-signoff-detail" superevent.superevent_id typeinst %}" value="Update signoff" class="searchButtonClass" id="update" disabled> - <input type="submit" formaction="{% url "shib:default:superevents:superevent-signoff-detail" superevent.superevent_id typeinst %}" value="Delete signoff" class="searchButtonClass" id="delete" disabled> + <input type="submit" formaction="{% url "api:default:superevents:superevent-signoff-detail" superevent.superevent_id typeinst %}" value="Update signoff" class="searchButtonClass" id="update" disabled> + <input type="submit" formaction="{% url "api:default:superevents:superevent-signoff-detail" superevent.superevent_id typeinst %}" value="Delete signoff" class="searchButtonClass" id="delete" disabled> {% endwith %} {% else %} - <input type="submit" value="Create signoff" class="searchButtonClass" formaction={% url "shib:default:superevents:superevent-signoff-list" superevent.superevent_id %} disabled> + <input type="submit" value="Create signoff" class="searchButtonClass" formaction={% url "api:default:superevents:superevent-signoff-list" superevent.superevent_id %} disabled> {% endif %} </td> </tr> diff --git a/gracedb/templates/superevents/file_list.html b/gracedb/templates/superevents/file_list.html index 5a71cd49a..c34b8fab8 100644 --- a/gracedb/templates/superevents/file_list.html +++ b/gracedb/templates/superevents/file_list.html @@ -8,7 +8,7 @@ <ul> {% for filename in file_list %} -<li><a href="{% url "shib:default:superevents:superevent-file-detail" object.superevent_id filename %}">{{ filename }}</a></li> +<li><a href="{% url "api:default:superevents:superevent-file-detail" object.superevent_id filename %}">{{ filename }}</a></li> {% endfor %} </ul> diff --git a/gracedb/templates/superevents/superevent_detail_script.js b/gracedb/templates/superevents/superevent_detail_script.js index 283af7e30..84c12f70e 100644 --- a/gracedb/templates/superevents/superevent_detail_script.js +++ b/gracedb/templates/superevents/superevent_detail_script.js @@ -156,13 +156,13 @@ var hasImage = function(object) { } // some URLs. Usage of Django template syntax should be limited to here -var tagListUrl = '{% url "shib:default:tag-list" %}'; -var tagCreateUrlPattern = '{% url "shib:default:superevents:superevent-log-tag-list" superevent.superevent_id "000" %}'; -var tagDeleteUrlPattern = '{% url "shib:default:superevents:superevent-log-tag-detail" superevent.superevent_id "000" "FAKE_TAG_NAME" %}'; -var logListUrl = '{% url "shib:default:superevents:superevent-log-list" superevent.superevent_id %}'; -var logSaveUrl = '{% url "shib:default:superevents:superevent-log-list" superevent.superevent_id %}'; -var emObservationListUrl = '{% url "shib:default:superevents:superevent-emobservation-list" superevent.superevent_id %}'; -var fileDownloadUrl = '{% url "shib:default:superevents:superevent-file-detail" superevent.superevent_id "FAKE_FILE_NAME" %}'; +var tagListUrl = '{% url "api:default:tag-list" %}'; +var tagCreateUrlPattern = '{% url "api:default:superevents:superevent-log-tag-list" superevent.superevent_id "000" %}'; +var tagDeleteUrlPattern = '{% url "api:default:superevents:superevent-log-tag-detail" superevent.superevent_id "000" "FAKE_TAG_NAME" %}'; +var logListUrl = '{% url "api:default:superevents:superevent-log-list" superevent.superevent_id %}'; +var logSaveUrl = '{% url "api:default:superevents:superevent-log-list" superevent.superevent_id %}'; +var emObservationListUrl = '{% url "api:default:superevents:superevent-emobservation-list" superevent.superevent_id %}'; +var fileDownloadUrl = '{% url "api:default:superevents:superevent-file-detail" superevent.superevent_id "FAKE_FILE_NAME" %}'; var skymapViewerUrl = '{{ SKYMAP_VIEWER_SERVICE_URL }}'; // This little list determines the priority ordering of the digest sections. -- GitLab