Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Tasks done #17

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions api/migrations/0003_todo_collaborators.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# Generated by Django 3.0.7 on 2021-08-07 09:21

from django.conf import settings
from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
('api', '0002_todo_creator'),
]

operations = [
migrations.AddField(
model_name='todo',
name='collaborators',
field=models.ManyToManyField(related_name='collabs', to=settings.AUTH_USER_MODEL),
),
]
1 change: 1 addition & 0 deletions api/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
class Todo(models.Model):
creator = models.ForeignKey(User, on_delete=models.CASCADE)
title = models.CharField(max_length=255)
collaborators = models.ManyToManyField(User, related_name = 'collabs')

def __str__(self):
return self.title
30 changes: 28 additions & 2 deletions api/serializers.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from rest_framework import serializers
from .models import Todo

from django.contrib.auth.models import User

"""
TODO:
Expand All @@ -23,7 +23,33 @@ def save(self, **kwargs):
user = self.context['request'].user
title = data['title']
todo = Todo.objects.create(creator=user, title=title)

response = {
"id": todo.id,
"title": todo.title,
}
return response

class Meta:
model = Todo
fields = ('id', 'title',)

class TodoCommonSerializer(serializers.ModelSerializer):
class Meta:
model = Todo
fields = ('id', 'title',)

class TodoListSerializer(serializers.ModelSerializer):
class Meta:
model = Todo
fields = ('id', 'title', 'collaborators',)

class UserCollabSerializer(serializers.ModelSerializer):
class Meta:
model = User
fields = ('username',)

class TodoCollabSerializer(serializers.ModelSerializer):
collaborators = UserCollabSerializer(read_only=True, many=True)
class Meta:
model = Todo
fields = ('id', 'collaborators',)
6 changes: 5 additions & 1 deletion api/urls.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from django.urls import path
from .views import TodoCreateView
from .views import *

"""
TODO:
Expand All @@ -9,4 +9,8 @@

urlpatterns = [
path('todo/create/', TodoCreateView.as_view()),
path('todo/', TodoListView.as_view()),
path('todo/<int:id>/', TodoDetailView.as_view()),
path('todo/<int:id>/add-collaborators/', TodoAddCollabView.as_view()),
path('todo/<int:id>/remove-collaborators/', TodoDeleteCollabView.as_view()),
]
77 changes: 72 additions & 5 deletions api/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,23 @@
from rest_framework import permissions
from rest_framework import status
from rest_framework.response import Response
from .serializers import TodoCreateSerializer
from .serializers import *
from .models import Todo

from django.contrib.auth.models import User

"""
TODO:
Create the appropriate View classes for implementing
Todo GET (List and Detail), PUT, PATCH and DELETE.
"""

class CustomPermission(permissions.BasePermission):
def has_object_permission(self, request, view, obj):
if(request.method == "POST"):
return True
todo = Todo.objects.get(id=obj.id)
if(todo.creator == request.user or request.user in todo.collaborators.all()):
return True
return False

class TodoCreateView(generics.GenericAPIView):
"""
Expand All @@ -31,5 +38,65 @@ def post(self, request):
"""
serializer = self.get_serializer(data=request.data)
serializer.is_valid(raise_exception=True)
serializer.save()
return Response(status=status.HTTP_200_OK)
response = serializer.save()
return Response(response,status=status.HTTP_200_OK)

class TodoListView(generics.GenericAPIView):
permission_classes = (permissions.IsAuthenticated, )
serializer_class = TodoListSerializer

def get(self, request):
queryset_cr = Todo.objects.filter(creator = request.user)
queryset_co = Todo.objects.filter(collaborators=request.user)

serializer_cr = self.get_serializer(queryset_cr,many=True)
serializer_co = self.get_serializer(queryset_co,many=True)

response = {
"CREATOR" :
serializer_cr.data,
"COLLABORATOR" :
serializer_co.data,
}
return Response(response,status=status.HTTP_200_OK)


class TodoDetailView(generics.RetrieveUpdateDestroyAPIView, CustomPermission):
permission_classes = (permissions.IsAuthenticated, CustomPermission)
serializer_class = TodoCommonSerializer
lookup_url_kwarg = 'id'
queryset = Todo.objects.all()


class TodoAddCollabView(generics.GenericAPIView):
permission_classes = (permissions.IsAuthenticated,)
serializer_class = TodoCollabSerializer

def patch(self, request, id):
todo = Todo.objects.get(id=id)
if(request.user == todo.creator):
username = request.data['username']
user = User.objects.get(username=username)
if(user != request.user):
todo.collaborators.add(user)
serializer_class = self.get_serializer(todo,data=request.data)
serializer_class.is_valid(raise_exception=True)
return Response(serializer_class.data, status = status.HTTP_200_OK)
return Response({"Error": "You are already the creator of this todo"}, status = status.HTTP_400_BAD_REQUEST)
return Response({"Error": "You are not the creator of this todo"}, status = status.HTTP_403_FORBIDDEN)


class TodoDeleteCollabView(generics.GenericAPIView):
permission_classes = (permissions.IsAuthenticated, )
serializer_class = TodoCollabSerializer

def patch(self, request, id):
todo = Todo.objects.get(id=id)
if(request.user == todo.creator):
username = request.data['username']
user = User.objects.get(username=username)
todo.collaborators.remove(user)
serializer_class = self.get_serializer(todo,data=request.data)
serializer_class.is_valid(raise_exception=True)
return Response(serializer_class.data, status = status.HTTP_200_OK)
return Response({"Error": "You are not the creator of this todo"}, status = status.HTTP_403_FORBIDDEN)
33 changes: 29 additions & 4 deletions authentication/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,40 @@ class TokenSerializer(serializers.Serializer):

class LoginSerializer(serializers.Serializer):
# TODO: Implement login functionality
pass
def save(self,data):
user = authenticate(username=data['username'], password=data['password'])
if(not user):
raise serializers.ValidationError({'Error': 'Incorrect password or username!'})
else:
return user

class Meta:
model = User
fields = ( 'username', 'password',)


class RegisterSerializer(serializers.Serializer):
# TODO: Implement register functionality
pass

def save(self, data):
if(User.objects.filter(username=data['username']).exists()):
raise serializers.ValidationError({'Error': 'Username already exists!'})
else:
user = User.objects.create_user(
first_name = data['name'],
email = data['email'],
username = data['username'],
password = data['password'],)
return user

class Meta:
model = User
fields = ( 'first_name', 'email', 'username', 'password',)


class UserSerializer(serializers.ModelSerializer):
# TODO: Implement the functionality to display user details
pass

name = serializers.CharField(source='first_name')
class Meta:
model = User
fields = ( 'id','name', 'email', 'username',)
41 changes: 36 additions & 5 deletions authentication/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@
from rest_framework.authtoken.models import Token
from .serializers import (
LoginSerializer, RegisterSerializer, UserSerializer, TokenSerializer)

from django.contrib.auth import login
from django.contrib.auth.models import User

def create_auth_token(user):
"""
Expand All @@ -21,16 +22,40 @@ class LoginView(generics.GenericAPIView):
Implement login functionality, taking username and password
as input, and returning the Token.
"""
pass

queryset = User.objects.all()
serializer_class = LoginSerializer

def post(self , request):
serializer_class = self.get_serializer(data=request.data)
serializer_class.is_valid(raise_exception=True)
user = serializer_class.save(request.data)
token = create_auth_token(user)
login(request, user)
response = {
'token' : token.key
}
return Response(response, status = status.HTTP_200_OK)

class RegisterView(generics.GenericAPIView):
"""
TODO:
Implement register functionality, registering the user by
taking his details, and returning the Token.
"""
pass
queryset = User.objects.all()
serializer_class = RegisterSerializer

def post(self, request):
serializer_class = self.get_serializer(data=request.data)
serializer_class.is_valid(raise_exception=True)
user = serializer_class.save(request.data)
token = create_auth_token(user)
login(request, user)
response = {
'token' : token.key
}
return Response(response, status = status.HTTP_200_OK)



class UserProfileView(generics.RetrieveAPIView):
Expand All @@ -39,4 +64,10 @@ class UserProfileView(generics.RetrieveAPIView):
Implement the functionality to retrieve the details
of the logged in user.
"""
pass
permission_classes = (permissions.IsAuthenticated,)
queryset = User.objects.all()
serializer_class = UserSerializer
def post(self, request):
serializer_class = self.get_serializer(request.user)
return Response(serializer_class.data, status = status.HTTP_200_OK)