allow only approved repos
parent
f79daf09db
commit
92e9b7cb3c
5
admin.py
5
admin.py
|
@ -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
|
||||||
|
|
|
@ -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']
|
|
@ -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)
|
||||||
|
|
19
api/tests.py
19
api/tests.py
|
@ -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])
|
||||||
|
|
||||||
|
|
|
@ -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]))
|
||||||
|
|
Loading…
Reference in New Issue