WIP django catalog admin
This commit is contained in:
50
lms/templates/admin/api_admin/catalog/change_form.html
Normal file
50
lms/templates/admin/api_admin/catalog/change_form.html
Normal file
@@ -0,0 +1,50 @@
|
||||
{% extends "admin/base_site.html" %}
|
||||
{% load admin_modify adminmedia %}
|
||||
|
||||
{% block extrahead %}
|
||||
{{ block.super }}
|
||||
{{ media }}
|
||||
{% endblock %}
|
||||
|
||||
{% block extrastyle %}{{ block.super }}<link rel="stylesheet" type="text/css" href="{% admin_media_prefix %}css/forms.css" />{% endblock %}
|
||||
|
||||
{% block coltype %}colMS{% endblock %}
|
||||
|
||||
{% block bodyclass %} change-form{% endblock %}
|
||||
|
||||
{% block breadcrumbs %}
|
||||
<div class="breadcrumbs">
|
||||
<a href="../../../">Home</a> ›
|
||||
<a href="../../">Api_Admin</a> ›
|
||||
<a href="../">Catalogs</a> ›
|
||||
{% if change %}
|
||||
{{form.name}}
|
||||
{% else %}
|
||||
Add Catalog
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div id="content-main">
|
||||
{% block object-tools %}
|
||||
{% endblock %}
|
||||
<form action="." method="post" enctype="multipart/form-data">
|
||||
|
||||
<fieldset class="module aligned {{ fieldset.classes }}">
|
||||
{% for field in form.visible_fields %}
|
||||
<div class="form-row">
|
||||
{{ field.errors }}
|
||||
{{ field.label_tag }}{{ field }}
|
||||
{% if field.field.help_text %}<p class="help">{{ field.field.help_text|safe }}</p>{% endif %}
|
||||
</div>
|
||||
{% endfor %}
|
||||
{% for field in form.hidden_fields %}
|
||||
{{ field }}
|
||||
{% endfor %}
|
||||
|
||||
</fieldset>
|
||||
<input type="submit" value="Save" />
|
||||
</form>
|
||||
</div>
|
||||
{% endblock %}
|
||||
27
lms/templates/admin/api_admin/catalog/change_list.html
Normal file
27
lms/templates/admin/api_admin/catalog/change_list.html
Normal file
@@ -0,0 +1,27 @@
|
||||
{% extends "admin/base_site.html" %}
|
||||
{% block extrahead %}
|
||||
{{ block.super }}
|
||||
{% endblock %}
|
||||
{% block innercontent %}
|
||||
<ul class="object-tools">
|
||||
<li>
|
||||
<a class="addlink" href="add/">Add Catalog</a>
|
||||
</li>
|
||||
</ul>
|
||||
<table cellspacing="0" style="margin-top: 20px;">
|
||||
<thead>
|
||||
<tr>
|
||||
<th></th>
|
||||
<th>Name</th>
|
||||
</tr>
|
||||
</thead>
|
||||
{% for catalog in catalogs %}
|
||||
<tr class="{% cycle 'row1' 'row2' %}">
|
||||
<td> </td>
|
||||
<td>
|
||||
<a href="{{catalog.id}}">{{catalog.name}}</a>
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</table>
|
||||
{% endblock %}
|
||||
49
lms/templates/api_admin/catalog_changeform.html
Normal file
49
lms/templates/api_admin/catalog_changeform.html
Normal file
@@ -0,0 +1,49 @@
|
||||
{% extends "admin/base_site.html" %}
|
||||
{% load admin_modify staticfiles %}
|
||||
|
||||
{% block extrahead %}
|
||||
{{ block.super }}
|
||||
{{ media }}
|
||||
{% endblock %}
|
||||
|
||||
{% block extrastyle %}{{ block.super }}<link rel="stylesheet" type="text/css" href="{% static 'css/forms.css' %}" />{% endblock %}
|
||||
|
||||
{% block coltype %}colMS{% endblock %}
|
||||
|
||||
{% block bodyclass %} change-form{% endblock %}
|
||||
|
||||
{% block breadcrumbs %}
|
||||
<div class="breadcrumbs">
|
||||
<a href="../../../">Home</a> ›
|
||||
<a href="../../">Api_Admin</a> ›
|
||||
<a href="../">Catalogs</a> ›
|
||||
{% if change %}
|
||||
{{form.name}}
|
||||
{% else %}
|
||||
Add Catalog
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div id="content-main">
|
||||
{% block object-tools %}
|
||||
{% endblock %}
|
||||
<form action="." method="post" enctype="multipart/form-data">{% csrf_token %}
|
||||
<fieldset class="module aligned {{ fieldset.classes }}">
|
||||
{% for field in form.visible_fields %}
|
||||
<div class="form-row">
|
||||
{{ field.errors }}
|
||||
{{ field.label_tag }}{{ field }}
|
||||
{% if field.field.help_text %}<p class="help">{{ field.field.help_text|safe }}</p>{% endif %}
|
||||
</div>
|
||||
{% endfor %}
|
||||
{% for field in form.hidden_fields %}
|
||||
{{ field }}
|
||||
{% endfor %}
|
||||
|
||||
</fieldset>
|
||||
<input type="submit" value="Save" />
|
||||
</form>
|
||||
</div>
|
||||
{% endblock %}
|
||||
60
lms/templates/api_admin/catalog_changelist.html
Normal file
60
lms/templates/api_admin/catalog_changelist.html
Normal file
@@ -0,0 +1,60 @@
|
||||
{% extends "admin/base_site.html" %}
|
||||
{% load i18n admin_urls static admin_list %}
|
||||
|
||||
{% block extrastyle %}
|
||||
{{ block.super }}
|
||||
<link rel="stylesheet" type="text/css" href="{% static "admin/css/changelists.css" %}" />
|
||||
{% if cl.formset %}
|
||||
<link rel="stylesheet" type="text/css" href="{% static "admin/css/forms.css" %}" />
|
||||
{% endif %}
|
||||
{% if cl.formset or action_form %}
|
||||
<script type="text/javascript" src="{% url 'admin:jsi18n' %}"></script>
|
||||
{% endif %}
|
||||
{{ media.css }}
|
||||
{% if not actions_on_top and not actions_on_bottom %}
|
||||
<style>
|
||||
#changelist table thead th:first-child {width: inherit}
|
||||
</style>
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
|
||||
{% block extrahead %}
|
||||
{{ block.super }}
|
||||
{{ media.js }}
|
||||
{% endblock %}
|
||||
|
||||
{% block breadcrumbs %}
|
||||
<div class="breadcrumbs">
|
||||
<a href="../../../">Home</a> ›
|
||||
<a href="../../">Api_Admin</a> ›
|
||||
Catalogs
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
{% block coltype %}flex{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
{% block innercontent %}
|
||||
<ul class="object-tools">
|
||||
<li>
|
||||
<a class="addlink" href="add/">Add Catalog</a>
|
||||
</li>
|
||||
</ul>
|
||||
<table cellspacing="0" style="margin-top: 20px;">
|
||||
<thead>
|
||||
<tr>
|
||||
<th></th>
|
||||
<th>Name</th>
|
||||
</tr>
|
||||
</thead>
|
||||
{% for catalog in catalogs %}
|
||||
<tr class="{% cycle 'row1' 'row2' %}">
|
||||
<td> </td>
|
||||
<td>
|
||||
<a href="{{catalog.id}}">{{catalog.name}}</a>
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</table>
|
||||
{% endblock %}
|
||||
{% endblock %}
|
||||
@@ -113,6 +113,9 @@ urlpatterns = (
|
||||
|
||||
# URLs for API access management
|
||||
url(r'^api-admin/', include('openedx.core.djangoapps.api_admin.urls', namespace='api_admin')),
|
||||
url(r'^admin/api_admin/catalog/add/$', 'openedx.core.djangoapps.api_admin.views.catalog_changeform'),
|
||||
url(r'^admin/api_admin/catalog/(?P<id>\d+)/$', 'openedx.core.djangoapps.api_admin.views.catalog_changeform'),
|
||||
url(r'^admin/api_admin/catalog/$', 'openedx.core.djangoapps.api_admin.views.catalog_changelist'),
|
||||
)
|
||||
|
||||
urlpatterns += (
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
from django.contrib import admin
|
||||
|
||||
from config_models.admin import ConfigurationModelAdmin
|
||||
from openedx.core.djangoapps.api_admin.models import ApiAccessRequest, ApiAccessConfig
|
||||
from openedx.core.djangoapps.api_admin.models import ApiAccessRequest, ApiAccessConfig, Catalog
|
||||
|
||||
|
||||
@admin.register(ApiAccessRequest)
|
||||
@@ -15,5 +15,8 @@ class ApiAccessRequestAdmin(admin.ModelAdmin):
|
||||
readonly_fields = ('user', 'website', 'reason', 'company_name', 'company_address', 'contacted', )
|
||||
exclude = ('site',)
|
||||
|
||||
@admin.register(Catalog)
|
||||
class CatalogAdmin (admin.ModelAdmin):
|
||||
name="Catalog"
|
||||
|
||||
admin.site.register(ApiAccessConfig, ConfigurationModelAdmin)
|
||||
|
||||
@@ -32,3 +32,13 @@ class ApiAccessRequestForm(forms.ModelForm):
|
||||
# Get rid of the colons at the end of the field labels.
|
||||
kwargs.setdefault('label_suffix', '')
|
||||
super(ApiAccessRequestForm, self).__init__(*args, **kwargs)
|
||||
|
||||
|
||||
class CatalogForm(forms.Form):
|
||||
id = forms.IntegerField(required=False, widget=forms.HiddenInput)
|
||||
name = forms.CharField(required=True, help_text="The name of this catalog")
|
||||
query = forms.CharField(
|
||||
required=True,
|
||||
help_text="The query for courses to be returned by catalog",
|
||||
widget=forms.Textarea
|
||||
)
|
||||
|
||||
@@ -179,3 +179,24 @@ def _send_decision_email(instance):
|
||||
instance.contacted = True
|
||||
except SMTPException:
|
||||
log.exception('Error sending API user notification email for request [%s].', instance.id)
|
||||
|
||||
|
||||
class CatalogManager(object):
|
||||
def get(self, key):
|
||||
log.info("GET api call: %s", key)
|
||||
return None
|
||||
|
||||
def all(self):
|
||||
log.info("ALL api call")
|
||||
return []
|
||||
|
||||
def filter(self, **kwargs):
|
||||
log.info("FILTER api call: %s", kwargs)
|
||||
return []
|
||||
|
||||
|
||||
class Catalog(models.Model):
|
||||
objects = CatalogManager()
|
||||
|
||||
class Meta:
|
||||
managed = False
|
||||
|
||||
@@ -2,10 +2,14 @@
|
||||
import logging
|
||||
|
||||
from django.conf import settings
|
||||
from django.contrib.admin.views.decorators import staff_member_required
|
||||
from django.contrib.sites.shortcuts import get_current_site
|
||||
from django.core.urlresolvers import reverse_lazy, reverse
|
||||
from django.shortcuts import redirect
|
||||
from django.http import HttpResponseRedirect
|
||||
from django.shortcuts import redirect, render
|
||||
from django.template import RequestContext
|
||||
from django.utils.translation import ugettext as _
|
||||
from django.views.decorators.cache import never_cache
|
||||
from django.views.generic import View
|
||||
from django.views.generic.base import TemplateView
|
||||
from django.views.generic.edit import CreateView
|
||||
@@ -14,9 +18,11 @@ from oauth2_provider.models import get_application_model
|
||||
from oauth2_provider.views import ApplicationRegistration
|
||||
|
||||
from edxmako.shortcuts import render_to_response
|
||||
from edx_rest_api_client.client import EdxRestApiClient
|
||||
from openedx.core.djangoapps.api_admin.decorators import require_api_access
|
||||
from openedx.core.djangoapps.api_admin.forms import ApiAccessRequestForm
|
||||
from openedx.core.djangoapps.api_admin.forms import ApiAccessRequestForm, CatalogForm
|
||||
from openedx.core.djangoapps.api_admin.models import ApiAccessRequest
|
||||
from openedx.core.lib.token_utils import get_asymmetric_token
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
@@ -115,3 +121,74 @@ class ApiTosView(TemplateView):
|
||||
"""View to show the API Terms of Service."""
|
||||
|
||||
template_name = 'api_admin/terms_of_service.html'
|
||||
|
||||
|
||||
@never_cache
|
||||
@staff_member_required
|
||||
def catalog_changelist(request):
|
||||
# TODO: get catalogs
|
||||
catalogs = [
|
||||
{
|
||||
'id': '1',
|
||||
'name': 'test1',
|
||||
'query': '*'
|
||||
}
|
||||
]
|
||||
return render(
|
||||
RequestContext(request),
|
||||
'api_admin/catalog_changelist.html',
|
||||
{
|
||||
'catalogs': catalogs,
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
@never_cache
|
||||
@staff_member_required
|
||||
def catalog_changeform(request, id=None):
|
||||
# import pdb; pdb.set_trace()
|
||||
if request.method == 'POST':
|
||||
form = CatalogForm(request.POST)
|
||||
change = False
|
||||
if form.is_valid():
|
||||
if id is None:
|
||||
log.info("CREATE NEW CATALOGUE") # create new catalog
|
||||
else:
|
||||
change = True
|
||||
log.info("UPDATE CATALOGUE") # update catalog
|
||||
return HttpResponseRedirect('..')
|
||||
else:
|
||||
if id is None: # Create new catalog
|
||||
change = False
|
||||
form = CatalogForm()
|
||||
else: # Update existing catalog
|
||||
change = True
|
||||
catalog = {
|
||||
'id': '2',
|
||||
'name': 'test2',
|
||||
'query': 'test*'
|
||||
} # Get catalogs
|
||||
|
||||
form = CatalogForm(catalog)
|
||||
# del form.fields['hidden_field']
|
||||
return render(
|
||||
request,
|
||||
'api_admin/catalog_changeform.html',
|
||||
{
|
||||
'change': change,
|
||||
'form': form,
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
def catalog_client(user):
|
||||
token = get_asymmetric_token(user, 'course-discovery')
|
||||
return EdxRestApiClient(
|
||||
"http://18.111.106.34:8008/api/v1/",
|
||||
jwt=token
|
||||
)
|
||||
|
||||
# from openedx.core.djangoapps.api_admin.views import catalog_client
|
||||
# from django.contrib.auth.models import User
|
||||
# user = User.objects.all()[1]
|
||||
# c = catalog_client(user)
|
||||
|
||||
@@ -67,7 +67,7 @@ def get_id_token(user, client_name):
|
||||
return jwt.encode(payload, client.client_secret)
|
||||
|
||||
|
||||
def get_asymmetric_token(user):
|
||||
def get_asymmetric_token(user, client_id):
|
||||
"""Construct a JWT signed with this app's private key.
|
||||
|
||||
The JWT includes the following claims:
|
||||
@@ -108,6 +108,7 @@ def get_asymmetric_token(user):
|
||||
'iss': settings.OAUTH_OIDC_ISSUER,
|
||||
'exp': now + datetime.timedelta(seconds=expires_in),
|
||||
'iat': now,
|
||||
'aud': client_id,
|
||||
'sub': anonymous_id_for_user(user, None),
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user