권주희

Merge branch 'feature/user' into 'develop'

Feature/user



See merge request !9
1 -# Generated by Django 3.0.7 on 2020-06-04 19:52 1 +# Generated by Django 3.0.6 on 2020-06-11 14:54
2 - 2 +
3 -from django.db import migrations, models 3 +from django.db import migrations, models
4 -import django.db.models.deletion 4 +
5 - 5 +
6 - 6 +class Migration(migrations.Migration):
7 -class Migration(migrations.Migration): 7 +
8 - 8 + initial = True
9 - initial = True 9 +
10 - 10 + dependencies = [
11 - dependencies = [ 11 + ]
12 - ] 12 +
13 - 13 + operations = [
14 - operations = [ 14 + migrations.CreateModel(
15 - migrations.CreateModel( 15 + name='Item',
16 - name='SharedItem', 16 + fields=[
17 - fields=[ 17 + ('item_id', models.AutoField(primary_key=True, serialize=False)),
18 - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), 18 + ('is_folder', models.BooleanField(default=False)),
19 - ('item_id', models.IntegerField()), 19 + ('name', models.CharField(max_length=50)),
20 - ('valid', models.DateTimeField()), 20 + ('file_type', models.CharField(max_length=100, null=True)),
21 - ('password', models.CharField(max_length=20)), 21 + ('path', models.TextField()),
22 - ], 22 + ('parent', models.IntegerField()),
23 - options={ 23 + ('user_id', models.IntegerField()),
24 - 'ordering': ['item_id'], 24 + ('size', models.IntegerField()),
25 - }, 25 + ('is_deleted', models.BooleanField(default=False)),
26 - ), 26 + ('created_time', models.DateTimeField(auto_now=True)),
27 - migrations.CreateModel( 27 + ('updated_time', models.DateTimeField(null=True)),
28 - name='User', 28 + ('status', models.BooleanField()),
29 - fields=[ 29 + ],
30 - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), 30 + options={
31 - ('int_id', models.IntegerField()), 31 + 'ordering': ['item_id'],
32 - ('user_id', models.CharField(max_length=50)), 32 + },
33 - ('name', models.CharField(max_length=50)), 33 + ),
34 - ('password', models.CharField(max_length=20)), 34 + migrations.CreateModel(
35 - ('total_size', models.IntegerField()), 35 + name='SharedItem',
36 - ('current_size', models.IntegerField()), 36 + fields=[
37 - ], 37 + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
38 - options={ 38 + ('item_id', models.IntegerField()),
39 - 'ordering': ['int_id'], 39 + ('expires', models.DateTimeField()),
40 - }, 40 + ('password', models.CharField(max_length=20)),
41 - ), 41 + ('created_time', models.DateTimeField(auto_now=True)),
42 - migrations.CreateModel( 42 + ],
43 - name='Item', 43 + options={
44 - fields=[ 44 + 'ordering': ['item_id'],
45 - ('item_id', models.IntegerField(primary_key=True, serialize=False)), 45 + },
46 - ('is_folder', models.BooleanField(default=False)), 46 + ),
47 - ('name', models.CharField(max_length=50)), 47 + migrations.CreateModel(
48 - ('path', models.TextField()), 48 + name='User',
49 - ('user_id', models.IntegerField()), 49 + fields=[
50 - ('size', models.IntegerField()), 50 + ('int_id', models.AutoField(primary_key=True, serialize=False)),
51 - ('is_deleted', models.BooleanField(default=False)), 51 + ('user_id', models.CharField(max_length=50)),
52 - ('created_time', models.DateTimeField()), 52 + ('name', models.CharField(max_length=50)),
53 - ('updated_time', models.DateTimeField()), 53 + ('password', models.CharField(max_length=20)),
54 - ('status', models.BooleanField()), 54 + ('total_size', models.IntegerField()),
55 - ('parent', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='api.Item')), 55 + ('current_size', models.IntegerField()),
56 - ], 56 + ('created_time', models.DateTimeField(auto_now=True)),
57 - options={ 57 + ],
58 - 'ordering': ['item_id'], 58 + options={
59 - }, 59 + 'ordering': ['int_id'],
60 - ), 60 + },
61 - ] 61 + ),
62 + ]
......
1 -# Generated by Django 3.0.7 on 2020-06-05 09:51 1 +# Generated by Django 3.0.6 on 2020-06-11 15:29
2 - 2 +
3 -from django.db import migrations, models 3 +from django.db import migrations, models
4 - 4 +
5 - 5 +
6 -class Migration(migrations.Migration): 6 +class Migration(migrations.Migration):
7 - 7 +
8 - dependencies = [ 8 + dependencies = [
9 - ('api', '0001_initial'), 9 + ('api', '0001_initial'),
10 - ] 10 + ]
11 - 11 +
12 - operations = [ 12 + operations = [
13 - migrations.AlterField( 13 + migrations.AddField(
14 - model_name='item', 14 + model_name='user',
15 - name='parent', 15 + name='root_folder',
16 - field=models.IntegerField(), 16 + field=models.IntegerField(null=True),
17 - ), 17 + ),
18 - ] 18 + migrations.AlterField(
19 + model_name='item',
20 + name='parent',
21 + field=models.IntegerField(null=True),
22 + ),
23 + ]
......
1 -# Generated by Django 3.0.6 on 2020-06-06 08:17
2 -
3 -from django.db import migrations
4 -
5 -
6 -class Migration(migrations.Migration):
7 -
8 - dependencies = [
9 - ('api', '0002_auto_20200605_1851'),
10 - ]
11 -
12 - operations = [
13 - migrations.RenameField(
14 - model_name='shareditem',
15 - old_name='valid',
16 - new_name='expires',
17 - ),
18 - ]
1 -# Generated by Django 3.0.6 on 2020-06-06 08:24
2 -
3 -from django.db import migrations, models
4 -
5 -
6 -class Migration(migrations.Migration):
7 -
8 - dependencies = [
9 - ('api', '0003_auto_20200606_0817'),
10 - ]
11 -
12 - operations = [
13 - migrations.AddField(
14 - model_name='shareditem',
15 - name='created_time',
16 - field=models.DateTimeField(auto_now=True),
17 - ),
18 - migrations.AddField(
19 - model_name='user',
20 - name='created_time',
21 - field=models.DateTimeField(auto_now=True),
22 - ),
23 - migrations.AlterField(
24 - model_name='item',
25 - name='created_time',
26 - field=models.DateTimeField(auto_now=True),
27 - ),
28 - ]
1 -# Generated by Django 3.0.6 on 2020-06-10 11:50
2 -
3 -from django.db import migrations, models
4 -
5 -
6 -class Migration(migrations.Migration):
7 -
8 - dependencies = [
9 - ('api', '0004_auto_20200606_0824'),
10 - ]
11 -
12 - operations = [
13 - migrations.AlterField(
14 - model_name='item',
15 - name='item_id',
16 - field=models.IntegerField(auto_created=True, primary_key=True, serialize=False),
17 - ),
18 - ]
1 -# Generated by Django 3.0.6 on 2020-06-10 12:09
2 -
3 -from django.db import migrations, models
4 -
5 -
6 -class Migration(migrations.Migration):
7 -
8 - dependencies = [
9 - ('api', '0005_auto_20200610_1150'),
10 - ]
11 -
12 - operations = [
13 - migrations.AlterField(
14 - model_name='item',
15 - name='item_id',
16 - field=models.AutoField(primary_key=True, serialize=False),
17 - ),
18 - ]
1 -# Generated by Django 3.0.6 on 2020-06-10 12:17
2 -
3 -from django.db import migrations, models
4 -
5 -
6 -class Migration(migrations.Migration):
7 -
8 - dependencies = [
9 - ('api', '0006_auto_20200610_1209'),
10 - ]
11 -
12 - operations = [
13 - migrations.AlterField(
14 - model_name='item',
15 - name='updated_time',
16 - field=models.DateTimeField(null=True),
17 - ),
18 - ]
1 -# Generated by Django 3.0.6 on 2020-06-10 13:29
2 -
3 -from django.db import migrations, models
4 -
5 -
6 -class Migration(migrations.Migration):
7 -
8 - dependencies = [
9 - ('api', '0007_auto_20200610_1217'),
10 - ]
11 -
12 - operations = [
13 - migrations.AddField(
14 - model_name='item',
15 - name='file_type',
16 - field=models.CharField(max_length=100, null=True),
17 - ),
18 - ]
...@@ -8,7 +8,7 @@ class Item(models.Model): ...@@ -8,7 +8,7 @@ class Item(models.Model):
8 file_type = models.CharField(max_length=100, null=True) # signed_url 생성을 위해 file type 세팅 8 file_type = models.CharField(max_length=100, null=True) # signed_url 생성을 위해 file type 세팅
9 path = models.TextField() 9 path = models.TextField()
10 #parent = models.ForeignKey('Item', on_delete=models.CASCADE, null=True) #related_name 10 #parent = models.ForeignKey('Item', on_delete=models.CASCADE, null=True) #related_name
11 - parent = models.IntegerField() 11 + parent = models.IntegerField(null=True) # root 폴더의 경우 null임
12 user_id = models.IntegerField() 12 user_id = models.IntegerField()
13 size = models.IntegerField() 13 size = models.IntegerField()
14 is_deleted = models.BooleanField(default = False) 14 is_deleted = models.BooleanField(default = False)
...@@ -33,10 +33,11 @@ class SharedItem(models.Model): ...@@ -33,10 +33,11 @@ class SharedItem(models.Model):
33 33
34 34
35 class User(models.Model): 35 class User(models.Model):
36 - int_id = models.IntegerField() 36 + int_id = models.AutoField(primary_key = True)
37 user_id = models.CharField(max_length = 50) 37 user_id = models.CharField(max_length = 50)
38 name = models.CharField(max_length = 50) 38 name = models.CharField(max_length = 50)
39 password = models.CharField(max_length = 20) 39 password = models.CharField(max_length = 20)
40 + root_folder = models.IntegerField(null=True)
40 total_size = models.IntegerField() 41 total_size = models.IntegerField()
41 current_size = models.IntegerField() 42 current_size = models.IntegerField()
42 created_time = models.DateTimeField(auto_now=True) 43 created_time = models.DateTimeField(auto_now=True)
......
1 -from django.contrib.auth.models import User, Group 1 +from django.contrib.auth.models import Group
2 from rest_framework import serializers 2 from rest_framework import serializers
3 -from api.models import Item, SharedItem 3 +from .models import Item, SharedItem,User
4 4
5 5
6 class UserSerializer(serializers.HyperlinkedModelSerializer): 6 class UserSerializer(serializers.HyperlinkedModelSerializer):
7 class Meta: 7 class Meta:
8 model = User 8 model = User
9 - fields = ['url', 'username', 'email', 'groups'] 9 + fields = '__all__'
10 10
11 class GroupSerializer(serializers.HyperlinkedModelSerializer): 11 class GroupSerializer(serializers.HyperlinkedModelSerializer):
12 class Meta: 12 class Meta:
......
1 import mimetypes 1 import mimetypes
2 import json 2 import json
3 import os 3 import os
4 -from datetime import datetime 4 +from datetime import datetime, timedelta
5 5
6 import boto3 6 import boto3
7 7
8 -from django.contrib.auth.models import User
9 from django.core import serializers 8 from django.core import serializers
10 from django.views.decorators.csrf import csrf_exempt 9 from django.views.decorators.csrf import csrf_exempt
11 from rest_framework import viewsets 10 from rest_framework import viewsets
...@@ -14,10 +13,14 @@ from rest_framework.response import Response ...@@ -14,10 +13,14 @@ from rest_framework.response import Response
14 from rest_framework.decorators import action 13 from rest_framework.decorators import action
15 from rest_framework.permissions import IsAuthenticated, AllowAny 14 from rest_framework.permissions import IsAuthenticated, AllowAny
16 15
17 -from api.models import Item, SharedItem 16 +from .models import Item, SharedItem, User
18 -from api.serializers import UserSerializer,GroupSerializer,ItemSerializer 17 +from .serializers import UserSerializer,GroupSerializer,ItemSerializer
19 from rest_framework import status 18 from rest_framework import status
20 from annoying.functions import get_object_or_None 19 from annoying.functions import get_object_or_None
20 +from django.conf import settings
21 +import jwt
22 +from django.http import HttpResponse, JsonResponse
23 +
21 24
22 class UserViewSet(viewsets.ModelViewSet): 25 class UserViewSet(viewsets.ModelViewSet):
23 """ 26 """
...@@ -25,7 +28,94 @@ class UserViewSet(viewsets.ModelViewSet): ...@@ -25,7 +28,94 @@ class UserViewSet(viewsets.ModelViewSet):
25 """ 28 """
26 queryset = User.objects.all().order_by('-date_joined') 29 queryset = User.objects.all().order_by('-date_joined')
27 serializer_class = UserSerializer 30 serializer_class = UserSerializer
28 - permission_classes = [permissions.IsAuthenticated] 31 + permission_classes = [permissions.IsAuthenticatedOrReadOnly, permissions.AllowAny,
32 + # IsOwnerOrReadOnly
33 + ]
34 + permission_classes_by_action = {'get': [permissions.AllowAny],
35 + 'destroy': [permissions.AllowAny]}
36 + @csrf_exempt
37 + @action(detail=False, methods=['POST'], permission_classes=[permissions.AllowAny], url_path='signup', url_name='singup')
38 + def signup(self, request):
39 + user_id = request.POST.get('user_id', '')
40 + name = request.POST.get('name', '')
41 + password = request.POST.get('password', '')
42 + user = get_object_or_None(User, user_id=user_id)
43 + if user == None:
44 + user = User(user_id = user_id, name = name, password = password, total_size=100000, current_size = 0)
45 + user.save()
46 + root = Item(is_folder=True, name="root", file_type="folder", path="", user_id=user.int_id, size=0,
47 + status=True)
48 + root.save()
49 + return Response({
50 + 'message': 'user created',
51 + 'int_id': user.int_id,
52 + 'user_id': user.user_id,
53 + 'name': user.name,
54 + 'root_folder':root.item_id,
55 + 'total_size': user.total_size,
56 + 'current_size': user.current_size,
57 + 'created_time': user.created_time
58 + },
59 + status=status.HTTP_200_OK,
60 + )
61 + else:
62 + return Response({'message': 'user is already exist.'}, status=status.HTTP_204_NO_CONTENT)
63 +
64 + @csrf_exempt
65 + @action(methods=['post'], detail=False, permission_classes=[permissions.AllowAny],
66 + url_path='login', url_name='login')
67 + def login(self, request):
68 + if not request.data:
69 + return Response({'Error': "Please provide user_id/password"}, status=status.HTTP_400_BAD_REQUEST)
70 + user_id = request.POST['user_id']
71 + password = request.POST['password']
72 + try:
73 + user = User.objects.get(user_id=user_id, password=password)
74 + except User.DoesNotExist:
75 + return Response({'Error': "Invalid user_id/password"}, status=status.HTTP_400_BAD_REQUEST)
76 + if user:
77 + payload1 = {
78 + 'int_id': user.int_id,
79 + 'user_id': user.user_id,
80 + 'exp': datetime.utcnow() + timedelta(seconds=300)
81 + }
82 + payload2 = {
83 + 'int_id': user.int_id,
84 + 'user_id': user.user_id,
85 + 'exp': datetime.utcnow() + timedelta(days=5)
86 + }
87 + access = jwt.encode(payload1, settings.SECRET_KEY, algorithm='HS256').decode('utf-8')
88 + refresh = jwt.encode(payload2, settings.SECRET_KEY, algorithm='HS256').decode('utf-8')
89 + exp = jwt.decode(access, settings.SECRET_KEY, algorithm='HS256')['exp']
90 + token = {'access': access,
91 + 'refresh': refresh,
92 + 'exp': exp}
93 + return JsonResponse(
94 + token,
95 + status=status.HTTP_200_OK,
96 + )
97 + else:
98 + return JsonResponse(
99 + {'Error': "Invalid credentials"},
100 + status=status.HTTP_400_BAD_REQUEST,
101 + )
102 + return JsonResponse(status=status.HTTP_405_METHOD_NOT_ALLOWED)
103 +
104 + def get(self, request, pk):
105 + user = User.objects.filter(int_id=pk)
106 + data = serializers.serialize("json", user)
107 + json_data = json.loads(data)
108 + res = json_data[0]['fields']
109 + res['id']=json_data[0]['pk']
110 + return Response({'data': res}, status=status.HTTP_200_OK)
111 +
112 + def get_permissions(self):
113 + try:
114 + # return permission_classes depending on `action`
115 + return [permission() for permission in self.permission_classes_by_action[self.action]]
116 + except KeyError:
117 + # action is not set return default permission_classes
118 + return [permission() for permission in self.permission_classes]
29 119
30 120
31 class ItemViewSet(viewsets.ViewSet): 121 class ItemViewSet(viewsets.ViewSet):
......
...@@ -34,5 +34,7 @@ urlpatterns = [ ...@@ -34,5 +34,7 @@ urlpatterns = [
34 url(r'^<int:pk>/move/$', views.ItemViewSet.move, name='move'), 34 url(r'^<int:pk>/move/$', views.ItemViewSet.move, name='move'),
35 url(r'^<int:pk>/copy/$', views.ItemViewSet.copy, name='copy'), 35 url(r'^<int:pk>/copy/$', views.ItemViewSet.copy, name='copy'),
36 url(r'^<int:pk>/children/$', views.ItemViewSet.children, name='copy'), 36 url(r'^<int:pk>/children/$', views.ItemViewSet.children, name='copy'),
37 + url(r'^signup/$', views.UserViewSet.signup, name='signup'),
38 + url(r'^login/$', views.UserViewSet.login, name='login'),
37 39
38 ] 40 ]
......