서승완
Builds for 1 pipeline passed in 11 minutes 30 seconds

Merge branch 'usergroup' into 'master'

Usergroup



See merge request !7
1 -from django.http import JsonResponse, Http404 1 +from django.http import Http404, JsonResponse
2 from ..services import files 2 from ..services import files
3 3
4 4
......
1 -from django.http import JsonResponse, Http404 1 +from django.http import Http404, JsonResponse
2 from ..services import groups 2 from ..services import groups
3 3
4 4
......
1 -from django.http import JsonResponse, Http404 1 +from django.http import Http404, JsonResponse
2 from ..services import users 2 from ..services import users
3 3
4 4
......
1 +# -*- coding: utf-8 -*-
2 +# Generated by Django 1.11.29 on 2020-06-13 17:18
3 +from __future__ import unicode_literals
4 +
5 +from django.db import migrations, models
6 +
7 +
8 +class Migration(migrations.Migration):
9 +
10 + dependencies = [
11 + ('khubox', '0001_initial'),
12 + ]
13 +
14 + operations = [
15 + migrations.AlterField(
16 + model_name='user',
17 + name='password',
18 + field=models.CharField(max_length=77),
19 + ),
20 + ]
...@@ -33,7 +33,7 @@ class GroupUser(models.Model): ...@@ -33,7 +33,7 @@ class GroupUser(models.Model):
33 33
34 class User(models.Model): 34 class User(models.Model):
35 email = models.CharField(max_length=255) 35 email = models.CharField(max_length=255)
36 - password = models.CharField(max_length=60) 36 + password = models.CharField(max_length=77)
37 name = models.CharField(max_length=50) 37 name = models.CharField(max_length=50)
38 root_folder = models.CharField(max_length=36) 38 root_folder = models.CharField(max_length=36)
39 created_at = models.DateTimeField() 39 created_at = models.DateTimeField()
......
1 +import json
2 +import uuid
3 +from django.utils import timezone
4 +from ..aws import s3_delete
5 +from ..models import File, Group, GroupUser, User
6 +
7 +
1 # 그룹 생성 8 # 그룹 생성
2 def create(request): 9 def create(request):
3 - return {'result': True} 10 + # TODO: Auth
11 + request.user_id = 1
12 +
13 + # Load
14 + try:
15 + received = json.loads(request.body.decode('utf-8'))
16 + except json.decoder.JSONDecodeError:
17 + return {'result': False, 'error': '입력이 잘못되었습니다.'}
18 +
19 + # Validate
20 + if 'name' not in received or received['name'] == '':
21 + return {'result': False, 'error': '입력이 누락되었습니다.'}
22 +
23 + # Create
24 + root_folder = uuid.uuid4()
25 + group = Group.objects.create(
26 + owner_id=request.user_id,
27 + name=received['name'],
28 + root_folder=root_folder,
29 + invite_code=uuid.uuid4(),
30 + created_at=timezone.now()
31 + )
32 + GroupUser.objects.create(
33 + group_id=group.id,
34 + user_id=request.user_id,
35 + joined_at=timezone.now()
36 + )
37 + File.objects.create(
38 + id=root_folder,
39 + owner_user_id=request.user_id,
40 + owner_group_id=group.id,
41 + type='folder',
42 + name='group_%s' % group.id,
43 + size=0,
44 + created_at=timezone.now()
45 + )
46 +
47 + return {'result': True, 'group_id': group.id}
4 48
5 49
6 # 그룹 초대장 조회 50 # 그룹 초대장 조회
7 def find_invite(request, invite_code): 51 def find_invite(request, invite_code):
8 - return {'result': True} 52 + # TODO: Auth
53 + request.user_id = 1
54 +
55 + # Query
56 + group = Group.objects.filter(invite_code=invite_code)
57 +
58 + # Check Exists
59 + if len(group) == 0:
60 + return {'result': False, 'error': '존재하지 않는 초대장입니다.'}
61 +
62 + # Structure
63 + data = {
64 + 'id': group[0].id,
65 + 'name': group[0].name
66 + }
67 +
68 + # Check Joined
69 + joined = GroupUser.objects.filter(group_id=group[0].id, user_id=request.user_id)
70 + if len(joined) == 0:
71 + data['joined'] = False
72 + else:
73 + data['joined'] = True
74 +
75 + return {'result': True, 'data': data}
9 76
10 77
11 # 그룹 초대장 사용 78 # 그룹 초대장 사용
12 def use_invite(request, invite_code): 79 def use_invite(request, invite_code):
80 + # TODO: Auth
81 + request.user_id = 1
82 +
83 + # Query
84 + group = Group.objects.filter(invite_code=invite_code)
85 +
86 + # Check Exists
87 + if len(group) == 0:
88 + return {'result': False, 'error': '존재하지 않는 초대장입니다.'}
89 +
90 + # Check Joined
91 + joined = GroupUser.objects.filter(group_id=group[0].id, user_id=request.user_id)
92 + if len(joined) != 0:
93 + return {'result': False, 'error': '이미 가입된 그룹입니다.'}
94 +
95 + # Join
96 + GroupUser.objects.create(
97 + group_id=group[0].id,
98 + user_id=request.user_id,
99 + joined_at=timezone.now()
100 + )
101 +
13 return {'result': True} 102 return {'result': True}
14 103
15 104
16 # 그룹 목록 105 # 그룹 목록
17 def list_me(request): 106 def list_me(request):
18 - return {'result': True} 107 + # TODO: Auth
108 + request.user_id = 1
109 +
110 + # Query
111 + joined = GroupUser.objects.filter(user_id=request.user_id).values_list('group_id', flat=True)
112 + groups = Group.objects.filter(id__in=joined)
113 +
114 + # Structure
115 + data = []
116 + for group in groups:
117 + data.append({
118 + 'id': group.id,
119 + 'name': group.name,
120 + 'root_folder': group.root_folder,
121 + })
122 +
123 + return {'result': True, 'data': data}
19 124
20 125
21 # 그룹 조회 126 # 그룹 조회
22 def find_item(request, group_id): 127 def find_item(request, group_id):
23 - return {'result': True} 128 + # TODO: Auth
129 + request.user_id = 1
130 +
131 + # Check Joined
132 + joined = GroupUser.objects.filter(group_id=group_id, user_id=request.user_id)
133 + if len(joined) == 0:
134 + return {'result': False, 'error': '입력이 잘못되었습니다.'}
135 +
136 + # Query
137 + group = Group.objects.filter(id=group_id)
138 +
139 + # Check Exists
140 + if len(group) == 0:
141 + return {'result': False, 'error': '존재하지 않는 그룹입니다.'}
142 +
143 + # Structure
144 + data = {
145 + 'id': group[0].id,
146 + 'name': group[0].name,
147 + 'root_folder': group[0].root_folder,
148 + }
149 +
150 + # If Owner
151 + if group[0].owner_id == request.user_id:
152 + user_ids = GroupUser.objects.filter(group_id=group_id).values_list('user_id', flat=True)
153 + users = User.objects.filter(id__in=user_ids)
154 + user_data = []
155 + for user in users:
156 + user_data.append({
157 + 'id': user.id,
158 + 'name': user.name,
159 + })
160 + data['user'] = user_data
161 + data['invite_code'] = group[0].invite_code
162 + data['created_at'] = group[0].created_at
163 + data['is_owner'] = True
164 +
165 + return {'result': True, 'data': data}
24 166
25 167
26 # 그룹 수정 168 # 그룹 수정
27 def update_item(request, group_id): 169 def update_item(request, group_id):
170 + # TODO: Auth
171 + request.user_id = 1
172 +
173 + # Load
174 + try:
175 + received = json.loads(request.body.decode('utf-8'))
176 + except json.decoder.JSONDecodeError:
177 + return {'result': False, 'error': '입력이 잘못되었습니다.'}
178 +
179 + # Validate
180 + if 'name' not in received or received['name'] == '':
181 + return {'result': False, 'error': '입력이 누락되었습니다.'}
182 +
183 + # Query
184 + group = Group.objects.filter(id=group_id)
185 +
186 + # Check Exists
187 + if len(group) == 0:
188 + return {'result': False, 'error': '존재하지 않는 그룹입니다.'}
189 +
190 + # Check Owner
191 + if group[0].owner_id != request.user_id:
192 + return {'result': False, 'error': '권한이 없습니다.'}
193 +
194 + # Update
195 + group[0].name = received['name']
196 + group[0].save()
197 +
28 return {'result': True} 198 return {'result': True}
29 199
30 200
31 # 그룹 삭제 201 # 그룹 삭제
32 def delete_item(request, group_id): 202 def delete_item(request, group_id):
203 + # TODO: Auth
204 + request.user_id = 1
205 +
206 + # Query
207 + group = Group.objects.filter(id=group_id)
208 +
209 + # Check Exists
210 + if len(group) == 0:
211 + return {'result': False, 'error': '존재하지 않는 그룹입니다.'}
212 +
213 + # Check Owner
214 + if group[0].owner_id != request.user_id:
215 + return {'result': False, 'error': '권한이 없습니다.'}
216 +
217 + # S3 Delete
218 + del_list = File.objects.filter(owner_group_id=group_id).values_list('id', flat=True)
219 + s3_delete(del_list)
220 +
221 + # Delete
222 + del_list.update(is_trashed=1, deleted_at=timezone.now())
223 + GroupUser.objects.filter(group_id=group_id).delete()
224 + Group.objects.filter(id=group_id).delete()
225 +
33 return {'result': True} 226 return {'result': True}
34 227
35 228
36 # 그룹 사용자 삭제 229 # 그룹 사용자 삭제
37 def remove_user(request, group_id, user_id): 230 def remove_user(request, group_id, user_id):
231 + # TODO: Auth
232 + request.user_id = 1
233 +
234 + # Query
235 + group = Group.objects.filter(id=group_id)
236 +
237 + # Check Owner
238 + if group[0].owner_id != request.user_id:
239 + return {'result': False, 'error': '권한이 없습니다.'}
240 +
241 + # Check Me
242 + if int(user_id) == request.user_id:
243 + return {'result': False, 'error': '본인은 삭제할 수 없습니다.'}
244 +
245 + # Remove
246 + GroupUser.objects.filter(group_id=group_id, user_id=user_id).delete()
247 +
38 return {'result': True} 248 return {'result': True}
......
1 +import datetime
2 +import json
3 +import jwt
4 +import uuid
5 +from django.conf import settings
6 +from django.contrib.auth.hashers import make_password, check_password
7 +from django.core.exceptions import ValidationError
8 +from django.core.validators import validate_email
9 +from django.utils import timezone
10 +from ..models import File, User
11 +
12 +
1 # 회원가입 13 # 회원가입
2 def create(request): 14 def create(request):
15 + # Load
16 + try:
17 + received = json.loads(request.body.decode('utf-8'))
18 + except json.decoder.JSONDecodeError:
19 + return {'result': False, 'error': '입력이 잘못되었습니다.'}
20 +
21 + # Validate
22 + if 'email' not in received \
23 + or 'password' not in received \
24 + or 'name' not in received:
25 + return {'result': False, 'error': '입력이 누락되었습니다.'}
26 +
27 + # Validate Email
28 + try:
29 + validate_email(received['email'])
30 + except ValidationError:
31 + return {'result': False, 'error': '이메일 형식이 잘못되었습니다.'}
32 +
33 + # Validate Password
34 + if len(received['password']) < 8:
35 + return {'result': False, 'error': '비밀번호는 최소 8글자 입니다.'}
36 +
37 + # Validate Name
38 + if len(received['name']) > 50:
39 + return {'result': False, 'error': '이름은 최대 50글자 입니다.'}
40 +
41 + # Check Duplicates
42 + is_exists = User.objects.filter(email=received['email'])
43 + if len(is_exists) > 0:
44 + return {'result': False, 'error': '이미 사용중인 이메일 주소 입니다.'}
45 +
46 + # Insert
47 + root_folder = uuid.uuid4()
48 + user = User.objects.create(
49 + email=received['email'],
50 + password=make_password(received['password']),
51 + name=received['name'],
52 + root_folder=root_folder,
53 + created_at=timezone.now()
54 + )
55 + File.objects.create(
56 + id=root_folder,
57 + owner_user_id=user.id,
58 + type='folder',
59 + name='user_%s' % user.id,
60 + size=0,
61 + created_at=timezone.now()
62 + )
63 +
3 return {'result': True} 64 return {'result': True}
4 65
5 66
6 # 로그인 67 # 로그인
7 def login(request): 68 def login(request):
8 - return {'result': True} 69 + # Load
70 + try:
71 + received = json.loads(request.body.decode('utf-8'))
72 + except json.decoder.JSONDecodeError:
73 + return {'result': False, 'error': '입력이 잘못되었습니다.'}
74 +
75 + # Validate
76 + if 'email' not in received \
77 + or 'password' not in received:
78 + return {'result': False, 'error': '입력이 누락되었습니다.'}
79 +
80 + # Select
81 + user = User.objects.filter(email=received['email'])
82 +
83 + # Not Exists
84 + if len(user) != 1:
85 + return {'result': False, 'error': '로그인에 실패하였습니다.'}
86 +
87 + # Check
88 + if check_password(received['password'], user[0].password) is False:
89 + return {'result': False, 'error': '로그인에 실패하였습니다.'}
90 +
91 + # Token Generate
92 + token = jwt.encode({'id': user[0].id, 'exp': datetime.datetime.utcnow() + datetime.timedelta(hours=6)},
93 + key=settings.SECRET_KEY, algorithm='HS256')
94 +
95 + return {'result': True, 'token': token.decode('utf-8')}
9 96
10 97
11 # 회원정보 조회 98 # 회원정보 조회
12 def find_me(request): 99 def find_me(request):
13 - return {'result': True} 100 + # TODO: Auth
101 + request.user_id = 1
102 +
103 + # Query
104 + user = User.objects.filter(id=request.user_id)
105 +
106 + # Check Exists
107 + if len(user) != 1:
108 + return {'result': False, 'error': '잘못된 요청입니다.'}
109 +
110 + # Serialize
111 + data = {
112 + 'id': user[0].id,
113 + 'email': user[0].email,
114 + 'name': user[0].name,
115 + 'root_folder': user[0].root_folder,
116 + 'created_at': user[0].created_at
117 + }
118 +
119 + return {'result': True, 'data': data}
14 120
15 121
16 # 회원정보 수정 122 # 회원정보 수정
17 def update_me(request): 123 def update_me(request):
124 + # TODO: Auth
125 + request.user_id = 1
126 +
127 + # Load
128 + try:
129 + received = json.loads(request.body.decode('utf-8'))
130 + except json.decoder.JSONDecodeError:
131 + return {'result': False, 'error': '입력이 잘못되었습니다.'}
132 +
133 + # Validate
134 + if 'name' not in received \
135 + and ('old_password' not in received and 'password' not in received):
136 + return {'result': False, 'error': '입력이 누락되었습니다.'}
137 +
138 + # Query
139 + user = User.objects.filter(id=request.user_id)
140 +
141 + # Check Exists
142 + if len(user) != 1:
143 + return {'result': False, 'error': '잘못된 요청입니다.'}
144 +
145 + # Change Name
146 + if 'name' in received:
147 + user[0].name = received['name']
148 +
149 + # Change Password
150 + if 'old_password' in received and 'password' in received:
151 + if check_password(received['old_password'], user[0].password) is False:
152 + return {'result': False, 'error': '이전 비밀번호가 잘못되었습니다.'}
153 + if len(received['password']) < 8:
154 + return {'result': False, 'error': '비밀번호는 최소 8글자 입니다.'}
155 + user[0].password = make_password(received['password'])
156 +
157 + # Save
158 + user[0].save()
159 +
18 return {'result': True} 160 return {'result': True}
......
...@@ -20,6 +20,7 @@ jmespath==0.10.0 ...@@ -20,6 +20,7 @@ jmespath==0.10.0
20 pip-tools==5.1.2 20 pip-tools==5.1.2
21 placebo==0.9.0 21 placebo==0.9.0
22 pycparser==2.20 22 pycparser==2.20
23 +PyJWT==1.7.1
23 PyMySQL==0.9.3 24 PyMySQL==0.9.3
24 python-dateutil==2.6.1 25 python-dateutil==2.6.1
25 python-slugify==4.0.0 26 python-slugify==4.0.0
......