mirror of
https://github.com/kennethreitz-archive/chishop.git
synced 2026-06-05 23:40:18 +00:00
Added authentication for register+upload, and projects now has owners.
This commit is contained in:
committed by
Ask Solem Hoel
parent
4335d5430f
commit
9a3a947bf3
+32
-10
@@ -35,6 +35,10 @@ from django import forms
|
||||
from djangopypi.models import Project, Classifier, Release
|
||||
|
||||
|
||||
class PermissionDeniedError(Exception):
|
||||
"""The user did not have the priveliges to execute an action."""
|
||||
|
||||
|
||||
class ProjectRegisterForm(forms.Form):
|
||||
name = forms.CharField()
|
||||
license = forms.CharField(required=False)
|
||||
@@ -48,12 +52,30 @@ class ProjectRegisterForm(forms.Form):
|
||||
version = forms.CharField()
|
||||
platform = forms.CharField(required=False)
|
||||
|
||||
def save(self, classifiers, file=None):
|
||||
PermissionDeniedError = PermissionDeniedError
|
||||
|
||||
def save(self, classifiers, user, file=None):
|
||||
values = dict(self.cleaned_data)
|
||||
name = values.pop("name")
|
||||
name = values["name"]
|
||||
version = values.pop("version")
|
||||
platform = values.pop("platform")
|
||||
project, c = Project.objects.get_or_create(name=name, defaults=values)
|
||||
platform = values.pop("platform", "UNKNOWN")
|
||||
values["owner"] = user
|
||||
|
||||
try:
|
||||
project = Project.objects.get(name=name)
|
||||
except Project.DoesNotExist:
|
||||
project = Project.objects.create(**values)
|
||||
else:
|
||||
# If the project already exists,
|
||||
# be sure that the current user owns this object.
|
||||
if project.owner != user:
|
||||
raise self.PermissionDeniedError(
|
||||
"%s doesn't own that project." % user.username)
|
||||
[setattr(project, field_name, field_value)
|
||||
for field_name, field_value in values.items()]
|
||||
project.save()
|
||||
|
||||
|
||||
for classifier in classifiers:
|
||||
project.classifiers.add(
|
||||
Classifier.objects.get_or_create(name=classifier)[0])
|
||||
@@ -62,17 +84,17 @@ class ProjectRegisterForm(forms.Form):
|
||||
# filename, however with .tar.gz files django does the "wrong" thing
|
||||
# and saves it as project-0.1.2.tar_.gz. So remove it before
|
||||
# django sees anything.
|
||||
|
||||
if file:
|
||||
try:
|
||||
previous_entry = Release.objects.get(version=version,
|
||||
release = Release.objects.get(version=version,
|
||||
platform=platform, project=project)
|
||||
if os.path.exists(previous_entry.distribution.path):
|
||||
os.remove(previous_entry.distribution.path)
|
||||
previous_entry.delete()
|
||||
except Release.DoesNotExist:
|
||||
if os.path.exists(release.distribution.path):
|
||||
os.remove(release.distribution.path)
|
||||
release.delete()
|
||||
except (Release.DoesNotExist, ValueError):
|
||||
pass
|
||||
|
||||
|
||||
release, created = Release.objects.get_or_create(version=version,
|
||||
platform=platform,
|
||||
project=project)
|
||||
|
||||
@@ -33,6 +33,7 @@ POSSIBILITY OF SUCH DAMAGE.
|
||||
import os
|
||||
from django.db import models
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
from django.contrib.auth.models import User
|
||||
|
||||
OS_NAMES = (
|
||||
("aix", "AIX"),
|
||||
@@ -85,6 +86,7 @@ class Project(models.Model):
|
||||
description = models.TextField(blank=True)
|
||||
author_email = models.CharField(max_length=255, blank=True)
|
||||
classifiers = models.ManyToManyField(Classifier)
|
||||
owner = models.ForeignKey(User, related_name="projects")
|
||||
|
||||
class Meta:
|
||||
verbose_name = _(u"project")
|
||||
|
||||
+35
-3
@@ -31,13 +31,14 @@ POSSIBILITY OF SUCH DAMAGE.
|
||||
"""
|
||||
|
||||
from django.http import Http404, HttpResponse, HttpResponseBadRequest
|
||||
from django.http import QueryDict
|
||||
from django.http import QueryDict, HttpResponseForbidden
|
||||
from django.shortcuts import render_to_response
|
||||
from djangopypi.models import Project
|
||||
from djangopypi.forms import ProjectRegisterForm
|
||||
from django.template import RequestContext
|
||||
from django.utils.datastructures import MultiValueDict
|
||||
from django.core.files.uploadedfile import SimpleUploadedFile
|
||||
from django.contrib.auth import authenticate, login
|
||||
|
||||
|
||||
def parse_weird_post_data(data):
|
||||
@@ -71,15 +72,46 @@ def parse_weird_post_data(data):
|
||||
return MultiValueDict(post_data), files
|
||||
|
||||
|
||||
def login_basic_auth(request):
|
||||
authentication = request.META.get("HTTP_AUTHORIZATION")
|
||||
if not authentication:
|
||||
return
|
||||
(authmeth, auth) = authentication.split(' ', 1)
|
||||
if authmeth.lower() != "basic":
|
||||
return
|
||||
auth = auth.strip().decode("base64")
|
||||
username, password = auth.split(":", 1)
|
||||
return authenticate(username=username, password=password)
|
||||
|
||||
|
||||
def authorization_required_response():
|
||||
response = HttpResponse("Authorization required",
|
||||
mimetype="text/plain")
|
||||
response['WWW-Authenticate'] = 'Basic realm="pypi"'
|
||||
response.status_code = 401
|
||||
return response
|
||||
|
||||
|
||||
def simple(request, template_name="djangopypi/simple.html"):
|
||||
if request.method == "POST":
|
||||
user = login_basic_auth(request)
|
||||
if not user:
|
||||
return authorization_required_response()
|
||||
login(request, user)
|
||||
if not request.user.is_authenticated():
|
||||
return HttpResponseForbidden(
|
||||
"Not logged in, or invalid username/password.")
|
||||
post_data, files = parse_weird_post_data(request.raw_post_data)
|
||||
action = post_data.get(":action")
|
||||
classifiers = post_data.getlist("classifiers")
|
||||
register_form = ProjectRegisterForm(post_data.copy())
|
||||
if register_form.is_valid():
|
||||
return HttpResponse(register_form.save(classifiers,
|
||||
file=files.get("content")))
|
||||
try:
|
||||
register_form.save(classifiers, request.user,
|
||||
file=files.get("content"))
|
||||
except register_form.PermissionDeniedError:
|
||||
return HttpResonseForbidden(
|
||||
"That project is owned by someone else!")
|
||||
return HttpResponse("Successfully registered.")
|
||||
return HttpResponse("ERRORS: %s" % register_form.errors)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user