Author | SHA1 | Message | Date |
---|---|---|---|
|
a2ae0403e7 | test | 2 years ago |
@@ -1,6 +1,6 @@ | |||||
from django.apps import AppConfig | from django.apps import AppConfig | ||||
class UserConfig(AppConfig): | |||||
class AccountsConfig(AppConfig): | |||||
default_auto_field = 'django.db.models.BigAutoField' | default_auto_field = 'django.db.models.BigAutoField' | ||||
name = 'user' | |||||
name = 'accounts' |
@@ -0,0 +1,7 @@ | |||||
from django import forms | |||||
from .models import Account | |||||
class AccountForm(forms.ModelForm): | |||||
class Meta: | |||||
model = Account | |||||
exclude = () # |
@@ -0,0 +1,28 @@ | |||||
# Generated by Django 4.1.9 on 2023-07-17 23:26 | |||||
from django.db import migrations, models | |||||
class Migration(migrations.Migration): | |||||
initial = True | |||||
dependencies = [ | |||||
] | |||||
operations = [ | |||||
migrations.CreateModel( | |||||
name='Account', | |||||
fields=[ | |||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), | |||||
('name', models.CharField(max_length=100)), | |||||
('address', models.CharField(max_length=200)), | |||||
('phone_number', models.CharField(max_length=20)), | |||||
('email', models.EmailField(max_length=254)), | |||||
('created_at', models.DateTimeField(auto_now_add=True)), | |||||
('total_revenue', models.DecimalField(decimal_places=2, default=0, max_digits=10)), | |||||
('total_expenses', models.DecimalField(decimal_places=2, default=0, max_digits=10)), | |||||
('total_investments', models.DecimalField(decimal_places=2, default=0, max_digits=10)), | |||||
], | |||||
), | |||||
] |
@@ -0,0 +1,72 @@ | |||||
# Generated by Django 4.1.9 on 2023-07-18 11:13 | |||||
from django.db import migrations, models | |||||
import django.db.models.deletion | |||||
class Migration(migrations.Migration): | |||||
dependencies = [ | |||||
('common', '0001_initial'), | |||||
('employee', '0002_alter_employee_user'), | |||||
('accounts', '0001_initial'), | |||||
] | |||||
operations = [ | |||||
migrations.CreateModel( | |||||
name='Client', | |||||
fields=[ | |||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), | |||||
('name', models.CharField(max_length=100)), | |||||
], | |||||
), | |||||
migrations.CreateModel( | |||||
name='Expense', | |||||
fields=[ | |||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), | |||||
('category', models.CharField(choices=[('Food', 'Food'), ('Fuel', 'Fuel'), ('Traveling', 'Traveling'), ('Gifts', 'Gifts')], max_length=100)), | |||||
('title', models.CharField(max_length=100)), | |||||
('bill_number', models.CharField(max_length=100)), | |||||
('date', models.DateField()), | |||||
('reimbursement', models.BooleanField()), | |||||
('bank_account', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='common.bankdetails')), | |||||
('employee', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='employee.employee')), | |||||
], | |||||
), | |||||
migrations.CreateModel( | |||||
name='Income', | |||||
fields=[ | |||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), | |||||
('type', models.CharField(choices=[('Invoice', 'Invoice'), ('Dividend', 'Dividend')], max_length=10)), | |||||
('title', models.CharField(max_length=100)), | |||||
('invoice_number', models.CharField(max_length=100)), | |||||
('date', models.DateField()), | |||||
('client', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='accounts.client')), | |||||
], | |||||
), | |||||
migrations.CreateModel( | |||||
name='Project', | |||||
fields=[ | |||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), | |||||
('name', models.CharField(max_length=100)), | |||||
], | |||||
), | |||||
migrations.CreateModel( | |||||
name='Reimbursement', | |||||
fields=[ | |||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), | |||||
('title', models.CharField(max_length=100)), | |||||
('rate', models.DecimalField(decimal_places=2, max_digits=10)), | |||||
('quantity', models.PositiveIntegerField()), | |||||
('status', models.CharField(max_length=10)), | |||||
], | |||||
), | |||||
migrations.DeleteModel( | |||||
name='Account', | |||||
), | |||||
migrations.AddField( | |||||
model_name='income', | |||||
name='project', | |||||
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='accounts.project'), | |||||
), | |||||
] |
@@ -0,0 +1,76 @@ | |||||
from django.db import models | |||||
# Create your models here. | |||||
from employee.models import Employee | |||||
from common.models import BankDetails | |||||
class Client(models.Model): | |||||
name = models.CharField(max_length=100) | |||||
# Other fields for client information | |||||
def __str__(self): | |||||
return self.name | |||||
class Project(models.Model): | |||||
name = models.CharField(max_length=100) | |||||
# Other fields for project information | |||||
def __str__(self): | |||||
return self.name | |||||
class Income(models.Model): | |||||
TYPE_CHOICES = [ | |||||
('Invoice', 'Invoice'), | |||||
('Dividend', 'Dividend'), | |||||
] | |||||
type = models.CharField(max_length=10, choices=TYPE_CHOICES) | |||||
title = models.CharField(max_length=100) | |||||
invoice_number = models.CharField(max_length=100) | |||||
date = models.DateField() | |||||
client = models.ForeignKey(Client, on_delete=models.CASCADE) | |||||
project = models.ForeignKey(Project, on_delete=models.CASCADE) | |||||
# Other fields specific to income | |||||
def __str__(self): | |||||
return self.title | |||||
class Expense(models.Model): | |||||
CATEGORY_CHOICES = [ | |||||
('Food', 'Food'), | |||||
('Fuel', 'Fuel'), | |||||
('Traveling', 'Traveling'), | |||||
('Gifts', 'Gifts'), | |||||
# Other expense categories | |||||
] | |||||
category = models.CharField(max_length=100, choices=CATEGORY_CHOICES) | |||||
title = models.CharField(max_length=100) | |||||
bill_number = models.CharField(max_length=100) | |||||
date = models.DateField() | |||||
employee = models.ForeignKey(Employee, on_delete=models.CASCADE) | |||||
bank_account = models.ForeignKey(BankDetails, on_delete=models.CASCADE) | |||||
reimbursement = models.BooleanField() | |||||
# Other fields specific to expenses | |||||
def __str__(self): | |||||
return self.title | |||||
class Reimbursement(models.Model): | |||||
STATUS_CHOICES=[ | |||||
('Paid','Paid'), | |||||
('Due', 'Due'), | |||||
('Overdue', 'Overdue'), | |||||
] | |||||
title = models.CharField(max_length=100) | |||||
rate = models.DecimalField(max_digits=10, decimal_places=2) | |||||
quantity = models.PositiveIntegerField() | |||||
status = models.CharField(max_length=10, choices=STATUS_CHOICES) # Paid, Due, Overdue | |||||
# Other fields specific to reimbursements | |||||
def __str__(self): | |||||
return self.title |
@@ -0,0 +1,19 @@ | |||||
from rest_framework import serializers | |||||
from .models import Income, Expense, Reimbursement | |||||
class IncomeSerializer(serializers.ModelSerializer): | |||||
class Meta: | |||||
model = Income | |||||
fields = '__all__' | |||||
class ExpenseSerializer(serializers.ModelSerializer): | |||||
class Meta: | |||||
model = Expense | |||||
fields = '__all__' | |||||
class ReimbursementSerializer(serializers.ModelSerializer): | |||||
class Meta: | |||||
model = Reimbursement | |||||
fields = '__all__' |
@@ -0,0 +1,17 @@ | |||||
from rest_framework import viewsets | |||||
from .models import Income, Expense, Reimbursement | |||||
from .serializers import IncomeSerializer, ExpenseSerializer, ReimbursementSerializer | |||||
class IncomeViewSet(viewsets.ModelViewSet): | |||||
queryset = Income.objects.all() | |||||
serializer_class = IncomeSerializer | |||||
class ExpenseViewSet(viewsets.ModelViewSet): | |||||
queryset = Expense.objects.all() | |||||
serializer_class = ExpenseSerializer | |||||
class ReimbursementViewSet(viewsets.ModelViewSet): | |||||
queryset = Reimbursement.objects.all() | |||||
serializer_class = ReimbursementSerializer |
@@ -1,8 +0,0 @@ | |||||
from django.shortcuts import render | |||||
from django.contrib import messages | |||||
from django.shortcuts import redirect | |||||
def signup_redirect(request): | |||||
messages.error(request, "Something wrong here, it may be that you already have account!") | |||||
return redirect("homepage") |
@@ -0,0 +1,48 @@ | |||||
# Generated by Django 4.1.9 on 2023-07-17 22:36 | |||||
from django.db import migrations, models | |||||
class Migration(migrations.Migration): | |||||
initial = True | |||||
dependencies = [ | |||||
] | |||||
operations = [ | |||||
migrations.CreateModel( | |||||
name='Address', | |||||
fields=[ | |||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), | |||||
('address_line_1', models.CharField(max_length=200)), | |||||
('address_line_2', models.CharField(blank=True, max_length=200)), | |||||
('city', models.CharField(max_length=50)), | |||||
('state', models.CharField(max_length=50)), | |||||
('zip_code', models.CharField(max_length=10)), | |||||
('country', models.CharField(max_length=50)), | |||||
], | |||||
options={ | |||||
'db_table': 'address', | |||||
}, | |||||
), | |||||
migrations.CreateModel( | |||||
name='BankDetails', | |||||
fields=[ | |||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), | |||||
('beneficiary_name', models.CharField(max_length=50)), | |||||
('bank_name', models.CharField(max_length=50)), | |||||
('account_number', models.CharField(max_length=20)), | |||||
('ifsc_code', models.CharField(max_length=20)), | |||||
('branch_name', models.CharField(max_length=50)), | |||||
('upi_id', models.CharField(blank=True, max_length=50)), | |||||
], | |||||
), | |||||
migrations.CreateModel( | |||||
name='NatureOfBusiness', | |||||
fields=[ | |||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), | |||||
('name', models.CharField(max_length=50)), | |||||
], | |||||
), | |||||
] |
@@ -0,0 +1,47 @@ | |||||
# Generated by Django 4.1.9 on 2023-07-19 21:26 | |||||
from django.db import migrations, models | |||||
import django.db.models.deletion | |||||
class Migration(migrations.Migration): | |||||
initial = True | |||||
dependencies = [ | |||||
('common', '0001_initial'), | |||||
] | |||||
operations = [ | |||||
migrations.CreateModel( | |||||
name='Company', | |||||
fields=[ | |||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), | |||||
('legal_name', models.CharField(max_length=256)), | |||||
('trade_name', models.CharField(max_length=256)), | |||||
('cin', models.CharField(max_length=64)), | |||||
('cin_proof', models.FileField(null=True, upload_to='company_proofs/')), | |||||
('gstin', models.CharField(max_length=16)), | |||||
('gstin_proof', models.FileField(null=True, upload_to='company_proofs/')), | |||||
('date_of_incorporation', models.DateField()), | |||||
('date_of_incorporation_proof', models.FileField(null=True, upload_to='company_proofs/')), | |||||
('pan', models.CharField(max_length=16)), | |||||
('pan_proof', models.FileField(null=True, upload_to='company_proofs/')), | |||||
('iec', models.CharField(max_length=16)), | |||||
('iec_proof', models.FileField(null=True, upload_to='company_proofs/')), | |||||
('msme_code', models.CharField(max_length=64)), | |||||
('msme_proof', models.FileField(null=True, upload_to='company_proofs/')), | |||||
('provident_fund_code_number', models.CharField(max_length=32)), | |||||
('provident_fund_code_number_proof', models.FileField(null=True, upload_to='company_proofs/')), | |||||
('se_registration_number', models.CharField(max_length=32)), | |||||
('se_registration_number_proof', models.FileField(null=True, upload_to='company_proofs/')), | |||||
('phone_number', models.CharField(max_length=13)), | |||||
('support_email', models.EmailField(max_length=254, null=True, unique=True)), | |||||
('address', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, to='common.address')), | |||||
('nature_of_business', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, to='common.natureofbusiness')), | |||||
], | |||||
options={ | |||||
'db_table': 'company', | |||||
}, | |||||
), | |||||
] |
@@ -1,5 +1,5 @@ | |||||
from django.shortcuts import render | from django.shortcuts import render | ||||
from rest_framework import viewsets | |||||
from rest_framework import viewsets, permissions | |||||
from .models import Company | from .models import Company | ||||
from .form import CompanyForm | from .form import CompanyForm | ||||
from .serializers import CompanySerializer | from .serializers import CompanySerializer | ||||
@@ -7,6 +7,7 @@ from .serializers import CompanySerializer | |||||
class CompanyViewSet(viewsets.ModelViewSet): | class CompanyViewSet(viewsets.ModelViewSet): | ||||
queryset = Company.objects.all() | queryset = Company.objects.all() | ||||
serializer_class = CompanySerializer | serializer_class = CompanySerializer | ||||
permission_classes = [permissions.IsAuthenticated] | |||||
def perform_create(self, serializer): | def perform_create(self, serializer): | ||||
form_data = self.request.data.get('form') | form_data = self.request.data.get('form') | ||||
@@ -1,7 +1,7 @@ | |||||
from django.contrib import admin | from django.contrib import admin | ||||
# Register your models here. | # Register your models here. | ||||
from employee.models import Department, Employee | |||||
from employee.models import Employee | |||||
admin.site.register(Department) | |||||
admin.site.register(Employee) | admin.site.register(Employee) |
@@ -0,0 +1,42 @@ | |||||
# Generated by Django 4.1.9 on 2023-07-17 22:35 | |||||
from django.conf import settings | |||||
from django.db import migrations, models | |||||
import django.db.models.deletion | |||||
class Migration(migrations.Migration): | |||||
initial = True | |||||
dependencies = [ | |||||
migrations.swappable_dependency(settings.AUTH_USER_MODEL), | |||||
('common', '__first__'), | |||||
] | |||||
operations = [ | |||||
migrations.CreateModel( | |||||
name='Role', | |||||
fields=[ | |||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), | |||||
('name', models.CharField(max_length=50, unique=True)), | |||||
], | |||||
), | |||||
migrations.CreateModel( | |||||
name='Employee', | |||||
fields=[ | |||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), | |||||
('first_name', models.CharField(max_length=30)), | |||||
('last_name', models.CharField(max_length=30)), | |||||
('personal_email', models.EmailField(max_length=254, unique=True)), | |||||
('official_email', models.EmailField(max_length=254, unique=True)), | |||||
('phone_number', models.CharField(max_length=13)), | |||||
('job_title', models.CharField(max_length=100)), | |||||
('ctc', models.DecimalField(decimal_places=2, max_digits=10)), | |||||
('address', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, to='common.address')), | |||||
('bank_details', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, to='common.bankdetails')), | |||||
('role', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, to='employee.role')), | |||||
('user', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)), | |||||
], | |||||
), | |||||
] |
@@ -0,0 +1,21 @@ | |||||
# Generated by Django 4.1.9 on 2023-07-17 22:46 | |||||
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), | |||||
('employee', '0001_initial'), | |||||
] | |||||
operations = [ | |||||
migrations.AlterField( | |||||
model_name='employee', | |||||
name='user', | |||||
field=models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, related_name='employee', to=settings.AUTH_USER_MODEL), | |||||
), | |||||
] |
@@ -1,15 +1,11 @@ | |||||
from django.db import models | from django.db import models | ||||
from common.models import BankDetails, Address | from common.models import BankDetails, Address | ||||
class Department(models.Model): | |||||
name = models.CharField(max_length=50) | |||||
def __str__(self): | |||||
return self.name | |||||
from django.contrib.auth.models import User | |||||
class Employee(models.Model): | class Employee(models.Model): | ||||
user = models.OneToOneField(User, on_delete=models.CASCADE, related_name='employee') | |||||
# Rest of the fields... | |||||
role = models.ForeignKey('Role', on_delete=models.SET_NULL, null=True) | |||||
first_name = models.CharField(max_length=30) | first_name = models.CharField(max_length=30) | ||||
last_name = models.CharField(max_length=30) | last_name = models.CharField(max_length=30) | ||||
personal_email = models.EmailField(unique=True) | personal_email = models.EmailField(unique=True) | ||||
@@ -17,9 +13,14 @@ class Employee(models.Model): | |||||
phone_number = models.CharField(max_length=13) | phone_number = models.CharField(max_length=13) | ||||
address = models.ForeignKey(Address, on_delete=models.SET_NULL, null=True) | address = models.ForeignKey(Address, on_delete=models.SET_NULL, null=True) | ||||
job_title = models.CharField(max_length=100) | job_title = models.CharField(max_length=100) | ||||
department = models.ManyToManyField(Department) | |||||
ctc = models.DecimalField(max_digits=10, decimal_places=2) | ctc = models.DecimalField(max_digits=10, decimal_places=2) | ||||
bank_details = models.OneToOneField(BankDetails, on_delete=models.CASCADE) | bank_details = models.OneToOneField(BankDetails, on_delete=models.CASCADE) | ||||
def __str__(self): | def __str__(self): | ||||
return f"{self.first_name} {self.last_name}" | return f"{self.first_name} {self.last_name}" | ||||
class Role(models.Model): | |||||
name = models.CharField(max_length=50, unique=True) | |||||
def __str__(self): | |||||
return self.name |
@@ -0,0 +1,45 @@ | |||||
from rest_framework import permissions | |||||
def has_permission(self, request, view): | |||||
if request.user.is_authenticated: | |||||
try: | |||||
employee = request.user.employee | |||||
return employee is not None and employee.role is not None | |||||
except Employee.DoesNotExist: | |||||
return False | |||||
return False | |||||
from .models import Employee | |||||
class EmployeeAPIPermission(permissions.BasePermission): | |||||
def has_permission(self, request, view): | |||||
if request.method in permissions.SAFE_METHODS: | |||||
return True # Allow GET requests for all users | |||||
user = request.user | |||||
if user.is_authenticated and user.role: | |||||
role_name = user.role.name | |||||
if role_name == 'Admin': | |||||
return True # Allow CRUD operations for Admin role | |||||
elif role_name == 'Employee' and request.method in ['GET', 'PUT']: | |||||
return True # Allow GET and PUT requests for Employee role | |||||
return False | |||||
from rest_framework import permissions | |||||
class GoogleAuthenticatedPermission(permissions.BasePermission): | |||||
def has_permission(self, request, view): | |||||
# Check if the user is authenticated | |||||
if not request.user.is_authenticated: | |||||
return False | |||||
# Check if the user is authenticated with a Google account | |||||
if 'email' not in request.session: | |||||
return False | |||||
# Perform additional checks if needed | |||||
# For example, verify the email in request.session with the email from id_token_data | |||||
return True | |||||
@@ -1,12 +1,29 @@ | |||||
from rest_framework import serializers | from rest_framework import serializers | ||||
from common.serializers import BankDetailsSerializer, AddressSerializer | from common.serializers import BankDetailsSerializer, AddressSerializer | ||||
from .models import Employee | |||||
from .models import Employee,Role | |||||
from common.models import BankDetails, Address | |||||
class EmployeeSerializer(serializers.ModelSerializer): | class EmployeeSerializer(serializers.ModelSerializer): | ||||
address = AddressSerializer() | |||||
bank_details = BankDetailsSerializer() | bank_details = BankDetailsSerializer() | ||||
address = AddressSerializer() | |||||
class Meta: | class Meta: | ||||
model = Employee | model = Employee | ||||
fields = '__all__' | |||||
fields = '__all__' | |||||
def create(self, validated_data): | |||||
bank_details_data = validated_data.pop('bank_details') | |||||
address_data = validated_data.pop('address') | |||||
bank_details = BankDetails.objects.create(**bank_details_data) | |||||
address = Address.objects.create(**address_data) | |||||
employee = Employee.objects.create(bank_details=bank_details, address=address, **validated_data) | |||||
return employee | |||||
class RoleSerializer(serializers.ModelSerializer): | |||||
class Meta: | |||||
model = Role | |||||
fields = '__all__' |
@@ -1,25 +1,27 @@ | |||||
from rest_framework import viewsets | |||||
from rest_framework import viewsets,permissions | |||||
from .models import Employee | from .models import Employee | ||||
from .serializers import EmployeeSerializer | from .serializers import EmployeeSerializer | ||||
from .forms import EmployeeForm | from .forms import EmployeeForm | ||||
from rest_framework import generics, permissions | |||||
from .models import Role | |||||
from .serializers import RoleSerializer | |||||
from .permissions import EmployeeAPIPermission,GoogleAuthenticatedPermission | |||||
class EmployeeViewSet(viewsets.ModelViewSet): | |||||
class RoleListCreateAPIView(generics.ListCreateAPIView): | |||||
queryset = Role.objects.all() | |||||
serializer_class = RoleSerializer | |||||
permission_classes = [permissions.IsAuthenticated, permissions.IsAdminUser] | |||||
class EmployeeListCreateAPIView(generics.ListCreateAPIView): | |||||
queryset = Employee.objects.all() | |||||
serializer_class = EmployeeSerializer | |||||
permission_classes = [permissions.IsAuthenticated| EmployeeAPIPermission] | |||||
class EmployeeRetrieveUpdateAPIView(generics.RetrieveUpdateAPIView): | |||||
queryset = Employee.objects.all() | queryset = Employee.objects.all() | ||||
serializer_class = EmployeeSerializer | serializer_class = EmployeeSerializer | ||||
permission_classes = [permissions.IsAuthenticated | EmployeeAPIPermission] | |||||
def perform_create(self, serializer): | |||||
form_data = self.request.data.get('form') | |||||
form = EmployeeForm(form_data) | |||||
if form.is_valid(): | |||||
employee = serializer.save() | |||||
form.instance = employee | |||||
form.save() | |||||
def perform_update(self, serializer): | |||||
form_data = self.request.data.get('form') | |||||
form = EmployeeForm(form_data, instance=serializer.instance) | |||||
if form.is_valid(): | |||||
employee = serializer.save() | |||||
form.instance = employee | |||||
form.save() | |||||
@@ -0,0 +1,3 @@ | |||||
from django.contrib import admin | |||||
# Register your models here. |
@@ -0,0 +1,6 @@ | |||||
from django.apps import AppConfig | |||||
class GoogleAuthConfig(AppConfig): | |||||
default_auto_field = 'django.db.models.BigAutoField' | |||||
name = 'google_auth' |
@@ -1,3 +1,3 @@ | |||||
from django.db import models | from django.db import models | ||||
# Create your models here. | |||||
# Create your models here. |
@@ -0,0 +1,3 @@ | |||||
from django.test import TestCase | |||||
# Create your tests here. |
@@ -0,0 +1,9 @@ | |||||
from django.urls import path | |||||
from . import views | |||||
app_name = 'google_auth' | |||||
urlpatterns = [ | |||||
path('login/', views.login, name='login'), | |||||
path('callback/', views.callback, name='callback'), | |||||
] |
@@ -0,0 +1,34 @@ | |||||
from django.shortcuts import redirect | |||||
from google.oauth2 import id_token | |||||
from django.conf import settings | |||||
from django.urls import reverse_lazy | |||||
import requests | |||||
from google.auth.transport import requests as google_requests | |||||
def login(request): | |||||
# Redirect the user to the Google authentication URL | |||||
redirect_uri = request.build_absolute_uri(reverse_lazy('google_auth:callback')) | |||||
authorization_url = f'https://accounts.google.com/o/oauth2/auth?response_type=code&client_id={settings.GOOGLE_OAUTH2_CLIENT_ID}&redirect_uri={redirect_uri}&scope=openid%20email%20profile' | |||||
return redirect(authorization_url) | |||||
def callback(request): | |||||
authorization_code = request.GET.get('code') | |||||
token_url = 'https://oauth2.googleapis.com/token' | |||||
redirect_uri = request.build_absolute_uri(reverse_lazy('google_auth:callback')) | |||||
token_request_data = { | |||||
'code': authorization_code, | |||||
'client_id': settings.GOOGLE_OAUTH2_CLIENT_ID, | |||||
'client_secret': settings.GOOGLE_OAUTH2_CLIENT_SECRET, | |||||
'redirect_uri': redirect_uri, | |||||
'grant_type': 'authorization_code' | |||||
} | |||||
token_response = requests.post(token_url, data=token_request_data) | |||||
token_response_data = token_response.json() | |||||
id_token_data = id_token.verify_oauth2_token( | |||||
token_response_data['id_token'], | |||||
google_requests.Request(), | |||||
settings.GOOGLE_OAUTH2_CLIENT_ID | |||||
) | |||||
return redirect('http://127.0.0.1:8000') |
@@ -0,0 +1,12 @@ | |||||
<!DOCTYPE html> | |||||
<html> | |||||
<head> | |||||
<title>Home</title> | |||||
<script> | |||||
window.location.href = "http://127.0.0.1:8000/api/"; // Replace "https://example.com" with your desired redirect URL | |||||
</script> | |||||
</head> | |||||
<body> | |||||
<h1>Redirecting...</h1> | |||||
</body> | |||||
</html> |
@@ -1,3 +0,0 @@ | |||||
from django.shortcuts import render | |||||
# Create your views here. |
@@ -27,27 +27,26 @@ DEBUG = True | |||||
ALLOWED_HOSTS = ['*'] | ALLOWED_HOSTS = ['*'] | ||||
GOOGLE_OAUTH2_CLIENT_ID = "611194092059-kk4bhv18i19cvngmi3335gtvk4nmp25d.apps.googleusercontent.com" | |||||
GOOGLE_OAUTH2_CLIENT_SECRET ="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" | |||||
# Application definition | # Application definition | ||||
INSTALLED_APPS = [ | INSTALLED_APPS = [ | ||||
'django.contrib.admin', | 'django.contrib.admin', | ||||
'django.contrib.auth', | 'django.contrib.auth', | ||||
'django.contrib.contenttypes', | 'django.contrib.contenttypes', | ||||
'django.contrib.sessions', | 'django.contrib.sessions', | ||||
'django.contrib.messages', | |||||
'django.contrib.staticfiles', | 'django.contrib.staticfiles', | ||||
'company', | 'company', | ||||
'common', | 'common', | ||||
'accounts', | |||||
'employee', | 'employee', | ||||
'client', | 'client', | ||||
'rest_framework', | 'rest_framework', | ||||
'django.contrib.sites', | |||||
'allauth', | |||||
'allauth.account', | |||||
'allauth.socialaccount', | |||||
'allauth.socialaccount.providers.google', | |||||
] | |||||
"django.contrib.messages", | |||||
"google_auth", | |||||
] | |||||
MIDDLEWARE = [ | MIDDLEWARE = [ | ||||
'django.middleware.security.SecurityMiddleware', | 'django.middleware.security.SecurityMiddleware', | ||||
@@ -79,58 +78,50 @@ TEMPLATES = [ | |||||
WSGI_APPLICATION = 'workx.wsgi.application' | WSGI_APPLICATION = 'workx.wsgi.application' | ||||
# AUTH_PASSWORD_VALIDATORS = [ | |||||
# { | |||||
# "NAME": "django.contrib.auth.password_validation." | |||||
# "UserAttributeSimilarityValidator", | |||||
# }, | |||||
# { | |||||
# "NAME": "django.contrib.auth.password_validation.MinimumLengthValidator", | |||||
# }, | |||||
# { | |||||
# "NAME": "django.contrib.auth.password_validation.CommonPasswordValidator", | |||||
# }, | |||||
# { | |||||
# "NAME": "django.contrib.auth.password_validation.NumericPasswordValidator", | |||||
# }, | |||||
# ] | |||||
# Database | # Database | ||||
# https://docs.djangoproject.com/en/4.1/ref/settings/#databases | # https://docs.djangoproject.com/en/4.1/ref/settings/#databases | ||||
DATABASES = { | DATABASES = { | ||||
'default': { | 'default': { | ||||
'ENGINE': 'djongo', | |||||
'NAME': 'WorkX', | |||||
'ENFORCE_SCHEMA': True, # Optional: enforce the database schema | |||||
'ENGINE': 'django.db.backends.postgresql_psycopg2', | |||||
'NAME': 'workxx', | |||||
'USER': 'postgres', | |||||
'PASSWORD': '123456', | |||||
'HOST': 'localhost', | |||||
'PORT': '5432', | |||||
} | } | ||||
} | } | ||||
SITE_ID = 2 | |||||
SOCIALACCOUNT_LOGIN_ON_GET=True | |||||
AUTHENTICATION_BACKENDS = [ | |||||
'allauth.account.auth_backends.AuthenticationBackend' | |||||
] | |||||
SOCIALACCOUNT_PROVIDERS = { | |||||
'google': { | |||||
'SCOPE': [ | |||||
'profile', | |||||
'email', | |||||
], | |||||
'AUTH_PARAMS': { | |||||
'access_type': 'online', | |||||
} | |||||
} | |||||
} | |||||
LOGIN_REDIRECT_URL = '/api/employee/' | |||||
# Password validation | # Password validation | ||||
# https://docs.djangoproject.com/en/4.1/ref/settings/#auth-password-validators | # https://docs.djangoproject.com/en/4.1/ref/settings/#auth-password-validators | ||||
AUTH_PASSWORD_VALIDATORS = [ | |||||
{ | |||||
'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator', | |||||
}, | |||||
{ | |||||
'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator', | |||||
}, | |||||
{ | |||||
'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator', | |||||
}, | |||||
{ | |||||
'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator', | |||||
}, | |||||
] | |||||
# GOOGLE_SSO_SCOPES = [ # default values | |||||
# "openid", | |||||
# "https://www.googleapis.com/auth/userinfo.email", | |||||
# "https://www.googleapis.com/auth/userinfo.profile", | |||||
# ] | |||||
# Internationalization | # Internationalization | ||||
@@ -15,20 +15,25 @@ Including another URLconf | |||||
""" | """ | ||||
from django.contrib import admin | from django.contrib import admin | ||||
from django.urls import path,include | from django.urls import path,include | ||||
from social_django.urls import urlpatterns as social_django_urls | |||||
from employee.views import EmployeeViewSet | |||||
from accounts.views import IncomeViewSet,ExpenseViewSet,ReimbursementViewSet | |||||
from employee.views import EmployeeListCreateAPIView,EmployeeRetrieveUpdateAPIView,RoleListCreateAPIView | |||||
from company.views import CompanyViewSet | from company.views import CompanyViewSet | ||||
from rest_framework import routers | from rest_framework import routers | ||||
from authUser.view import signup_redirect | |||||
from google_auth.views import login, callback | |||||
router = routers.DefaultRouter() | router = routers.DefaultRouter() | ||||
router.register(r'employee', EmployeeViewSet) | |||||
router.register(r'company', CompanyViewSet) | router.register(r'company', CompanyViewSet) | ||||
router.register(r'accounts/income', IncomeViewSet) | |||||
router.register(r'accounts/reimbursement', ReimbursementViewSet) | |||||
router.register(r'accounts/expense', ExpenseViewSet) | |||||
urlpatterns = [ | urlpatterns = [ | ||||
path('admin/', admin.site.urls), | path('admin/', admin.site.urls), | ||||
path('api/', include(router.urls)), | |||||
path("", include("allauth.urls")), | |||||
path('social/signup/', signup_redirect, name='signup_redirect'), | |||||
] | |||||
path('', include(router.urls)), | |||||
path('employees/', EmployeeListCreateAPIView.as_view(), name='employee-list-create'), | |||||
path('employees/<int:pk>/', EmployeeRetrieveUpdateAPIView.as_view(), name='employee-retrieve-update'), | |||||
path('roles/', RoleListCreateAPIView.as_view(), name='role-list-create'), | |||||
path('google-auth/', include('google_auth.urls')), | |||||
] | |||||