allow only approved repos

pull/1/head
eric 2015-08-04 12:02:06 -04:00
parent f79daf09db
commit 92e9b7cb3c
6 changed files with 93 additions and 0 deletions

View File

@ -36,6 +36,7 @@ regluit imports
from regluit import payment from regluit import payment
from regluit.core import models from regluit.core import models
from regluit.marc.models import MARCRecord from regluit.marc.models import MARCRecord
from regluit.api.models import AllowedRepo
from regluit.core.lookups import ( from regluit.core.lookups import (
PublisherNameLookup, PublisherNameLookup,
WorkLookup, WorkLookup,
@ -233,6 +234,9 @@ class MARCRecordAdmin(ModelAdmin):
date_hierarchy = 'created' date_hierarchy = 'created'
form = MARCRecordAdminForm form = MARCRecordAdminForm
class AllowedRepoAdmin(ModelAdmin):
list_display = ('org', 'repo_name')
admin_site = RegluitAdmin("Admin") admin_site = RegluitAdmin("Admin")
admin_site.register(User, UserAdmin) admin_site.register(User, UserAdmin)
@ -258,6 +262,7 @@ admin_site.register(models.CeleryTask, CeleryTaskAdmin)
admin_site.register(models.Press, PressAdmin) admin_site.register(models.Press, PressAdmin)
admin_site.register(models.Gift, GiftAdmin) admin_site.register(models.Gift, GiftAdmin)
admin_site.register(MARCRecord, MARCRecordAdmin) admin_site.register(MARCRecord, MARCRecordAdmin)
admin_site.register(AllowedRepo, AllowedRepoAdmin)
admin_site.register(models.Relation, RelationAdmin) admin_site.register(models.Relation, RelationAdmin)
# payments # payments

View File

@ -0,0 +1,34 @@
# -*- coding: utf-8 -*-
import datetime
from south.db import db
from south.v2 import SchemaMigration
from django.db import models
class Migration(SchemaMigration):
def forwards(self, orm):
# Adding model 'AllowedRepo'
db.create_table('api_allowedrepo', (
('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
('org', self.gf('django.db.models.fields.CharField')(max_length=39)),
('repo_name', self.gf('django.db.models.fields.CharField')(max_length=100)),
))
db.send_create_signal('api', ['AllowedRepo'])
def backwards(self, orm):
# Deleting model 'AllowedRepo'
db.delete_table('api_allowedrepo')
models = {
'api.allowedrepo': {
'Meta': {'object_name': 'AllowedRepo'},
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'org': ('django.db.models.fields.CharField', [], {'max_length': '39'}),
'repo_name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
}
}
complete_apps = ['api']

View File

View File

@ -0,0 +1,31 @@
from django.db import models
#https://github.com/GITenberg/Adventures-of-Huckleberry-Finn_76/raw/master/metadata.yaml
def repo_allowed(repo_url):
if not repo_url.startswith('https://github.com/'):
return (False, "repo url must start with 'https://github.com/'")
try:
(org,repo_name,raw,branch,filename) = repo_url[19:].split('/')
except ValueError:
return (False, "repo url must be well formed, metadata at top repo level")
if not raw == 'raw':
return (False, "repo url must point at 'raw' file")
if not filename == 'metadata.yaml':
return (False, "repo filename must be 'metadata.yaml'")
if not branch == 'master':
return (False, "repo branch must be 'master'")
allowed_repos = AllowedRepo.objects.filter(org=org)
for allowed_repo in allowed_repos:
if allowed_repo.repo_name == '*':
return (True, '*')
if allowed_repo.repo_name == repo_name:
return (True, '*')
return (False, "no allowed repos in that org")
class AllowedRepo(models.Model):
org = models.CharField(max_length=39)
repo_name = models.CharField(max_length=100)

View File

@ -18,6 +18,7 @@ import regluit.core.isbn
from regluit.core import bookloader, models from regluit.core import bookloader, models
from regluit.utils.localdatetime import now from regluit.utils.localdatetime import now
from regluit.api import models as apimodels
class ApiTests(TestCase): class ApiTests(TestCase):
work_id=None work_id=None
@ -125,3 +126,21 @@ class ApiTests(TestCase):
r = self.client.get('/api/widget/%s/'%self.work_id) r = self.client.get('/api/widget/%s/'%self.work_id)
self.assertEqual(r.status_code, 200) self.assertEqual(r.status_code, 200)
class AllowedRepoTests(TestCase):
def setUp(self):
apimodels.AllowedRepo.objects.create(org='test',repo_name='test')
apimodels.AllowedRepo.objects.create(org='star',repo_name='*')
def test_urls(self):
#good
self.assertTrue(apimodels.repo_allowed('https://github.com/test/test/raw/master/metadata.yaml')[0])
self.assertTrue(apimodels.repo_allowed('https://github.com/star/test/raw/master/metadata.yaml')[0])
# bad urls
self.assertFalse(apimodels.repo_allowed('auhf8peargp8ge')[0])
self.assertFalse(apimodels.repo_allowed('')[0])
self.assertFalse(apimodels.repo_allowed('http://github.com/test/test/raw/master/metadata.yaml')[0])
self.assertFalse(apimodels.repo_allowed('https://github.com/test/test/raw/master/samples/metadata.yaml')[0])
self.assertFalse(apimodels.repo_allowed('https://github.com/test/test/raw/branch/metadata.yaml')[0])
self.assertFalse(apimodels.repo_allowed('https://github.com/test/test/master/metadata.yaml')[0])
self.assertFalse(apimodels.repo_allowed('https://github.com/test/test/raw/master/metadata.json')[0])

View File

@ -17,6 +17,7 @@ from django.http import (
import regluit.core.isbn import regluit.core.isbn
from regluit.core.bookloader import load_from_yaml from regluit.core.bookloader import load_from_yaml
from regluit.api import opds from regluit.api import opds
from regluit.api.models import repo_allowed
from regluit.core import models from regluit.core import models
@ -70,6 +71,9 @@ def load_yaml(request):
repo_url = request.POST.get('repo_url', None) repo_url = request.POST.get('repo_url', None)
if not repo_url: if not repo_url:
return HttpResponse('needs repo_url') return HttpResponse('needs repo_url')
(allowed,reason) =repo_allowed(repo_url)
if not allowed:
return HttpResponse('repo_url not allowed: '+reason)
try: try:
work_id = load_from_yaml(repo_url) work_id = load_from_yaml(repo_url)
return HttpResponseRedirect(reverse('work', args=[work_id])) return HttpResponseRedirect(reverse('work', args=[work_id]))