def delete(self, request, note_id): """ This API is used to delete collaborator's self email from collaborator list @param note_id: specific note id @return: deletes collaborator's self email from collaborator list """ try: note = Notes.objects.get(id=note_id) if request.user.email in note.collaborators['collaborators']: note.collaborators['collaborators'].remove(request.user.email) if not len(note.collaborators['collaborators']): note.collaborators = None note.save() logger.info('collaborator removes self email') return Response( { 'response_msg': "You have removed yourself from the collaborator" }, status=status.HTTP_200_OK) logger.warning( 'unauthorised access to delete collaborator self email') return Response({'response_msg': "Unauthorised access"}, status=status.HTTP_401_UNAUTHORIZED) except Notes.DoesNotExist: logger.info('note is not found') return Response({'response_msg': 'Note not found'}, status=status.HTTP_404_NOT_FOUND)
def put(self, request): """ This API is used to update user profile @param: user profile data @return: updates user profile """ serializer = self.serializer_class(data=request.data) if serializer.is_valid(): try: profile = Profile.objects.get(user=request.user.pk) user = User.objects.get(pk=request.user.pk) profile.bio = serializer.data.get('bio') profile.dob = serializer.data.get('dob') profile.save() user.first_name = serializer.data.get('firstName') user.last_name = serializer.data.get('lastName') user.save() msg = "Your Profile is updated" logger.info(f"{user.username}'s profile is updated") return Response({'response_msg':msg},status=status.HTTP_200_OK) except Profile.DoesNotExist as e: msg = "Some error occurred" logger.error(e) return Response({'response_msg': msg}, status=status.HTTP_403_FORBIDDEN) logger.error(serializer.errors) return Response({'response_msg': serializer.errors}, status=status.HTTP_400_BAD_REQUEST)
def put(self, request, uid, token): """ This API is used to reset user password @param: uid and token fetched for get request @return: reset user password """ serializer = self.serializer_class(data=request.data) if serializer.is_valid(): password = serializer.data.get('password') response = JWTAuth.verifyToken(jwtToken=token) if not response: msg = 'Session for this token is expired!' logger.info('Token session expired!') return Response({'response_msg':msg}, status=status.HTTP_403_FORBIDDEN) username=response.get('username') try: user = User.objects.get(username=username) user.set_password(raw_password=password) user.save() TokenBlackLists(token=token).save() msg = 'Your password is reset successfully !' logger.info(f"{username}'s password reset successfully") return Response({'response_msg':msg}, status=status.HTTP_200_OK) except Exception as e: msg = 'Something went wrong !' logger.error(e) return Response({'response_msg':msg}, status=status.HTTP_403_FORBIDDEN) logger.error(serializer.errors) return Response({'response_msg': serializer.errors}, status=status.HTTP_400_BAD_REQUEST)
def delete(self, request, note_id): """ This API is used to delete and trash existing note @param note_id: primary_key of the specific note @return: trash or delete the note if it is already trashed """ try: note = Notes.objects.get(Q(pk=note_id) & Q(user=request.user)) cache = Cache.getCacheInstance() cache.delete(f'user-{request.user.id}-note-{note.id}') if note.is_trash: note.delete() logger.info("Note is deleted permanently") return Response( {'response_msg': 'Your Note is deleted permanently'}, status=status.HTTP_200_OK) else: note.is_trash = True note.trashed_time = datetime.now() note.save() logger.info("Note is Trashed") return Response({'response_msg': 'Your Note is trashed'}, status=status.HTTP_200_OK) except Notes.DoesNotExist: logger.warning("Note does not exist") return Response({'response_msg': 'This Note is not exist'}, status=status.HTTP_404_NOT_FOUND)
def get(self, request): """ This api is for user log out @return: release all resources from user on logged out """ logout(request) msg = 'You are logged out successfully' logger.info(f"{request.user.username} is logged out") return Response({'response_msg':msg},status=status.HTTP_204_NO_CONTENT)
def get(self, request): """ This api is used to fetch user profile @return: User profile data """ user = User.objects.get(pk=request.user.pk) userSerializer = dict(UserDataSerializer(user).data) profileSerializer = UserProfileSerializer(request.user.profile) userSerializer.update(profileSerializer.data) logger.info(f"{request.user.username}'s profile is accessed") return Response({'response_msg':userSerializer},status=status.HTTP_200_OK)
def get(self, request): """ This API is used to get all existing label created by the user @param request: Get request @return: returns all existing label """ label_data = Label.objects.filter(Q(user=request.user)) serializer = self.serializer_class(label_data, many=True) if not serializer.data: logger.info("No label found") return Response({'response_data': 'No labels found'}, status=status.HTTP_404_NOT_FOUND) logger.info("All labels are accessed") return Response({'response_data': serializer.data}, status=status.HTTP_200_OK)
def delete(self, request): """ This API is used to delete current profile picture and reset to default @return: """ image_name = request.user.profile.image.name if image_name != 'profile_pics/default.jpg': actual_path = os.path.join(os.getcwd(), 'media',image_name ) os.remove(actual_path) request.user.profile.image = 'profile_pics/default.jpg' request.user.profile.save() logger.info(f"{request.user.username}'s profile picture is deleted") return Response({'response_msg': "Profile picture is deleted"}, status=status.HTTP_200_OK) logger.info("No profile picture is found to be deleted") return Response({'response_msg':'No image to be deleted'}, status=status.HTTP_400_BAD_REQUEST)
def get(self, request): """ This API is used to get all trashed notes @param request: get request @return: Returns all trashed notes """ notes = Notes.objects.filter( Q(user=request.user.pk) & Q(is_trash=True)) if not notes: logger.info(f"Trash is empty") return Response({'response_data': 'No notes in Trash'}, status=status.HTTP_404_NOT_FOUND) serializer = self.serializer_class(notes, many=True) logger.info(f"All trashed notes are accessed") return Response({'response_data': serializer.data}, status=status.HTTP_200_OK)
def post(self, request): """ This API is used to create a note for user @param request: It takes note title, content, label(optional) and color(optional) @return: creates not on successful validation """ serializer = self.serializer_class(data=request.data, context={'user': request.user}) if serializer.is_valid(): serializer.save() logger.info(f"{request.user.username}'s note is saved") return Response({'response_msg': 'Your note is saved'}, status=status.HTTP_201_CREATED) logger.error(serializer.errors) return Response({'response_msg': serializer.errors}, status=status.HTTP_400_BAD_REQUEST)
def get(self, request): """ This API is used to fetch all reminder notes of the user @return: returns all notes """ Reminder_Notes = ReminderNotes.objects.filter(is_trash=False).\ filter(Q(user=request.user.pk) | Q(collaborators__icontains=request.user.email)).exclude(reminder=None) if not Reminder_Notes: logger.info(f"{request.user.username}'s no notes present") return Response({'response_data': 'No reminder notes available'}, status=status.HTTP_404_NOT_FOUND) serializer = self.serializer_class( Reminder_Notes, many=True, context={'email': request.user.email}) logger.info(f"{request.user.username}'s reminder notes accessed") return Response({'response_data': serializer.data}, status=status.HTTP_200_OK)
def post(self, request): """ This API is used to create a label @param request: label name @return: Creates label """ serializer = self.serializer_class(data=request.data, context={'user': request.user}) if serializer.is_valid(): Label(user=request.user, label_name=serializer.data.get('label_name')).save() logger.info("label created") return Response({'response_msg': 'Label added'}, status=status.HTTP_201_CREATED) logger.error(serializer.errors) return Response({'response_msg': serializer.errors}, status=status.HTTP_400_BAD_REQUEST)
def delete(self, request, note_id): """ This API is used to remove reminder @param note_id: primary_key of specific note @return: removes reminder """ try: note = Notes.objects.get(id=note_id, user=request.user.id) except Notes.DoesNotExist: logger.info('Note not found') return Response({'response_msg': 'Note Not Found'}, status=status.HTTP_404_NOT_FOUND) note.reminder = None note.save() logger.info('Reminder is removed') return Response({'response_msg': 'Reminder is removed'}, status=status.HTTP_200_OK)
def get(self, request): """ This API is used to search notes by serch query @param request: search query @return: returns the note if match found """ query = request.GET.get('query') if not query: logger.info('Query string is blank') return Response({'response_msg': 'Cant Process blank request'}, status=status.HTTP_400_BAD_REQUEST) querylist = query.split(' ') cache = Cache.getCacheInstance() datalist = [] cache_flag = False for key in cache.keys('*'): # checkig if data is available in cache if f'user-{request.user.id}-note-' in str(key): data = json.loads( cache.hmget(name=key.decode('utf-8'), keys='noteObj')[0]) for query in querylist: if query.lower() in data['title'].lower() or query.lower( ) in data['content'].lower(): cache_flag = True datalist.append(data) if cache_flag: break if cache_flag: logger.info('Notes accessed from cache') return Response({'response_msg': datalist}, status=status.HTTP_200_OK) for query in querylist: notes = Notes.objects.filter( Q(title__icontains=query) | Q(content__icontains=query) | Q(color__icontains=query)).filter(user=request.user.pk, is_trash=False) if len(notes): break serializer = self.serializer_class(notes, many=True) note_ids = [] for note in notes: note_ids.append(note.id) note_ids = iter(note_ids) for note in serializer.data: id_no = next(note_ids) cache.hmset(f'user-{request.user.id}-note-{id_no}', {'noteObj': json.dumps(note)}) cache.expire(f'user-{request.user.id}-note-{id_no}', time=timedelta(days=3)) if len(serializer.data): logger.info('Notes accessed from database') return Response({'response_msg': serializer.data}, status=status.HTTP_200_OK) logger.info('Search result not found') return Response({'response_msg': 'Search results not found'}, status=status.HTTP_404_NOT_FOUND)
def patch(self, request, note_id): """ This API is used to restore trashed note @param note_id: primary_key of the specific note @return: Restores the note """ try: note = Notes.objects.get( Q(pk=note_id) & Q(user=request.user.pk) & Q(is_trash=True)) note.is_trash = False note.save() logger.info("Note is restored") return Response({'response_msg': 'Your Note is restored'}, status=status.HTTP_200_OK) except Notes.DoesNotExist: logger.info("Note does not exist") return Response({'response_msg': 'This Note is not exist'}, status=status.HTTP_404_NOT_FOUND)
def delete(self, request, label_name): """ This API is used to delete a specific label @param label_name: specific label name to be deleted @return: deletes label """ try: label = Label.objects.get( Q(label_name=label_name) & Q(user_id=request.user.pk)) label.delete() logger.info(f"{label_name} label is deleted") return Response({'response_msg': 'Label deleted'}, status=status.HTTP_200_OK) except Label.DoesNotExist: logger.info(f"{label_name} label does not exist") return Response( {'response_msg': f'{label_name} label is not exist'}, status=status.HTTP_404_NOT_FOUND)
def put(self, request): """ This API is used to change user password """ serializer = self.serializer_class(data=request.data) if serializer.is_valid(): user = User.objects.get(pk=request.user.pk) if check_password(serializer.data.get('old_password'), user.password): user.set_password(raw_password=serializer.data.get('password')) user.save() msg = "Your password is changed" logger.info(f"{user.username}'s password changed") return Response({'response_msg':msg}, status=status.HTTP_200_OK) msg = "Old password does not match!" logger.warning(f"{user.username}'s old password does not match") return Response({'response_msg':msg}, status=status.HTTP_401_UNAUTHORIZED) logger.error(serializer.errors) return Response({'msg': serializer.errors["non_field_errors"][0]}, status=status.HTTP_400_BAD_REQUEST)
def put(self, request): """ This api is used to update user profile picture @param: profile picture @return: updates profile picture """ if request.FILES: img = request.FILES['image'] serializer = self.serializer_class(data={'image':img}) serializer.is_valid(raise_exception=True) old_image_name = request.user.profile.image.name if old_image_name != 'profile_pics/default.jpg': actual_path = os.path.join(os.getcwd(), 'media', old_image_name) os.remove(actual_path) request.user.profile.image = img request.user.profile.save() logger.info(f"{request.user.username}'s profile picture is updated") return Response({'response_msg':'Your profile picture is uploaded'}, status=status.HTTP_200_OK) logger.error("Blank image filed is found on put request") return Response({'response_msg':'select a file'}, status=status.HTTP_400_BAD_REQUEST)
def post(self, request, label_name): """ This API is used to create label specific notes @param label_name: existing specific label name @return: creates note for this specific label """ serializer = self.serializer_class( data=request.data, context={'email': request.user.email}) if serializer.is_valid(): try: label = Label.objects.get( Q(label_name=label_name) & Q(user_id=request.user.pk)) note = Notes(user=request.user, title=serializer.data.get('title'), content=serializer.data.get('content'), color=serializer.data.get('color')) collaborators = serializer.data.get('collaborators') if collaborators: collaborators_json = { 'owner': request.user.email, 'collaborators': collaborators } note.collaborators = collaborators_json note.save() note.label.add(label) cache = Cache.getCacheInstance() cache.hmset(f'user-{request.user.id}-note-{note.id}', { 'noteObj': json.dumps(RetriveAllNotesSerializer(note).data) }) logger.info(f"Note is saved") return Response({'response_msg': 'Your note is saved'}, status=status.HTTP_201_CREATED) except Label.DoesNotExist: logger.info(f'{label_name} label is not exist') return Response( {'response_msg': f'{label_name} label is not exist'}, status=status.HTTP_404_NOT_FOUND) logger.error(serializer.errors) return Response({'response_msg': serializer.errors}, status=status.HTTP_400_BAD_REQUEST)
def patch(self, request, note_id): """ This API is used to set reminder @param note_id: primary_key of specific note @return: sets reminder """ try: note = Notes.objects.get(id=note_id, user=request.user.id) except Notes.DoesNotExist: logger.info('Note not found') return Response({'response_msg': 'Note Not Found'}, status=status.HTTP_404_NOT_FOUND) serializer = self.serializer_class(data=request.data, initial=note, partial=True) serializer.is_valid(raise_exception=True) note.reminder = serializer.data.get('reminder') note.save() logger.info('Reminder is set') return Response({'response_msg': 'Reminder is set'}, status=status.HTTP_200_OK)
def get(self, request, label_name): """ This API is used to get label specific notes @param label_name: existing specific label name @return: Retrieves note for this specific label """ try: label = Label.objects.get( Q(label_name=label_name) & Q(user_id=request.user.pk)) notes = Notes.objects.filter( Q(label=label) & Q(user=request.user.pk) & Q(is_archive=False)) if not notes: logger.info(f"No notes available for label '{label_name}' ") return Response( { 'response_data': f"No notes available for label '{label_name}' " }, status=status.HTTP_200_OK) serializer = RetriveAllNotesSerializer(notes, many=True) logger.info(f"all notes of {label_name} are fetched") return Response({'response_data': serializer.data}, status=status.HTTP_200_OK) except (Label.DoesNotExist, Notes.DoesNotExist): logger.info(f'{label_name} label is not exist') return Response( {'response_msg': f'{label_name} label is not exist'}, status=status.HTTP_404_NOT_FOUND)
def get(self, request): """ This Api verifies the user email and jwt token sent to the email and activates the account @param request: Get request hits with jwt token which contains user information @return: Account activation confirmation """ jwtToken = request.GET.get('token') try: blacklist_token = TokenBlackLists.objects.get(token=jwtToken) except TokenBlackLists.DoesNotExist: blacklist_token = None if blacklist_token is None: response = JWTAuth.verifyToken(jwtToken=jwtToken) if not response: msg = 'Session for this token is expired!' logger.info('token session expired!') return Response({'response_msg':msg}, status=status.HTTP_401_UNAUTHORIZED) username = response.get('username') user = User.objects.get(username=username) user.is_active = True user.save() TokenBlackLists(token=jwtToken).save() msg = 'Your account is activated! Now you can log in' logger.info(f"{user.username}'s account is activated") return Response({'response_msg':msg}, status=status.HTTP_200_OK) msg = 'This link is no valid longer' logger.info('This link is already used') return Response({'response_msg':msg}, status=status.HTTP_403_FORBIDDEN)
def post(self, request): """ This API is used to authenticate user to access resources @param request: user credential like username and password @return: Redirects to all notes url on successful login """ serializer = self.serializer_class(data=request.data) if serializer.is_valid(): username = serializer.data.get('username') password = serializer.data.get('password') user = authenticate(request, username=username, password=password) if user: logger.info(f"{username} is authenticated") login(request, user) logger.info(f"{username} is logged in") redirect_url = request.GET.get('next') if redirect_url: logger.info(f'Redirects to {redirect_url}') return redirect(redirect_url) logger.info(f'Redirects to /notes/') return redirect('/notes/') try: user = User.objects.get(username=username) except User.DoesNotExist: user = None if user and check_password(password, user.password): jwtToken = JWTAuth.getToken(user.username, user.password) current_site = get_current_site(request).domain relative_url = 'user/verify-email/' email_data = Email.configureEmail(jwtToken, user, current_site, relative_url) Email.sendEmail(email_data) logger.info(f"{username}'s account is not active, activation mail is sent to {user.email}") msg = 'Your account is not active. Please activate your account from the link shared in your mail' return Response({'response_msg':msg}, status=status.HTTP_100_CONTINUE) msg = 'Bad Credential found' logger.error(f"Credential failure for {username}") return Response({'response_msg':msg}, status=status.HTTP_401_UNAUTHORIZED) logger.error(serializer.errors) return Response({'msg':serializer.errors}, status=status.HTTP_400_BAD_REQUEST)
def get(self, request, uid, token): """ This api accepts the get request hit from the email on clicked on link @param : user id and token @return: user id and token after verification """ try: blacklist_token = TokenBlackLists.objects.get(token=token) except TokenBlackLists.DoesNotExist: blacklist_token = None if blacklist_token is None: response = JWTAuth.verifyToken(jwtToken=token) if not response: msg = 'Session for this token is expired!' logger.info('Token session expired!') return Response({'response_msg':msg},status=status.HTTP_401_UNAUTHORIZED) responseMsg = { 'uid': uid, 'token': token } return Response({'response_msg':responseMsg}, status=status.HTTP_200_OK) logger.info('This token is already used!') msg = 'This link is no valid longer' return Response({'response_msg':msg},status=status.HTTP_403_FORBIDDEN)
def post(self, request): """ This api is for user registration to this application @param request: user registration data like username, email, password, firstname, lastname @return: account verification link to registered email once registration is successful """ serializer = self.serializer_class(data=request.data) if serializer.is_valid(): serializer.save() user = User.objects.get(username=serializer.data.get('username')) user.is_active = False user.save() logger.info(f"{user.username} is registered") jwtToken = JWTAuth.getToken(user.username, user.password) current_site = get_current_site(request).domain relative_url = 'user/verify-email/' email_data = Email.configureEmail(jwtToken, user, current_site, relative_url) Email.sendEmail(email_data) logger.info(f'Account activation link is sent to {user.email}') msg= "Your account is created and a confirmation mail is sent to your mail for account activation" return Response({'response_msg':msg, 'response_data':jwtToken},status = status.HTTP_201_CREATED) logger.error(serializer.errors) return Response({'response_msg':serializer.errors}, status=status.HTTP_400_BAD_REQUEST)
def post(self, request): """ This api is used to send reset password request to server @param request: user registered email id @return: sends a password reset link to user validated email id """ serializer = self.serializer_class(data=request.data) if serializer.is_valid(): try: user = User.objects.get(email=serializer.data.get('email')) except User.DoesNotExist: msg = 'Your Mail id is not registered' logger.info(f"{serializer.data.get('email')} is not registered") return Response({'response_msg':msg}, status=status.HTTP_404_NOT_FOUND) jwtToken = JWTAuth.getToken(user.username, user.password) current_site = get_current_site(request).domain relative_url = 'user/reset-password/'+str(user.pk)+"/"+str(jwtToken) email_data = Email.configureResetPasswordMail(jwtToken, user, current_site, relative_url) Email.sendEmail(email_data) msg = 'Password reset link is sent to your mail.' logger.info(f'password reset link is sent to {user.email}') return Response({'response_msg':msg, 'response_data':jwtToken}, status=status.HTTP_100_CONTINUE) logger.error(serializer.errors) return Response({'response_msg': serializer.errors}, status=status.HTTP_400_BAD_REQUEST)
def patch(self, request, note_id): """ This API is used to update the existing note @param request: title, content, label, color @param note_id: primary_key of the specific note @return: updates the note """ try: note = Notes.objects.get( Q(pk=note_id) & Q(user=request.user) & Q(is_trash=False)) except Notes.DoesNotExist: logger.warning("Note does not exist on update API hit") return Response({'msg': 'Your not authorised to access this data'}, status=status.HTTP_401_UNAUTHORIZED) serializer = self.serializer_class(data=request.data, partial=True, context={'user': request.user}) if serializer.is_valid(): note.last_updated = datetime.now() note.title = serializer.data.get('title') note.content = serializer.data.get('content') note.color = serializer.data.get('color') collabortors = serializer.data.get('collaborators') if serializer.data.get('label'): for label in serializer.data.get('label'): try: Label.objects.get( Q(label_name=label['label_name']) & Q(user=request.user)) except Label.DoesNotExist: logger.warning(f"{label['label_name']} does not exist") return Response( {'response_msg': 'This label is not exist'}, status=status.HTTP_404_NOT_FOUND) note.label.clear() if serializer.data.get('label'): for label in serializer.data.get('label'): label_obj = Label.objects.get( Q(label_name=label['label_name']) & Q(user=request.user)) note.label.add(label_obj) if note.collaborators: note.collaborators.pop('owner') note.collaborators.pop('collaborators') if collabortors: collaborators_json = { 'owner': request.user.email, 'collaborators': collabortors } note.collaborators = collaborators_json note.save() logger.info("Note is updated") cache = Cache.getCacheInstance() cache.delete(f'user-{request.user.id}-note-{note.id}') cache.hmset( f'user-{request.user.id}-note-{note.id}', {'noteObj': json.dumps(RetriveAllNotesSerializer(note).data)}) cache.expire(f'user-{request.user.id}-note-{note.id}', time=timedelta(days=3)) logger.info("Note is updated in cache") return Response({'response_msg': 'Your note is Updated'}, status=status.HTTP_200_OK) logger.error(serializer.errors) return Response({'response_msg': serializer.errors}, status=status.HTTP_400_BAD_REQUEST)