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.core import models
from regluit.marc.models import MARCRecord
from regluit.api.models import AllowedRepo
from regluit.core.lookups import (
PublisherNameLookup,
WorkLookup,
@ -233,6 +234,9 @@ class MARCRecordAdmin(ModelAdmin):
date_hierarchy = 'created'
form = MARCRecordAdminForm
class AllowedRepoAdmin(ModelAdmin):
list_display = ('org', 'repo_name')
admin_site = RegluitAdmin("Admin")
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.Gift, GiftAdmin)
admin_site.register(MARCRecord, MARCRecordAdmin)
admin_site.register(AllowedRepo, AllowedRepoAdmin)
admin_site.register(models.Relation, RelationAdmin)
# 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.utils.localdatetime import now
from regluit.api import models as apimodels
class ApiTests(TestCase):
work_id=None
@ -125,3 +126,21 @@ class ApiTests(TestCase):
r = self.client.get('/api/widget/%s/'%self.work_id)
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
from regluit.core.bookloader import load_from_yaml
from regluit.api import opds
from regluit.api.models import repo_allowed
from regluit.core import models
@ -70,6 +71,9 @@ def load_yaml(request):
repo_url = request.POST.get('repo_url', None)
if not repo_url:
return HttpResponse('needs repo_url')
(allowed,reason) =repo_allowed(repo_url)
if not allowed:
return HttpResponse('repo_url not allowed: '+reason)
try:
work_id = load_from_yaml(repo_url)
return HttpResponseRedirect(reverse('work', args=[work_id]))