diff --git a/accounts/serializer.py b/accounts/serializer.py index 01c7ee441..922247d10 100644 --- a/accounts/serializer.py +++ b/accounts/serializer.py @@ -5,6 +5,7 @@ AttachmentsSerializer, OrganizationSerializer, ProfileSerializer, + UserSerializer ) from contacts.serializer import ContactSerializer from leads.serializer import LeadSerializer @@ -18,7 +19,7 @@ class Meta: class AccountSerializer(serializers.ModelSerializer): - created_by = ProfileSerializer() + created_by = UserSerializer() lead = LeadSerializer() org = OrganizationSerializer() tags = TagsSerailizer(read_only=True, many=True) diff --git a/accounts/views.py b/accounts/views.py index 210d6ee62..d27470881 100644 --- a/accounts/views.py +++ b/accounts/views.py @@ -30,8 +30,10 @@ from accounts.tasks import send_email, send_email_to_assigned_user from cases.serializer import CaseSerializer from common.models import Attachments, Comment, Profile +from leads.models import Lead +from leads.serializer import LeadSerializer -# from common.custom_auth import JSONWebTokenAuthentication +from common.external_auth import CustomDualAuthentication from common.serializer import ( AttachmentsSerializer, CommentSerializer, @@ -55,7 +57,7 @@ class AccountsListView(APIView, LimitOffsetPagination): - # authentication_classes = (JSONWebTokenAuthentication,) + authentication_classes = (CustomDualAuthentication,) permission_classes = (IsAuthenticated,) model = Account serializer_class = AccountReadSerializer @@ -65,7 +67,7 @@ def get_context_data(self, **kwargs): queryset = self.model.objects.filter(org=self.request.profile.org).order_by("-id") if self.request.profile.role != "ADMIN" and not self.request.profile.is_admin: queryset = queryset.filter( - Q(created_by=self.request.profile) | Q(assigned_to=self.request.profile) + Q(created_by=self.request.profile.user.user) | Q(assigned_to=self.request.profile) ).distinct() if params: @@ -77,7 +79,7 @@ def get_context_data(self, **kwargs): queryset = queryset.filter(industry__icontains=params.get("industry")) if params.get("tags"): queryset = queryset.filter( - tags__in=json.loads(params.get("tags")) + tags__in=params.get("tags") ).distinct() context = {} @@ -136,6 +138,12 @@ def get_context_data(self, **kwargs): "id", "user__email" ) context["users"] = users + leads = Lead.objects.filter(org=self.request.profile.org).exclude( + Q(status="converted") | Q(status="closed") + ) + context["users"] = users + context["leads"] = LeadSerializer(leads, many=True).data + context["status"] = ["open","close"] return context @extend_schema(tags=["Accounts"], parameters=swagger_params1.account_get_params) @@ -207,7 +215,7 @@ def post(self, request, *args, **kwargs): class AccountDetailView(APIView): - # authentication_classes = (JSONWebTokenAuthentication,) + authentication_classes = (CustomDualAuthentication,) permission_classes = (IsAuthenticated,) serializer_class = AccountReadSerializer @@ -226,7 +234,6 @@ def put(self, request, pk, format=None): serializer = AccountCreateSerializer( account_object, data=data, request_obj=request, account=True ) - serializer.data['org'] = request.profile.org if serializer.is_valid(): if ( @@ -285,7 +292,7 @@ def put(self, request, pk, format=None): if self.request.FILES.get("account_attachment"): attachment = Attachments() - attachment.created_by = self.request.profile + attachment.created_by = self.request.profile.user attachment.file_name = self.request.FILES.get("account_attachment").name attachment.account = account_object attachment.attachment = self.request.FILES.get("account_attachment") @@ -375,6 +382,9 @@ def get(self, request, pk, format=None): users_mention = [] else: users_mention = [] + leads = Lead.objects.filter(org=self.request.profile.org).exclude( + Q(status="converted") | Q(status="closed") + ) context.update( { "attachments": AttachmentsSerializer( @@ -419,6 +429,8 @@ def get(self, request, pk, format=None): self.account.sent_email.all(), many=True ).data, "users_mention": users_mention, + "leads" : LeadSerializer(leads, many=True).data, + "status" : ["open","close"] } ) return Response(context) @@ -460,7 +472,7 @@ def post(self, request, pk, **kwargs): if self.request.FILES.get("account_attachment"): attachment = Attachments() - attachment.created_by = self.request.profile + attachment.created_by = self.request.profile.user attachment.file_name = self.request.FILES.get("account_attachment").name attachment.account = self.account_obj attachment.attachment = self.request.FILES.get("account_attachment") @@ -484,7 +496,7 @@ def post(self, request, pk, **kwargs): class AccountCommentView(APIView): model = Comment - # authentication_classes = (JSONWebTokenAuthentication,) + authentication_classes = (CustomDualAuthentication,) permission_classes = (IsAuthenticated,) serializer_class = AccountCommentEditSwaggerSerializer @@ -546,7 +558,7 @@ def delete(self, request, pk, format=None): class AccountAttachmentView(APIView): model = Attachments - # authentication_classes = (JSONWebTokenAuthentication,) + authentication_classes = (CustomDualAuthentication,) permission_classes = (IsAuthenticated,) serializer_class = AccountDetailEditSwaggerSerializer @@ -573,7 +585,7 @@ def delete(self, request, pk, format=None): class AccountCreateMailView(APIView): - # authentication_classes = (JSONWebTokenAuthentication,) + authentication_classes = (CustomDualAuthentication,) permission_classes = (IsAuthenticated,) model = Account serializer_class = EmailWriteSerializer diff --git a/cases/migrations/0003_alter_case_created_by.py b/cases/migrations/0003_alter_case_created_by.py new file mode 100644 index 000000000..350a4bfd9 --- /dev/null +++ b/cases/migrations/0003_alter_case_created_by.py @@ -0,0 +1,21 @@ +# Generated by Django 4.2.1 on 2023-10-31 12:42 + +from django.conf import settings +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ('cases', '0002_initial'), + ] + + operations = [ + migrations.AlterField( + model_name='case', + name='created_by', + field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='%(class)s_created_by', to=settings.AUTH_USER_MODEL, verbose_name='Created By'), + ), + ] diff --git a/cases/models.py b/cases/models.py index 1ea4ede43..eaf8dc724 100644 --- a/cases/models.py +++ b/cases/models.py @@ -32,9 +32,9 @@ class Case(BaseModel): closed_on = models.DateField() description = models.TextField(blank=True, null=True) assigned_to = models.ManyToManyField(Profile, related_name="case_assigned_users") - created_by = models.ForeignKey( - Profile, related_name="case_created_by", on_delete=models.SET_NULL, null=True - ) + # created_by = models.ForeignKey( + # Profile, related_name="case_created_by", on_delete=models.SET_NULL, null=True + # ) is_active = models.BooleanField(default=False) teams = models.ManyToManyField(Teams, related_name="cases_teams") org = models.ForeignKey( diff --git a/cases/serializer.py b/cases/serializer.py index 9ec86d704..b0926249d 100644 --- a/cases/serializer.py +++ b/cases/serializer.py @@ -2,7 +2,7 @@ from accounts.serializer import AccountSerializer from cases.models import Case -from common.serializer import OrganizationSerializer, ProfileSerializer +from common.serializer import OrganizationSerializer, ProfileSerializer,UserSerializer from contacts.serializer import ContactSerializer from teams.serializer import TeamsSerializer @@ -11,7 +11,7 @@ class CaseSerializer(serializers.ModelSerializer): account = AccountSerializer() contacts = ContactSerializer(read_only=True, many=True) assigned_to = ProfileSerializer(read_only=True, many=True) - created_by = ProfileSerializer(read_only=True) + created_by = UserSerializer(read_only=True) teams = TeamsSerializer(read_only=True, many=True) org = OrganizationSerializer() diff --git a/cases/views.py b/cases/views.py index 00a9c935a..2d7302eb4 100644 --- a/cases/views.py +++ b/cases/views.py @@ -16,7 +16,7 @@ from cases.tasks import send_email_to_assigned_user from common.models import Attachments, Comment, Profile -# from common.custom_auth import JSONWebTokenAuthentication +from common.external_auth import CustomDualAuthentication from common.serializer import AttachmentsSerializer, CommentSerializer from common.utils import CASE_TYPE, PRIORITY_CHOICE, STATUS_CHOICE from contacts.models import Contact @@ -25,7 +25,7 @@ class CaseListView(APIView, LimitOffsetPagination): - # authentication_classes = (JSONWebTokenAuthentication,) + authentication_classes = (CustomDualAuthentication,) permission_classes = (IsAuthenticated,) model = Case @@ -37,13 +37,13 @@ def get_context_data(self, **kwargs): profiles = Profile.objects.filter(is_active=True, org=self.request.profile.org) if self.request.profile.role != "ADMIN" and not self.request.profile.is_admin: queryset = queryset.filter( - Q(created_by=self.request.profile) | Q(assigned_to=self.request.profile) + Q(created_by=self.request.profile.user) | Q(assigned_to=self.request.profile) ).distinct() accounts = accounts.filter( - Q(created_by=self.request.profile) | Q(assigned_to=self.request.profile) + Q(created_by=self.request.profile.user) | Q(assigned_to=self.request.profile) ).distinct() contacts = contacts.filter( - Q(created_by=self.request.profile) | Q(assigned_to=self.request.profile) + Q(created_by=self.request.profile.user) | Q(assigned_to=self.request.profile) ).distinct() profiles = profiles.filter(role="ADMIN") @@ -97,26 +97,26 @@ def post(self, request, *args, **kwargs): serializer = CaseCreateSerializer(data=params, request_obj=request) if serializer.is_valid(): cases_obj = serializer.save( - created_by=request.profile, + created_by=request.profile.user, org=request.profile.org, closed_on=params.get("closed_on"), case_type=params.get("case_type"), ) if params.get("contacts"): - contacts_list = json.loads(params.get("contacts")) + contacts_list = params.get("contacts") contacts = Contact.objects.filter(id__in=contacts_list, org=request.profile.org) if contacts: cases_obj.contacts.add(*contacts) if params.get("teams"): - teams_list = json.loads(params.get("teams")) + teams_list = params.get("teams") teams = Teams.objects.filter(id__in=teams_list, org=request.profile.org) if teams.exists(): cases_obj.teams.add(*teams) if params.get("assigned_to"): - assinged_to_list = json.loads(params.get("assigned_to")) + assinged_to_list = params.get("assigned_to") profiles = Profile.objects.filter( id__in=assinged_to_list, org=request.profile.org, is_active=True ) @@ -125,7 +125,7 @@ def post(self, request, *args, **kwargs): if self.request.FILES.get("case_attachment"): attachment = Attachments() - attachment.created_by = self.request.profile + attachment.created_by = self.request.profile.user attachment.file_name = self.request.FILES.get("case_attachment").name attachment.cases = cases_obj attachment.attachment = self.request.FILES.get("case_attachment") @@ -148,7 +148,7 @@ def post(self, request, *args, **kwargs): class CaseDetailView(APIView): - # authentication_classes = (JSONWebTokenAuthentication,) + authentication_classes = (CustomDualAuthentication,) permission_classes = (IsAuthenticated,) model = Case @@ -194,21 +194,21 @@ def put(self, request, pk, format=None): ) cases_object.contacts.clear() if params.get("contacts"): - contacts_list = json.loads(params.get("contacts")) + contacts_list = params.get("contacts") contacts = Contact.objects.filter(id__in=contacts_list, org=request.profile.org) if contacts: cases_object.contacts.add(*contacts) cases_object.teams.clear() if params.get("teams"): - teams_list = json.loads(params.get("teams")) + teams_list = params.get("teams") teams = Teams.objects.filter(id__in=teams_list, org=request.profile.org) if teams.exists(): cases_object.teams.add(*teams) cases_object.assigned_to.clear() if params.get("assigned_to"): - assinged_to_list = json.loads(params.get("assigned_to")) + assinged_to_list = params.get("assigned_to") profiles = Profile.objects.filter( id__in=assinged_to_list, org=request.profile.org, is_active=True ) @@ -217,7 +217,7 @@ def put(self, request, pk, format=None): if self.request.FILES.get("case_attachment"): attachment = Attachments() - attachment.created_by = self.request.profile + attachment.created_by = self.request.profile.user attachment.file_name = self.request.FILES.get("case_attachment").name attachment.case = cases_object attachment.attachment = self.request.FILES.get("case_attachment") @@ -366,7 +366,7 @@ def post(self, request, pk, **kwargs): if self.request.FILES.get("case_attachment"): attachment = Attachments() - attachment.created_by = self.request.profile + attachment.created_by = self.request.profile.user attachment.file_name = self.request.FILES.get("case_attachment").name attachment.case = self.cases_obj attachment.attachment = self.request.FILES.get("case_attachment") @@ -387,7 +387,7 @@ def post(self, request, pk, **kwargs): class CaseCommentView(APIView): model = Comment - # authentication_classes = (JSONWebTokenAuthentication,) + authentication_classes = (CustomDualAuthentication,) permission_classes = (IsAuthenticated,) def get_object(self, pk): @@ -450,7 +450,7 @@ def delete(self, request, pk, format=None): class CaseAttachmentView(APIView): model = Attachments - # authentication_classes = (JSONWebTokenAuthentication,) + authentication_classes = (CustomDualAuthentication,) permission_classes = (IsAuthenticated,) @extend_schema( diff --git a/common/external_auth.py b/common/external_auth.py new file mode 100644 index 000000000..63464ad0c --- /dev/null +++ b/common/external_auth.py @@ -0,0 +1,57 @@ +import jwt +from rest_framework.authentication import BaseAuthentication +from rest_framework.exceptions import AuthenticationFailed +from rest_framework.request import Request +from common.models import Org,Profile,User +from django.conf import settings + +def verify_jwt_token(token1): + secret_key = (settings.SECRET_KEY) # Replace with your secret key used for token encoding/decoding + try: + token = token1.split(" ")[1] # getting the token value + payload = jwt.decode(token, (settings.SECRET_KEY), algorithms=[settings.JWT_ALGO]) + return True, payload + except jwt.ExpiredSignatureError: + return False, "Token is expired" + except jwt.InvalidTokenError: + return False, "Invalid token" + +class CustomDualAuthentication(BaseAuthentication): + + def authenticate(self, request: Request): + + jwt_user = None + profile = None + # Check JWT authentication + # Implement your JWT authentication logic here + # You might use a library like `python_jwt` to decode and verify the JWT token + # Example code assumes a method `verify_jwt_token` for JWT verification + jwt_token = request.META.get('HTTP_AUTHORIZATION') + if jwt_token: + is_valid, jwt_payload = verify_jwt_token(jwt_token) + if is_valid: + # JWT authentication successful + jwt_user = (User.objects.get(id=jwt_payload['user_id']),True) + if jwt_payload['user_id'] is not None: + if request.headers.get("org"): + profile = Profile.objects.get( + user_id=jwt_payload['user_id'], org=request.headers.get("org"), is_active=True + ) + if profile: + request.profile = profile + # Check API key authentication + api_key = request.headers.get('Token') # Get API key from request query params + if api_key: + try: + organization = Org.objects.get(api_key=api_key) + # API key authentication successful + api_key_user = organization + request.META['org'] = api_key_user.id + profile = Profile.objects.filter(org=api_key_user,role="ADMIN").first() + request.profile = profile + profile = (profile.user,True) + except Org.DoesNotExist: + raise AuthenticationFailed('Invalid API Key') + # Select the appropriate user based on authentication method + # Return the user if any authentication method succeeded + return jwt_user or profile diff --git a/common/middleware/get_company.py b/common/middleware/get_company.py index 9e33a94ed..c8e1ef96b 100644 --- a/common/middleware/get_company.py +++ b/common/middleware/get_company.py @@ -61,4 +61,5 @@ def process_request(self, request): if profile: request.profile = profile except : + print('test1') raise PermissionDenied() diff --git a/common/migrations/0005_org_api_key.py b/common/migrations/0005_org_api_key.py new file mode 100644 index 000000000..2fb1db59e --- /dev/null +++ b/common/migrations/0005_org_api_key.py @@ -0,0 +1,19 @@ +# Generated by Django 4.2.1 on 2023-11-02 11:19 + +import common.models +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('common', '0004_alter_profile_alternate_phone'), + ] + + operations = [ + migrations.AddField( + model_name='org', + name='api_key', + field=models.TextField(default=common.models.generate_unique_key, editable=False), + ), + ] diff --git a/common/migrations/0006_alter_org_api_key.py b/common/migrations/0006_alter_org_api_key.py new file mode 100644 index 000000000..fb672699d --- /dev/null +++ b/common/migrations/0006_alter_org_api_key.py @@ -0,0 +1,30 @@ +# Generated by Django 4.2.1 on 2023-11-02 11:20 + +import common.models +from django.db import migrations, models +import uuid + +def generate_unique_key(): + return str(uuid.uuid4()) + +def set_unique_api_keys(apps, schema_editor): + Org = apps.get_model('common', 'Org') + for org in Org.objects.all(): + org.api_key = generate_unique_key() + org.save() + + +class Migration(migrations.Migration): + + dependencies = [ + ('common', '0005_org_api_key'), + ] + + operations = [ + migrations.RunPython(set_unique_api_keys), + migrations.AlterField( + model_name='org', + name='api_key', + field=models.TextField(default=common.models.generate_unique_key, editable=False, unique=True), + ), + ] diff --git a/common/migrations/0007_org_is_active.py b/common/migrations/0007_org_is_active.py new file mode 100644 index 000000000..0f274f212 --- /dev/null +++ b/common/migrations/0007_org_is_active.py @@ -0,0 +1,18 @@ +# Generated by Django 4.2.1 on 2023-11-02 11:42 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('common', '0006_alter_org_api_key'), + ] + + operations = [ + migrations.AddField( + model_name='org', + name='is_active', + field=models.BooleanField(default=True), + ), + ] diff --git a/common/models.py b/common/models.py index afa2ebb01..3eb9e5d2a 100644 --- a/common/models.py +++ b/common/models.py @@ -3,7 +3,6 @@ import os import time import uuid - import arrow from django.contrib.auth.models import AbstractUser from django.contrib.auth.models import AbstractBaseUser, PermissionsMixin, UserManager @@ -115,9 +114,15 @@ def get_complete_address(self): address += self.get_country_display() return address +def generate_unique_key(): + return str(uuid.uuid4()) class Org(BaseModel): name = models.CharField(max_length=100, blank=True, null=True) + api_key = models.TextField( + default=generate_unique_key, unique=True, editable=False + ) + is_active = models.BooleanField(default=True) # address = models.TextField(blank=True, null=True) # user_limit = models.IntegerField(default=5) # country = models.CharField(max_length=3, choices=COUNTRIES, blank=True, null=True) diff --git a/common/serializer.py b/common/serializer.py index b575187d8..409de6bfa 100644 --- a/common/serializer.py +++ b/common/serializer.py @@ -22,7 +22,7 @@ class OrganizationSerializer(serializers.ModelSerializer): class Meta: model = Org - fields = ("id", "name") + fields = ("id", "name","api_key") class SocialLoginSerializer(serializers.Serializer): @@ -217,7 +217,7 @@ class Meta: class DocumentSerializer(serializers.ModelSerializer): shared_to = ProfileSerializer(read_only=True, many=True) teams = serializers.SerializerMethodField() - created_by = ProfileSerializer() + created_by = UserSerializer() org = OrganizationSerializer() def get_teams(self, obj): @@ -299,7 +299,7 @@ def validate_website(self, website): class APISettingsListSerializer(serializers.ModelSerializer): - created_by = ProfileSerializer() + created_by = UserSerializer() lead_assigned_to = ProfileSerializer(read_only=True, many=True) tags = serializers.SerializerMethodField() org = OrganizationSerializer() diff --git a/common/views.py b/common/views.py index 270c51a8c..cddaa79f6 100644 --- a/common/views.py +++ b/common/views.py @@ -1,4 +1,5 @@ import json +import secrets from multiprocessing import context from re import template @@ -23,6 +24,7 @@ from django.views.decorators.http import require_http_methods from drf_spectacular.types import OpenApiTypes from drf_spectacular.utils import OpenApiExample, OpenApiParameter, extend_schema +from common.external_auth import CustomDualAuthentication from rest_framework import status from rest_framework.authtoken.models import Token from rest_framework.pagination import LimitOffsetPagination @@ -340,19 +342,19 @@ def get(self, request, format=None): if self.request.profile.role != "ADMIN" and not self.request.user.is_superuser: accounts = accounts.filter( - Q(assigned_to=self.request.profile) | Q(created_by=self.request.profile) + Q(assigned_to=self.request.profile) | Q(created_by=self.request.profile.user) ) contacts = contacts.filter( Q(assigned_to__id__in=self.request.profile) - | Q(created_by=self.request.profile) + | Q(created_by=self.request.profile.user) ) leads = leads.filter( Q(assigned_to__id__in=self.request.profile) - | Q(created_by=self.request.profile) + | Q(created_by=self.request.profile.user) ).exclude(status="closed") opportunities = opportunities.filter( Q(assigned_to__id__in=self.request.profile) - | Q(created_by=self.request.profile) + | Q(created_by=self.request.profile.user) ) context = {} context["accounts_count"] = accounts.count() @@ -367,7 +369,7 @@ def get(self, request, format=None): class OrgProfileCreateView(APIView): - ##authentication_classes = (JSONWebTokenAuthentication,) + authentication_classes = (CustomDualAuthentication,) permission_classes = (IsAuthenticated,) model1 = Org @@ -380,8 +382,9 @@ class OrgProfileCreateView(APIView): request=OrgProfileCreateSerializer ) def post(self, request, format=None): - params = request.data - serializer = self.serializer_class(data=params) + data = request.data + data['api_key'] = secrets.token_hex(16) + serializer = self.serializer_class(data=data) if serializer.is_valid(): org_obj = serializer.save() @@ -438,7 +441,7 @@ def get(self, request, format=None): return Response(context, status=status.HTTP_200_OK) class DocumentListView(APIView, LimitOffsetPagination): - ##authentication_classes = (JSONWebTokenAuthentication,) + authentication_classes = (CustomDualAuthentication,) permission_classes = (IsAuthenticated,) model = Document @@ -545,19 +548,19 @@ def post(self, request, *args, **kwargs): serializer = DocumentCreateSerializer(data=params, request_obj=request) if serializer.is_valid(): doc = serializer.save( - created_by=request.profile, + created_by=request.profile.user, org=request.profile.org, document_file=request.FILES.get("document_file"), ) if params.get("shared_to"): - assinged_to_list = json.loads(params.get("shared_to")) + assinged_to_list = params.get("shared_to") profiles = Profile.objects.filter( id__in=assinged_to_list, org=request.profile.org, is_active=True ) if profiles: doc.shared_to.add(*profiles) if params.get("teams"): - teams_list = json.loads(params.get("teams")) + teams_list = params.get("teams") teams = Teams.objects.filter(id__in=teams_list, org=request.profile.org) if teams: doc.teams.add(*teams) @@ -573,7 +576,7 @@ def post(self, request, *args, **kwargs): class DocumentDetailView(APIView): - ##authentication_classes = (JSONWebTokenAuthentication,) + authentication_classes = (CustomDualAuthentication,) permission_classes = (IsAuthenticated,) def get_object(self, pk): @@ -694,7 +697,7 @@ def put(self, request, pk, format=None): ) doc.shared_to.clear() if params.get("shared_to"): - assinged_to_list = json.loads(params.get("shared_to")) + assinged_to_list = params.get("shared_to") profiles = Profile.objects.filter( id__in=assinged_to_list, org=request.profile.org, is_active=True ) @@ -703,7 +706,7 @@ def put(self, request, pk, format=None): doc.teams.clear() if params.get("teams"): - teams_list = json.loads(params.get("teams")) + teams_list = params.get("teams") teams = Teams.objects.filter(id__in=teams_list, org=request.profile.org) if teams: doc.teams.add(*teams) @@ -787,12 +790,12 @@ def post(self, request, *args, **kwargs): params = request.data assign_to_list = [] if params.get("lead_assigned_to"): - assign_to_list = json.loads(params.get("lead_assigned_to")) + assign_to_list = params.get("lead_assigned_to") serializer = APISettingsSerializer(data=params) if serializer.is_valid(): - settings_obj = serializer.save(created_by=request.profile, org=request.profile.org) + settings_obj = serializer.save(created_by=request.profile.user, org=request.profile.org) if params.get("tags"): - tags = json.loads(params.get("tags")) + tags = params.get("tags") for tag in tags: tag_obj = Tags.objects.filter(name=tag).first() if not tag_obj: @@ -812,7 +815,7 @@ def post(self, request, *args, **kwargs): class DomainDetailView(APIView): model = APISettings - ##authentication_classes = (JSONWebTokenAuthentication,) + authentication_classes = (CustomDualAuthentication,) permission_classes = (IsAuthenticated,) @extend_schema( @@ -833,14 +836,14 @@ def put(self, request, pk, **kwargs): params = request.data assign_to_list = [] if params.get("lead_assigned_to"): - assign_to_list = json.loads(params.get("lead_assigned_to")) + assign_to_list = params.get("lead_assigned_to") serializer = APISettingsSerializer(data=params, instance=api_setting) if serializer.is_valid(): api_setting = serializer.save() api_setting.tags.clear() api_setting.lead_assigned_to.clear() if params.get("tags"): - tags = json.loads(params.get("tags")) + tags = params.get("tags") for tag in tags: tag_obj = Tags.objects.filter(name=tag).first() if not tag_obj: diff --git a/contacts/views.py b/contacts/views.py index ebdb2734e..719ea0256 100644 --- a/contacts/views.py +++ b/contacts/views.py @@ -17,7 +17,7 @@ ) from common.utils import COUNTRIES -# from common.custom_auth import JSONWebTokenAuthentication +from common.external_auth import CustomDualAuthentication from contacts import swagger_params1 from contacts.models import Contact, Profile from contacts.serializer import * @@ -27,7 +27,7 @@ class ContactsListView(APIView, LimitOffsetPagination): - # authentication_classes = (JSONWebTokenAuthentication,) + authentication_classes = (CustomDualAuthentication,) permission_classes = (IsAuthenticated,) model = Contact @@ -37,7 +37,7 @@ def get_context_data(self, **kwargs): if self.request.profile.role != "ADMIN" and not self.request.profile.is_admin: queryset = queryset.filter( Q(assigned_to__in=[self.request.profile]) - | Q(created_by=self.request.profile) + | Q(created_by=self.request.profile.user) ).distinct() if params: @@ -51,7 +51,7 @@ def get_context_data(self, **kwargs): queryset = queryset.filter(primary_email__icontains=params.get("email")) if params.getlist("assigned_to"): queryset = queryset.filter( - assigned_to__id__in=json.loads(params.get("assigned_to")) + assigned_to__id__in=params.get("assigned_to") ).distinct() context = {} @@ -111,12 +111,12 @@ def post(self, request, *args, **kwargs): contact_obj.save() if params.get("teams"): - teams_list = json.loads(params.get("teams")) + teams_list = params.get("teams") teams = Teams.objects.filter(id__in=teams_list, org=request.profile.org) contact_obj.teams.add(*teams) if params.get("assigned_to"): - assinged_to_list = json.loads(params.get("assigned_to")) + assinged_to_list = params.get("assigned_to") profiles = Profile.objects.filter(id__in=assinged_to_list, org=request.profile.org) contact_obj.assigned_to.add(*profiles) @@ -140,7 +140,7 @@ def post(self, request, *args, **kwargs): class ContactDetailView(APIView): - # authentication_classes = (JSONWebTokenAuthentication,) + # authentication_classes = (CustomDualAuthentication,) permission_classes = (IsAuthenticated,) model = Contact @@ -366,7 +366,7 @@ def post(self, request, pk, **kwargs): if self.request.FILES.get("contact_attachment"): attachment = Attachments() - attachment.created_by = self.request.profile + attachment.created_by = self.request.profile.user attachment.file_name = self.request.FILES.get("contact_attachment").name attachment.contact = self.contact_obj attachment.attachment = self.request.FILES.get("contact_attachment") @@ -390,7 +390,7 @@ def post(self, request, pk, **kwargs): class ContactCommentView(APIView): model = Comment - # authentication_classes = (JSONWebTokenAuthentication,) + # authentication_classes = (CustomDualAuthentication,) permission_classes = (IsAuthenticated,) def get_object(self, pk): @@ -452,7 +452,7 @@ def delete(self, request, pk, format=None): class ContactAttachmentView(APIView): model = Attachments - # authentication_classes = (JSONWebTokenAuthentication,) + # authentication_classes = (CustomDualAuthentication,) permission_classes = (IsAuthenticated,) @extend_schema( diff --git a/crm/settings.py b/crm/settings.py index 9576e9ad7..f6c52706a 100644 --- a/crm/settings.py +++ b/crm/settings.py @@ -87,7 +87,7 @@ "django.middleware.clickjacking.XFrameOptionsMiddleware", "corsheaders.middleware.CorsMiddleware", "crum.CurrentRequestUserMiddleware", - "common.middleware.get_company.GetProfileAndOrg", + # "common.middleware.get_company.GetProfileAndOrg", "wagtail.contrib.redirects.middleware.RedirectMiddleware", ] diff --git a/events/serializer.py b/events/serializer.py index 1fdada64d..3810cccd6 100644 --- a/events/serializer.py +++ b/events/serializer.py @@ -7,6 +7,7 @@ CommentSerializer, OrganizationSerializer, ProfileSerializer, + UserSerializer ) from contacts.serializer import ContactSerializer from events.models import Event @@ -14,7 +15,7 @@ class EventSerializer(serializers.ModelSerializer): - created_by = ProfileSerializer() + created_by = UserSerializer() assigned_to = ProfileSerializer(read_only=True, many=True) contacts = ContactSerializer(read_only=True, many=True) teams = TeamsSerializer(read_only=True, many=True) diff --git a/events/views.py b/events/views.py index 0593ae543..3b6bf24e4 100644 --- a/events/views.py +++ b/events/views.py @@ -12,7 +12,7 @@ from common.models import Attachments, Comment, Profile, User -# from common.custom_auth import JSONWebTokenAuthentication +from common.external_auth import CustomDualAuthentication from common.serializer import ( AttachmentsSerializer, CommentSerializer, @@ -40,7 +40,7 @@ class EventListView(APIView, LimitOffsetPagination): model = Event - # authentication_classes = (JSONWebTokenAuthentication,) + authentication_classes = (CustomDualAuthentication,) permission_classes = (IsAuthenticated,) def get_context_data(self, **kwargs): @@ -50,10 +50,10 @@ def get_context_data(self, **kwargs): if self.request.profile.role != "ADMIN" and not self.request.profile.is_admin: queryset = queryset.filter( Q(assigned_to__in=[self.request.profile]) - | Q(created_by=self.request.profile) + | Q(created_by=self.request.profile.user) ) contacts = contacts.filter( - Q(created_by=self.request.profile) | Q(assigned_to=self.request.profile) + Q(created_by=self.request.profile.user) | Q(assigned_to=self.request.profile) ).distinct() if params: @@ -63,7 +63,7 @@ def get_context_data(self, **kwargs): queryset = queryset.filter(created_by=params.get("created_by")) if params.getlist("assigned_users"): queryset = queryset.filter( - assigned_to__id__in=json.loads(params.get("assigned_users")) + assigned_to__id__in=params.get("assigned_users") ) if params.get("date_of_meeting"): queryset = queryset.filter( @@ -104,7 +104,7 @@ def post(self, request, *args, **kwargs): recurring_days = json.dumps(params.get("recurring_days")) if params.get("event_type") == "Non-Recurring": event_obj = serializer.save( - created_by=request.profile, + created_by=request.profile.user, date_of_meeting=params.get("start_date"), is_active=True, disabled=False, @@ -118,12 +118,12 @@ def post(self, request, *args, **kwargs): event_obj.contacts.add(obj_contact) if params.get("teams"): - teams_list = json.loads(params.get("teams")) + teams_list = params.get("teams") teams = Teams.objects.filter(id__in=teams_list, org=request.profile.org) event_obj.teams.add(*teams) if params.get("assigned_to"): - assinged_to_list = json.loads(params.get("assigned_to")) + assinged_to_list = params.get("assigned_to") profiles = Profile.objects.filter( id__in=assinged_to_list, org=request.profile.org ) @@ -159,7 +159,7 @@ def post(self, request, *args, **kwargs): data = serializer.validated_data event = Event.objects.create( - created_by=request.profile, + created_by=request.profile.user, start_date=start_date, end_date=end_date, name=data["name"], @@ -178,12 +178,12 @@ def post(self, request, *args, **kwargs): event.contacts.add(obj_contact) if params.get("teams"): - teams_list = json.loads(params.get("teams")) + teams_list = params.get("teams") teams = Teams.objects.filter(id__in=teams_list, org=request.profile.org) event.teams.add(*teams) if params.get("assigned_to"): - assinged_to_list = json.loads(params.get("assigned_to")) + assinged_to_list = params.get("assigned_to") profiles = Profile.objects.filter( id__in=assinged_to_list, org=request.profile.org ) @@ -208,7 +208,7 @@ def post(self, request, *args, **kwargs): class EventDetailView(APIView): model = Event - # authentication_classes = (JSONWebTokenAuthentication,) + authentication_classes = (CustomDualAuthentication,) permission_classes = (IsAuthenticated,) def get_object(self, pk): @@ -343,7 +343,7 @@ def post(self, request, pk, **kwargs): if self.request.FILES.get("event_attachment"): attachment = Attachments() - attachment.created_by = self.request.profile + attachment.created_by = self.request.profile.user attachment.file_name = self.request.FILES.get("event_attachment").name attachment.event = self.event_obj attachment.attachment = self.request.FILES.get("event_attachment") @@ -396,13 +396,13 @@ def put(self, request, pk, **kwargs): event_obj.teams.clear() if params.get("teams"): - teams_list = json.loads(params.get("teams")) + teams_list = params.get("teams") teams = Teams.objects.filter(id__in=teams_list, org=request.profile.org) event_obj.teams.add(*teams) event_obj.assigned_to.clear() if params.get("assigned_to"): - assinged_to_list = json.loads(params.get("assigned_to")) + assinged_to_list = params.get("assigned_to") profiles = Profile.objects.filter( id__in=assinged_to_list, org=request.profile.org ) @@ -448,7 +448,7 @@ def delete(self, request, pk, **kwargs): class EventCommentView(APIView): model = Comment - # authentication_classes = (JSONWebTokenAuthentication,) + authentication_classes = (CustomDualAuthentication,) permission_classes = (IsAuthenticated,) def get_object(self, pk): @@ -510,7 +510,7 @@ def delete(self, request, pk, format=None): class EventAttachmentView(APIView): model = Attachments - # authentication_classes = (JSONWebTokenAuthentication,) + authentication_classes = (CustomDualAuthentication,) permission_classes = (IsAuthenticated,) @extend_schema( diff --git a/invoices/api_views.py b/invoices/api_views.py index e04df926d..b3b9a035c 100644 --- a/invoices/api_views.py +++ b/invoices/api_views.py @@ -15,7 +15,7 @@ from accounts.serializer import AccountSerializer from common.models import Attachments, Comment, User -# from common.custom_auth import JSONWebTokenAuthentication +from common.external_auth import CustomDualAuthentication from common.serializer import ( AttachmentsSerializer, BillingAddressSerializer, @@ -50,7 +50,7 @@ class InvoiceListView(APIView, LimitOffsetPagination): - # authentication_classes = (JSONWebTokenAuthentication,) + authentication_classes = (CustomDualAuthentication,) permission_classes = (IsAuthenticated,) model = Invoice @@ -77,7 +77,7 @@ def get_context_data(self, **kwargs): queryset = queryset.filter(created_by=params.get("created_by")) if params.get("assigned_users"): queryset = queryset.filter( - assigned_to__in=json.loads(params.get("assigned_users")) + assigned_to__in=params.get("assigned_users") ) if params.get("status"): queryset = queryset.filter(status=params.get("status")) @@ -184,7 +184,7 @@ def post(self, request, *args, **kwargs): ) if params.get("accounts"): - accounts = json.loads(params.get("accounts")) + accounts = params.get("accounts") for account in accounts: obj_account = Account.objects.filter( id=account, company=request.company @@ -198,7 +198,7 @@ def post(self, request, *args, **kwargs): if self.request.user.role == "ADMIN": if params.get("teams"): - teams = json.loads(params.get("teams")) + teams = params.get("teams") for team in teams: obj_team = Teams.objects.filter( id=team, company=request.company @@ -210,7 +210,7 @@ def post(self, request, *args, **kwargs): data["team"] = "Please enter valid Team" return Response({"error": True}, data) if params.get("assigned_to"): - assinged_to_users_ids = json.loads(params.get("assigned_to")) + assinged_to_users_ids = params.get("assigned_to") for user_id in assinged_to_users_ids: user = User.objects.filter(id=user_id, company=request.company) @@ -240,7 +240,7 @@ def post(self, request, *args, **kwargs): class InvoiceDetailView(APIView): - # authentication_classes = (JSONWebTokenAuthentication,) + authentication_classes = (CustomDualAuthentication,) permission_classes = (IsAuthenticated,) model = Invoice @@ -325,7 +325,7 @@ def put(self, request, pk, format=None): invoice_obj.accounts.clear() if params.get("accounts"): - accounts = json.loads(params.get("accounts")) + accounts = params.get("accounts") for account in accounts: obj_account = Account.objects.filter( id=account, company=request.company @@ -339,7 +339,7 @@ def put(self, request, pk, format=None): if self.request.user.role == "ADMIN": invoice_obj.teams.clear() if params.get("teams"): - teams = json.loads(params.get("teams")) + teams = params.get("teams") for team in teams: obj_team = Teams.objects.filter( id=team, company=request.company @@ -352,7 +352,7 @@ def put(self, request, pk, format=None): invoice_obj.assigned_to.clear() if params.get("assigned_to"): - assinged_to_users_ids = json.loads(params.get("assigned_to")) + assinged_to_users_ids = params.get("assigned_to") for user_id in assinged_to_users_ids: user = User.objects.filter(id=user_id, company=request.company) if user.exists(): @@ -540,7 +540,7 @@ def post(self, request, pk, **kwargs): class InvoiceCommentView(APIView): model = Comment - # authentication_classes = (JSONWebTokenAuthentication,) + authentication_classes = (CustomDualAuthentication,) permission_classes = (IsAuthenticated,) def get_object(self, pk): @@ -603,7 +603,7 @@ def delete(self, request, pk, format=None): class InvoiceAttachmentView(APIView): model = Attachments - # authentication_classes = (JSONWebTokenAuthentication,) + authentication_classes = (CustomDualAuthentication,) permission_classes = (IsAuthenticated,) @swagger_auto_schema( diff --git a/leads/views.py b/leads/views.py index 0c3ba98e6..6d328ef52 100644 --- a/leads/views.py +++ b/leads/views.py @@ -10,7 +10,7 @@ from accounts.models import Account, Tags from common.models import APISettings, Attachments, Comment, Profile -# from common.custom_auth import JSONWebTokenAuthentication +from common.external_auth import CustomDualAuthentication from common.serializer import ( AttachmentsSerializer, CommentSerializer, @@ -63,7 +63,7 @@ def get_context_data(self, **kwargs): if self.request.profile.role != "ADMIN" and not self.request.user.is_superuser: queryset = queryset.filter( Q(assigned_to__in=[self.request.profile]) - | Q(created_by=self.request.profile.user) + | Q(created_by=self.request.profile.user.user) ) if params: @@ -258,7 +258,7 @@ def post(self, request, *args, **kwargs): class LeadDetailView(APIView): model = Lead - # authentication_classes = (JSONWebTokenAuthentication,) + authentication_classes = (CustomDualAuthentication,) permission_classes = (IsAuthenticated,) def get_object(self, pk): @@ -563,7 +563,7 @@ def delete(self, request, pk, **kwargs): class LeadUploadView(APIView): model = Lead - # authentication_classes = (JSONWebTokenAuthentication,) + authentication_classes = (CustomDualAuthentication,) permission_classes = (IsAuthenticated,) @extend_schema(tags=["Leads"], parameters=swagger_params1.organization_params,request=LeadUploadSwaggerSerializer) @@ -589,7 +589,7 @@ def post(self, request, *args, **kwargs): class LeadCommentView(APIView): model = Comment - # authentication_classes = (JSONWebTokenAuthentication,) + authentication_classes = (CustomDualAuthentication,) permission_classes = (IsAuthenticated,) def get_object(self, pk): @@ -648,7 +648,7 @@ def delete(self, request, pk, format=None): class LeadAttachmentView(APIView): model = Attachments - # authentication_classes = (JSONWebTokenAuthentication,) + authentication_classes = (CustomDualAuthentication,) permission_classes = (IsAuthenticated,) @extend_schema(tags=["Leads"], parameters=swagger_params1.organization_params) diff --git a/opportunity/migrations/0002_alter_opportunity_created_by.py b/opportunity/migrations/0002_alter_opportunity_created_by.py new file mode 100644 index 000000000..f4b2ec97e --- /dev/null +++ b/opportunity/migrations/0002_alter_opportunity_created_by.py @@ -0,0 +1,21 @@ +# Generated by Django 4.2.1 on 2023-10-31 12:35 + +from django.conf import settings +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ('opportunity', '0001_initial'), + ] + + operations = [ + migrations.AlterField( + model_name='opportunity', + name='created_by', + field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='%(class)s_created_by', to=settings.AUTH_USER_MODEL, verbose_name='Created By'), + ), + ] diff --git a/opportunity/models.py b/opportunity/models.py index beea932d2..be39c6476 100644 --- a/opportunity/models.py +++ b/opportunity/models.py @@ -47,12 +47,6 @@ class Opportunity(BaseModel): assigned_to = models.ManyToManyField( Profile, related_name="opportunity_assigned_to" ) - created_by = models.ForeignKey( - Profile, - related_name="opportunity_created_by", - on_delete=models.SET_NULL, - null=True, - ) is_active = models.BooleanField(default=False) tags = models.ManyToManyField(Tags, blank=True) teams = models.ManyToManyField(Teams, related_name="oppurtunity_teams") diff --git a/opportunity/serializer.py b/opportunity/serializer.py index e99a482e0..436b3f31d 100644 --- a/opportunity/serializer.py +++ b/opportunity/serializer.py @@ -2,7 +2,7 @@ from accounts.models import Tags from accounts.serializer import AccountSerializer -from common.serializer import AttachmentsSerializer, ProfileSerializer +from common.serializer import AttachmentsSerializer, ProfileSerializer,UserSerializer from contacts.serializer import ContactSerializer from opportunity.models import Opportunity from teams.serializer import TeamsSerializer @@ -17,7 +17,7 @@ class Meta: class OpportunitySerializer(serializers.ModelSerializer): account = AccountSerializer() closed_by = ProfileSerializer() - created_by = ProfileSerializer() + created_by = UserSerializer() tags = TagsSerializer(read_only=True, many=True) assigned_to = ProfileSerializer(read_only=True, many=True) contacts = ContactSerializer(read_only=True, many=True) diff --git a/opportunity/views.py b/opportunity/views.py index dc26775ae..3ab18f159 100644 --- a/opportunity/views.py +++ b/opportunity/views.py @@ -12,7 +12,7 @@ from accounts.serializer import AccountSerializer, TagsSerailizer from common.models import Attachments, Comment, Profile -# from common.custom_auth import JSONWebTokenAuthentication +from common.external_auth import CustomDualAuthentication from common.serializer import ( AttachmentsSerializer, CommentSerializer, @@ -30,7 +30,7 @@ class OpportunityListView(APIView, LimitOffsetPagination): - # authentication_classes = (JSONWebTokenAuthentication,) + authentication_classes = (CustomDualAuthentication,) permission_classes = (IsAuthenticated,) model = Opportunity @@ -41,13 +41,13 @@ def get_context_data(self, **kwargs): contacts = Contact.objects.filter(org=self.request.profile.org) if self.request.profile.role != "ADMIN" and not self.request.user.is_superuser: queryset = queryset.filter( - Q(created_by=self.request.profile) | Q(assigned_to=self.request.profile) + Q(created_by=self.request.profile.user) | Q(assigned_to=self.request.profile) ).distinct() accounts = accounts.filter( - Q(created_by=self.request.profile) | Q(assigned_to=self.request.profile) + Q(created_by=self.request.profile.user) | Q(assigned_to=self.request.profile) ).distinct() contacts = contacts.filter( - Q(created_by=self.request.profile) | Q(assigned_to=self.request.profile) + Q(created_by=self.request.profile.user) | Q(assigned_to=self.request.profile) ).distinct() if params: @@ -63,7 +63,7 @@ def get_context_data(self, **kwargs): ) if params.get("tags"): queryset = queryset.filter( - tags__in=json.loads(params.get("tags")) + tags__in=params.get("tags") ).distinct() context = {} @@ -113,18 +113,18 @@ def post(self, request, *args, **kwargs): serializer = OpportunityCreateSerializer(data=params, request_obj=request) if serializer.is_valid(): opportunity_obj = serializer.save( - created_by=request.profile, + created_by=request.profile.user, closed_on=params.get("due_date"), org=request.profile.org, ) if params.get("contacts"): - contacts_list = json.loads(params.get("contacts")) + contacts_list = params.get("contacts") contacts = Contact.objects.filter(id__in=contacts_list, org=request.profile.org) opportunity_obj.contacts.add(*contacts) if params.get("tags"): - tags = json.loads(params.get("tags")) + tags = params.get("tags") for tag in tags: obj_tag = Tags.objects.filter(slug=tag.lower()) if obj_tag.exists(): @@ -139,12 +139,12 @@ def post(self, request, *args, **kwargs): opportunity_obj.closed_by = self.request.profile if params.get("teams"): - teams_list = json.loads(params.get("teams")) + teams_list = params.get("teams") teams = Teams.objects.filter(id__in=teams_list, org=request.profile.org) opportunity_obj.teams.add(*teams) if params.get("assigned_to"): - assinged_to_list = json.loads(params.get("assigned_to")) + assinged_to_list = params.get("assigned_to") profiles = Profile.objects.filter( id__in=assinged_to_list, org=request.profile.org, is_active=True ) @@ -152,7 +152,7 @@ def post(self, request, *args, **kwargs): if self.request.FILES.get("opportunity_attachment"): attachment = Attachments() - attachment.created_by = self.request.profile + attachment.created_by = self.request.profile.user attachment.file_name = self.request.FILES.get( "opportunity_attachment" ).name @@ -180,7 +180,7 @@ def post(self, request, *args, **kwargs): class OpportunityDetailView(APIView): - # authentication_classes = (JSONWebTokenAuthentication,) + authentication_classes = (CustomDualAuthentication,) permission_classes = (IsAuthenticated,) model = Opportunity @@ -226,13 +226,13 @@ def put(self, request, pk, format=None): ) opportunity_object.contacts.clear() if params.get("contacts"): - contacts_list = json.loads(params.get("contacts")) + contacts_list = params.get("contacts") contacts = Contact.objects.filter(id__in=contacts_list, org=request.profile.org) opportunity_object.contacts.add(*contacts) opportunity_object.tags.clear() if params.get("tags"): - tags = json.loads(params.get("tags")) + tags = params.get("tags") for tag in tags: obj_tag = Tags.objects.filter(slug=tag.lower()) if obj_tag.exists(): @@ -248,13 +248,13 @@ def put(self, request, pk, format=None): opportunity_object.teams.clear() if params.get("teams"): - teams_list = json.loads(params.get("teams")) + teams_list = params.get("teams") teams = Teams.objects.filter(id__in=teams_list, org=request.profile.org) opportunity_object.teams.add(*teams) opportunity_object.assigned_to.clear() if params.get("assigned_to"): - assinged_to_list = json.loads(params.get("assigned_to")) + assinged_to_list = params.get("assigned_to") profiles = Profile.objects.filter( id__in=assinged_to_list, org=request.profile.org, is_active=True ) @@ -262,7 +262,7 @@ def put(self, request, pk, format=None): if self.request.FILES.get("opportunity_attachment"): attachment = Attachments() - attachment.created_by = self.request.profile + attachment.created_by = self.request.profile.user attachment.file_name = self.request.FILES.get( "opportunity_attachment" ).name @@ -423,7 +423,7 @@ def post(self, request, pk, **kwargs): if self.request.FILES.get("opportunity_attachment"): attachment = Attachments() - attachment.created_by = self.request.profile + attachment.created_by = self.request.profile.user attachment.file_name = self.request.FILES.get( "opportunity_attachment" ).name @@ -449,7 +449,7 @@ def post(self, request, pk, **kwargs): class OpportunityCommentView(APIView): model = Comment - # authentication_classes = (JSONWebTokenAuthentication,) + authentication_classes = (CustomDualAuthentication,) permission_classes = (IsAuthenticated,) def get_object(self, pk): @@ -513,7 +513,7 @@ def delete(self, request, pk, format=None): class OpportunityAttachmentView(APIView): model = Attachments - # authentication_classes = (JSONWebTokenAuthentication,) + authentication_classes = (CustomDualAuthentication,) permission_classes = (IsAuthenticated,) @extend_schema( diff --git a/tasks/migrations/0002_alter_task_created_by.py b/tasks/migrations/0002_alter_task_created_by.py new file mode 100644 index 000000000..3460261ff --- /dev/null +++ b/tasks/migrations/0002_alter_task_created_by.py @@ -0,0 +1,21 @@ +# Generated by Django 4.2.1 on 2023-10-31 12:42 + +from django.conf import settings +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ('tasks', '0001_initial'), + ] + + operations = [ + migrations.AlterField( + model_name='task', + name='created_by', + field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='%(class)s_created_by', to=settings.AUTH_USER_MODEL, verbose_name='Created By'), + ), + ] diff --git a/tasks/models.py b/tasks/models.py index 1578c694a..1fa891b95 100644 --- a/tasks/models.py +++ b/tasks/models.py @@ -35,13 +35,13 @@ class Task(BaseModel): assigned_to = models.ManyToManyField(Profile, related_name="users_tasks") - created_by = models.ForeignKey( - Profile, - related_name="task_created", - blank=True, - null=True, - on_delete=models.SET_NULL, - ) + # created_by = models.ForeignKey( + # Profile, + # related_name="task_created", + # blank=True, + # null=True, + # on_delete=models.SET_NULL, + # ) teams = models.ManyToManyField(Teams, related_name="tasks_teams") org = models.ForeignKey( Org, on_delete=models.SET_NULL, null=True, blank=True, related_name="task_org" diff --git a/tasks/serializer.py b/tasks/serializer.py index 85be62bf1..cf4b6acbc 100644 --- a/tasks/serializer.py +++ b/tasks/serializer.py @@ -4,6 +4,7 @@ AttachmentsSerializer, CommentSerializer, ProfileSerializer, + UserSerializer ) from contacts.serializer import ContactSerializer from tasks.models import Task @@ -11,7 +12,7 @@ class TaskSerializer(serializers.ModelSerializer): - created_by = ProfileSerializer() + created_by = UserSerializer() assigned_to = ProfileSerializer(read_only=True, many=True) contacts = ContactSerializer(read_only=True, many=True) teams = TeamsSerializer(read_only=True, many=True) diff --git a/tasks/views.py b/tasks/views.py index 724c22d28..348c812fc 100644 --- a/tasks/views.py +++ b/tasks/views.py @@ -12,7 +12,7 @@ from accounts.serializer import AccountSerializer from common.models import Attachments, Comment, Profile -# from common.custom_auth import JSONWebTokenAuthentication +from common.external_auth import CustomDualAuthentication from common.serializer import ( AttachmentsSerializer, CommentSerializer, @@ -30,7 +30,7 @@ class TaskListView(APIView, LimitOffsetPagination): model = Task - # authentication_classes = (JSONWebTokenAuthentication,) + authentication_classes = (CustomDualAuthentication,) permission_classes = (IsAuthenticated,) def get_context_data(self, **kwargs): @@ -41,13 +41,13 @@ def get_context_data(self, **kwargs): if self.request.profile.role != "ADMIN" and not self.request.profile.is_admin: queryset = queryset.filter( Q(assigned_to__in=[self.request.profile]) - | Q(created_by=self.request.profile) + | Q(created_by=self.request.profile.user) ) accounts = accounts.filter( - Q(created_by=self.request.profile) | Q(assigned_to=self.request.profile) + Q(created_by=self.request.profile.user) | Q(assigned_to=self.request.profile) ).distinct() contacts = contacts.filter( - Q(created_by=self.request.profile) | Q(assigned_to=self.request.profile) + Q(created_by=self.request.profile.user) | Q(assigned_to=self.request.profile) ).distinct() if params: @@ -96,22 +96,22 @@ def post(self, request, *args, **kwargs): serializer = TaskCreateSerializer(data=params, request_obj=request) if serializer.is_valid(): task_obj = serializer.save( - created_by=request.profile, + created_by=request.profile.user, due_date=params.get("due_date"), org=request.profile.org, ) if params.get("contacts"): - contacts_list = json.loads(params.get("contacts")) + contacts_list = params.get("contacts") contacts = Contact.objects.filter(id__in=contacts_list, org=request.profile.org) task_obj.contacts.add(*contacts) if params.get("teams"): - teams_list = json.loads(params.get("teams")) + teams_list = params.get("teams") teams = Teams.objects.filter(id__in=teams_list, org=request.profile.org) task_obj.teams.add(*teams) if params.get("assigned_to"): - assinged_to_list = json.loads(params.get("assigned_to")) + assinged_to_list = params.get("assigned_to") profiles = Profile.objects.filter( id__in=assinged_to_list, org=request.profile.org, is_active=True ) @@ -129,7 +129,7 @@ def post(self, request, *args, **kwargs): class TaskDetailView(APIView): model = Task - # authentication_classes = (JSONWebTokenAuthentication,) + authentication_classes = (CustomDualAuthentication,) permission_classes = (IsAuthenticated,) def get_object(self, pk): @@ -246,7 +246,7 @@ def post(self, request, pk, **kwargs): if self.request.FILES.get("task_attachment"): attachment = Attachments() - attachment.created_by = self.request.profile + attachment.created_by = self.request.profile.user attachment.file_name = self.request.FILES.get("task_attachment").name attachment.task = self.task_obj attachment.attachment = self.request.FILES.get("task_attachment") @@ -283,19 +283,19 @@ def put(self, request, pk, **kwargs): ) task_obj.contacts.clear() if params.get("contacts"): - contacts_list = json.loads(params.get("contacts")) + contacts_list = params.get("contacts") contacts = Contact.objects.filter(id__in=contacts_list, org=request.profile.org) task_obj.contacts.add(*contacts) task_obj.teams.clear() if params.get("teams"): - teams_list = json.loads(params.get("teams")) + teams_list = params.get("teams") teams = Teams.objects.filter(id__in=teams_list, org=request.profile.org) task_obj.teams.add(*teams) task_obj.assigned_to.clear() if params.get("assigned_to"): - assinged_to_list = json.loads(params.get("assigned_to")) + assinged_to_list = params.get("assigned_to") profiles = Profile.objects.filter( id__in=assinged_to_list, org=request.profile.org, is_active=True ) @@ -333,7 +333,7 @@ def delete(self, request, pk, **kwargs): class TaskCommentView(APIView): model = Comment - # authentication_classes = (JSONWebTokenAuthentication,) + authentication_classes = (CustomDualAuthentication,) permission_classes = (IsAuthenticated,) def get_object(self, pk): @@ -397,7 +397,7 @@ def delete(self, request, pk, format=None): class TaskAttachmentView(APIView): model = Attachments - # authentication_classes = (JSONWebTokenAuthentication,) + authentication_classes = (CustomDualAuthentication,) permission_classes = (IsAuthenticated,) @extend_schema( diff --git a/teams/serializer.py b/teams/serializer.py index 5178dd029..fc6a8b634 100644 --- a/teams/serializer.py +++ b/teams/serializer.py @@ -1,12 +1,12 @@ from rest_framework import serializers -from common.serializer import ProfileSerializer +from common.serializer import ProfileSerializer,UserSerializer from teams.models import Teams class TeamsSerializer(serializers.ModelSerializer): users = ProfileSerializer(read_only=True, many=True) - created_by = ProfileSerializer() + created_by = UserSerializer() class Meta: model = Teams diff --git a/teams/views.py b/teams/views.py index dda221c1d..ba33a5805 100644 --- a/teams/views.py +++ b/teams/views.py @@ -1,7 +1,7 @@ import json from drf_spectacular.utils import OpenApiExample, OpenApiParameter, extend_schema -# from common.custom_auth import JSONWebTokenAuthentication +from common.external_auth import CustomDualAuthentication from rest_framework import status from rest_framework.pagination import LimitOffsetPagination from rest_framework.permissions import IsAuthenticated @@ -17,7 +17,7 @@ class TeamsListView(APIView, LimitOffsetPagination): model = Teams - # authentication_classes = (JSONWebTokenAuthentication,) + authentication_classes = (CustomDualAuthentication,) permission_classes = (IsAuthenticated,) def get_context_data(self, **kwargs): @@ -30,7 +30,7 @@ def get_context_data(self, **kwargs): queryset = queryset.filter(created_by=params.get("created_by")) if params.get("assigned_users"): queryset = queryset.filter( - users__id__in=json.loads(params.get("assigned_users")) + users__id__in=params.get("assigned_users") ) context = {} @@ -85,7 +85,7 @@ def post(self, request, *args, **kwargs): team_obj = serializer.save(org=request.profile.org) if params.get("assign_users"): - assinged_to_list = json.loads(params.get("users")) + assinged_to_list = params.get("users") profiles = Profile.objects.filter( id__in=assinged_to_list, org=request.profile.org ) @@ -103,7 +103,7 @@ def post(self, request, *args, **kwargs): class TeamsDetailView(APIView): model = Teams - # authentication_classes = (JSONWebTokenAuthentication,) + authentication_classes = (CustomDualAuthentication,) permission_classes = (IsAuthenticated,) def get_object(self, pk):