Commit 26e09fee by Douglas Hall

Merge pull request #11243 from edx/hasnain-naveed/HOL-37-proxy-rss

HOL-12 HOL-29 rss_proxy djangoapp
parents 22e01a8c e3c9f873
"""
Admin module for the rss_proxy djangoapp.
"""
from django.contrib import admin
from rss_proxy.models import WhitelistedRssUrl
admin.site.register(WhitelistedRssUrl)
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import migrations, models
import django.utils.timezone
import model_utils.fields
class Migration(migrations.Migration):
dependencies = [
]
operations = [
migrations.CreateModel(
name='WhitelistedRssUrl',
fields=[
('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
('created', model_utils.fields.AutoCreatedField(default=django.utils.timezone.now, verbose_name='created', editable=False)),
('modified', model_utils.fields.AutoLastModifiedField(default=django.utils.timezone.now, verbose_name='modified', editable=False)),
('url', models.CharField(unique=True, max_length=255, db_index=True)),
],
),
]
"""
Models for the rss_proxy djangoapp.
"""
from django.db import models
from model_utils.models import TimeStampedModel
class WhitelistedRssUrl(TimeStampedModel):
"""
Model for persisting RSS feed URLs which are whitelisted
for proxying via this rss_proxy djangoapp.
"""
url = models.CharField(max_length=255, unique=True, db_index=True)
class Meta(object):
""" Meta class for this Django model """
app_label = "rss_proxy"
def __unicode__(self):
return unicode(self.url)
"""
Tests for the rss_proxy models
"""
from django.test import TestCase
from rss_proxy.models import WhitelistedRssUrl
class WhitelistedRssUrlTests(TestCase):
""" Tests for the rss_proxy.WhitelistedRssUrl model """
def setUp(self):
super(WhitelistedRssUrlTests, self).setUp()
self.whitelisted_rss_url = WhitelistedRssUrl.objects.create(url='http://www.example.com')
def test_unicode(self):
"""
Test the unicode function returns the url
"""
self.assertEqual(unicode(self.whitelisted_rss_url), self.whitelisted_rss_url.url)
"""
Tests for the rss_proxy views
"""
from django.test import TestCase
from django.core.urlresolvers import reverse
from mock import patch, Mock
from rss_proxy.models import WhitelistedRssUrl
class RssProxyViewTests(TestCase):
""" Tests for the rss_proxy views """
def setUp(self):
super(RssProxyViewTests, self).setUp()
self.whitelisted_url1 = 'http://www.example.com'
self.whitelisted_url2 = 'http://www.example.org'
self.non_whitelisted_url = 'http://www.example.net'
self.rss = '''
<?xml version="1.0" encoding="utf-8" ?>
<rss version="2.0">
<channel>
<title></title>
<link>http://www.example.com/rss</link>
<description></description>
<language>en</language>
<item>
<title>Example</title>
<link>http://www.example.com/rss/item</link>
<description>Example item description</description>
<pubDate>Fri, 13 May 1977 00:00:00 +0000</pubDate>
</item>
</channel>
</rss>
'''
WhitelistedRssUrl.objects.create(url=self.whitelisted_url1)
WhitelistedRssUrl.objects.create(url=self.whitelisted_url2)
@patch('rss_proxy.views.requests.get')
def test_proxy_with_whitelisted_url(self, mock_requests_get):
"""
Test the proxy view with a whitelisted URL
"""
mock_requests_get.return_value = Mock(status_code=200, content=self.rss)
resp = self.client.get('%s?url=%s' % (reverse('rss_proxy:proxy'), self.whitelisted_url1))
self.assertEqual(resp.status_code, 200)
self.assertEqual(resp['Content-Type'], 'application/xml')
self.assertEqual(resp.content, self.rss)
@patch('rss_proxy.views.requests.get')
def test_proxy_with_whitelisted_url_404(self, mock_requests_get):
"""
Test the proxy view with a whitelisted URL that is not found
"""
mock_requests_get.return_value = Mock(status_code=404)
resp = self.client.get('%s?url=%s' % (reverse('rss_proxy:proxy'), self.whitelisted_url2))
print resp.status_code
print resp.content
print resp['Content-Type']
self.assertEqual(resp.status_code, 404)
self.assertEqual(resp['Content-Type'], 'application/xml')
self.assertEqual(resp.content, '')
def test_proxy_with_non_whitelisted_url(self):
"""
Test the proxy view with a non-whitelisted URL
"""
resp = self.client.get('%s?url=%s' % (reverse('rss_proxy:proxy'), self.non_whitelisted_url))
self.assertEqual(resp.status_code, 404)
"""
URLs for the rss_proxy djangoapp.
"""
from django.conf.urls import url
urlpatterns = [
url(r"^$", "rss_proxy.views.proxy", name="proxy"),
]
"""
Views for the rss_proxy djangoapp.
"""
import requests
from django.conf import settings
from django.core.cache import cache
from django.http import HttpResponse, HttpResponseNotFound
from rss_proxy.models import WhitelistedRssUrl
CACHE_KEY_RSS = "rss_proxy.{url}"
def proxy(request):
"""
Proxy requests for the given RSS url if it has been whitelisted.
"""
url = request.GET.get('url')
if url and WhitelistedRssUrl.objects.filter(url=url).exists():
# Check cache for RSS if the given url is whitelisted
cache_key = CACHE_KEY_RSS.format(url=url)
status_code = 200
rss = cache.get(cache_key, '')
print cache_key
print 'Cached rss: %s' % rss
if not rss:
# Go get the RSS from the URL if it was not cached
resp = requests.get(url)
status_code = resp.status_code
if status_code == 200:
# Cache RSS
rss = resp.content
cache.set(cache_key, rss, settings.RSS_PROXY_CACHE_TIMEOUT)
return HttpResponse(rss, status=status_code, content_type='application/xml')
return HttpResponseNotFound()
......@@ -1860,6 +1860,9 @@ INSTALLED_APPS = (
# Microsite configuration
'microsite_configuration',
# RSS Proxy
'rss_proxy',
# Student Identity Reverification
'reverification',
......@@ -2656,6 +2659,9 @@ MICROSITE_TEMPLATE_BACKEND = 'microsite_configuration.backends.filebased.Filebas
# TTL for microsite database template cache
MICROSITE_DATABASE_TEMPLATE_CACHE_TTL = 5 * 60
################################ Settings for rss_proxy ################################
RSS_PROXY_CACHE_TIMEOUT = 3600 # The length of time we cache RSS retrieved from remote URLs in seconds
#### PROCTORING CONFIGURATION DEFAULTS
......
......@@ -101,6 +101,7 @@ urlpatterns = (
url(r'^api/commerce/', include('commerce.api.urls', namespace='commerce_api')),
url(r'^api/credit/', include('openedx.core.djangoapps.credit.urls', app_name="credit", namespace='credit')),
url(r'^rss_proxy/', include('rss_proxy.urls', namespace='rss_proxy')),
)
if settings.FEATURES["ENABLE_COMBINED_LOGIN_REGISTRATION"]:
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment