권주희

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
5 4
6 5
7 class Migration(migrations.Migration): 6 class Migration(migrations.Migration):
...@@ -13,12 +12,33 @@ class Migration(migrations.Migration): ...@@ -13,12 +12,33 @@ class Migration(migrations.Migration):
13 12
14 operations = [ 13 operations = [
15 migrations.CreateModel( 14 migrations.CreateModel(
15 + name='Item',
16 + fields=[
17 + ('item_id', models.AutoField(primary_key=True, serialize=False)),
18 + ('is_folder', models.BooleanField(default=False)),
19 + ('name', models.CharField(max_length=50)),
20 + ('file_type', models.CharField(max_length=100, null=True)),
21 + ('path', models.TextField()),
22 + ('parent', models.IntegerField()),
23 + ('user_id', models.IntegerField()),
24 + ('size', models.IntegerField()),
25 + ('is_deleted', models.BooleanField(default=False)),
26 + ('created_time', models.DateTimeField(auto_now=True)),
27 + ('updated_time', models.DateTimeField(null=True)),
28 + ('status', models.BooleanField()),
29 + ],
30 + options={
31 + 'ordering': ['item_id'],
32 + },
33 + ),
34 + migrations.CreateModel(
16 name='SharedItem', 35 name='SharedItem',
17 fields=[ 36 fields=[
18 ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), 37 ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
19 ('item_id', models.IntegerField()), 38 ('item_id', models.IntegerField()),
20 - ('valid', models.DateTimeField()), 39 + ('expires', models.DateTimeField()),
21 ('password', models.CharField(max_length=20)), 40 ('password', models.CharField(max_length=20)),
41 + ('created_time', models.DateTimeField(auto_now=True)),
22 ], 42 ],
23 options={ 43 options={
24 'ordering': ['item_id'], 44 'ordering': ['item_id'],
...@@ -27,35 +47,16 @@ class Migration(migrations.Migration): ...@@ -27,35 +47,16 @@ class Migration(migrations.Migration):
27 migrations.CreateModel( 47 migrations.CreateModel(
28 name='User', 48 name='User',
29 fields=[ 49 fields=[
30 - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), 50 + ('int_id', models.AutoField(primary_key=True, serialize=False)),
31 - ('int_id', models.IntegerField()),
32 ('user_id', models.CharField(max_length=50)), 51 ('user_id', models.CharField(max_length=50)),
33 ('name', models.CharField(max_length=50)), 52 ('name', models.CharField(max_length=50)),
34 ('password', models.CharField(max_length=20)), 53 ('password', models.CharField(max_length=20)),
35 ('total_size', models.IntegerField()), 54 ('total_size', models.IntegerField()),
36 ('current_size', models.IntegerField()), 55 ('current_size', models.IntegerField()),
56 + ('created_time', models.DateTimeField(auto_now=True)),
37 ], 57 ],
38 options={ 58 options={
39 'ordering': ['int_id'], 59 'ordering': ['int_id'],
40 }, 60 },
41 ), 61 ),
42 - migrations.CreateModel(
43 - name='Item',
44 - fields=[
45 - ('item_id', models.IntegerField(primary_key=True, serialize=False)),
46 - ('is_folder', models.BooleanField(default=False)),
47 - ('name', models.CharField(max_length=50)),
48 - ('path', models.TextField()),
49 - ('user_id', models.IntegerField()),
50 - ('size', models.IntegerField()),
51 - ('is_deleted', models.BooleanField(default=False)),
52 - ('created_time', models.DateTimeField()),
53 - ('updated_time', models.DateTimeField()),
54 - ('status', models.BooleanField()),
55 - ('parent', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='api.Item')),
56 - ],
57 - options={
58 - 'ordering': ['item_id'],
59 - },
60 - ),
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
...@@ -10,9 +10,14 @@ class Migration(migrations.Migration): ...@@ -10,9 +10,14 @@ class Migration(migrations.Migration):
10 ] 10 ]
11 11
12 operations = [ 12 operations = [
13 + migrations.AddField(
14 + model_name='user',
15 + name='root_folder',
16 + field=models.IntegerField(null=True),
17 + ),
13 migrations.AlterField( 18 migrations.AlterField(
14 model_name='item', 19 model_name='item',
15 name='parent', 20 name='parent',
16 - field=models.IntegerField(), 21 + field=models.IntegerField(null=True),
17 ), 22 ),
18 ] 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 ]
......