Skip to content

Commit

Permalink
first commit
Browse files Browse the repository at this point in the history
  • Loading branch information
sankalp_j committed Mar 20, 2019
0 parents commit abf939d
Show file tree
Hide file tree
Showing 15 changed files with 467 additions and 0 deletions.
3 changes: 3 additions & 0 deletions .gitignore
@@ -0,0 +1,3 @@
.env
*.pyc
venv/*
Empty file added __init__.py
Empty file.
22 changes: 22 additions & 0 deletions manage.py
@@ -0,0 +1,22 @@
#!/usr/bin/env python
import os
import sys

if __name__ == "__main__":
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "settings")
try:
from django.core.management import execute_from_command_line
except ImportError:
# The above import may fail for some other reason. Ensure that the
# issue is really that Django is missing to avoid masking other
# exceptions on Python 2.
try:
import django
except ImportError:
raise ImportError(
"Couldn't import Django. Are you sure it's installed and "
"available on your PYTHONPATH environment variable? Did you "
"forget to activate a virtual environment?"
)
raise
execute_from_command_line(sys.argv)
8 changes: 8 additions & 0 deletions requirements.txt
@@ -0,0 +1,8 @@
Django==1.11.13
djangorestframework==3.8.2
django-mysql==2.4.0
uwsgi==2.0.15
django-filter==1.0.4
django-suit==0.2.25
mysqlclient==1.3.13
django-cors-headers==2.4.0
Empty file added saas/__init__.py
Empty file.
10 changes: 10 additions & 0 deletions saas/admin.py
@@ -0,0 +1,10 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals

from django.contrib import admin
from .models import *

admin.site.register(Business)
admin.site.register(Plan)
admin.site.register(Subscription)
admin.site.register(BusinessTeamMember)
67 changes: 67 additions & 0 deletions saas/migrations/0001_initial.py
@@ -0,0 +1,67 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.13 on 2019-03-20 09:16
from __future__ import unicode_literals

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),
]

operations = [
migrations.CreateModel(
name='Business',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('name', models.CharField(max_length=255)),
('created_at', models.DateTimeField(auto_now_add=True)),
('last_updated_on', models.DateTimeField(auto_now=True)),
('is_active', models.BooleanField(default=True)),
('api_key', models.CharField(max_length=50, null=True)),
],
),
migrations.CreateModel(
name='BusinessTeamMember',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('activation_key', models.CharField(max_length=36)),
('created_at', models.DateTimeField(auto_now_add=True)),
('last_updated_on', models.DateTimeField(auto_now=True)),
('business', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='saas.Business')),
('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
],
),
migrations.CreateModel(
name='Plan',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('name', models.CharField(max_length=255)),
('description', models.CharField(blank=True, max_length=255, null=True)),
('usd_price', models.DecimalField(decimal_places=2, max_digits=6)),
('created_at', models.DateTimeField(auto_now_add=True)),
('last_updated_on', models.DateTimeField(auto_now=True)),
],
),
migrations.CreateModel(
name='Subscription',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('is_active', models.BooleanField(default=False)),
('created_at', models.DateTimeField(auto_now_add=True)),
('last_updated_on', models.DateTimeField(auto_now=True)),
('business', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='saas.Business')),
('plan', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='saas.Plan')),
],
),
migrations.AlterUniqueTogether(
name='businessteammember',
unique_together=set([('business', 'user')]),
),
]
Empty file added saas/migrations/__init__.py
Empty file.
51 changes: 51 additions & 0 deletions saas/models.py
@@ -0,0 +1,51 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals

from django.db import models
from django.contrib.auth.models import User

# below models can be extended according to the specific saas uses cases. This is boiler plate only

class Plan(models.Model):
name = models.CharField(max_length=255)
description = models.CharField(max_length=255, null=True, blank=True)
usd_price = models.DecimalField(max_digits=6, decimal_places=2)
created_at = models.DateTimeField(auto_now_add=True)
last_updated_on = models.DateTimeField(auto_now=True)

def __unicode__(self):
return self.name

class Business(models.Model):
name = models.CharField(max_length=255)
created_at = models.DateTimeField(auto_now_add=True)
last_updated_on = models.DateTimeField(auto_now=True)
is_active = models.BooleanField(default=True)
api_key = models.CharField(max_length=50, null=True)

def __unicode__(self):
return "{}_{}".format(self.id, self.name)


class Subscription(models.Model):
business = models.ForeignKey(Business)
plan = models.ForeignKey(Plan)
is_active = models.BooleanField(default=False)
created_at = models.DateTimeField(auto_now_add=True)
last_updated_on = models.DateTimeField(auto_now=True)

def __unicode__(self):
return self.business.__unicode__() + "_" + str(self.id)

class BusinessTeamMember(models.Model):
business = models.ForeignKey(Business)
user = models.ForeignKey(User)
activation_key = models.CharField(max_length=36)
created_at = models.DateTimeField(auto_now_add=True)
last_updated_on = models.DateTimeField(auto_now=True)

class Meta:
unique_together = ('business', 'user',)

def __unicode__(self):
return "{}_{}".format(self.business.id, self.user.username)
Empty file added saas/permissions.py
Empty file.
Empty file added saas/serializers.py
Empty file.
23 changes: 23 additions & 0 deletions saas/urls.py
@@ -0,0 +1,23 @@
"""saas URL Configuration
The `urlpatterns` list routes URLs to views. For more information please see:
https://docs.djangoproject.com/en/1.11/topics/http/urls/
Examples:
Function views
1. Add an import: from my_app import views
2. Add a URL to urlpatterns: url(r'^$', views.home, name='home')
Class-based views
1. Add an import: from other_app.views import Home
2. Add a URL to urlpatterns: url(r'^$', Home.as_view(), name='home')
Including another URLconf
1. Import the include() function: from django.conf.urls import url, include
2. Add a URL to urlpatterns: url(r'^blog/', include('blog.urls'))
"""
from django.conf.urls import url
from django.contrib import admin
from django.conf.urls import url, include

urlpatterns = [
url(r'^', include('django.contrib.auth.urls')),
url(r'^admin/', admin.site.urls),
]
100 changes: 100 additions & 0 deletions saas/views.py
@@ -0,0 +1,100 @@
from rest_framework.views import APIView
from rest_framework.generics import CreateAPIView
from .serializers import LoginSerializer, BusinessTeamMemberSerializer, ResetPasswordSerializer \
SignupSerializer, ResetPasswordSerializer, ResetPasswordConfirmationSerializer \
InviteTeamMemberSerialiser
from .permissions import IsBusiness

class BusinessAPIView(APIView):
"""
This view must by inherited by any view that should be accessed only
if the user making the request is part of a business that is registered
"""

def initial(self, request, *args, **kwargs):
ret = super(BusinessAPIView, self).initial(request, *args, **kwargs)
if not request.user.is_anonymous():
try:
team_member = BusinessTeamMember.objects.get(user=request.user)
request.business = team_member.business
except BusinessTeamMember.DoesNotExist:
raise MemberDoesNotExist()
return ret


class SubscriptionAPIView(BusinessAPIView):
"""
This view must be inherited by any view that should be accessed only if
there is an active subscription present for a business to which
the user that is making the api call belongs to
"""
def initial(self, request, *args, **kwargs):
ret = super(SubscriptionAPIView, self).initial(request, *args, **kwargs)
try:
subscription = Subscription.objects.get(business=request.business, is_active=True)
request.subscription = subscription
except Subscription.DoesNotExist:
raise NoActiveSubscriptionFound()
return ret


class LoginView(CreateAPIView):
serializer_class = LoginSerializer
parser_classes = (parsers.FormParser, parsers.MultiPartParser, parsers.JSONParser,)


class PrefillSignupView(RetrieveAPIView):
"""
If signup form is accessed via an activation link, form will be prefilled with some information.
To retrieve that information, use this API with the activation key
"""
serializer_class = BusinessTeamMemberSerializer

def get_object(self):
key = self.request.query_params.get('key', None)
try:
return BusinessTeamMember.objects.get(activation_key=key)
except BusinessTeamMember.DoesNotExist:
raise serializers.ValidationError('Activation key not found')

class SignupView(generics.CreateAPIView):
serializer_class = SignupSerializer
parser_classes = (parsers.FormParser, parsers.MultiPartParser, parsers.JSONParser,)


class ResetPasswordView(generics.CreateAPIView):
"""
Sending email to a team member with an activation key that will be used to reset password
"""

serializer_class = ResetPasswordSerializer
parser_classes = (parsers.FormParser, parsers.MultiPartParser, parsers.JSONParser,)


class ResetPasswordConfirmationView(generics.CreateAPIView):
"""
Using the activation key sent in the mail, password will be reset using new password
"""

serializer_class = ResetPasswordConfirmationSerializer
parser_classes = (parsers.FormParser, parsers.MultiPartParser, parsers.JSONParser,)

class MeView(generics.RetrieveAPIView, BusinessAPIView):
"""
Returns information about the user to which this auth token belongs to and the corresponding business.
Can be used in settings
"""

serializer_class = BusinessTeamMemberSerializer
permission_classes = [IsBusiness]

def get_object(self):
return BusinessTeamMember.objects.get(user=self.request.user, business=self.request.business)

class InviteTeamMemberView(generics.CreateAPIView, SubscriptionAPIView):
"""
Sending invitation to a team member to join SessionFox
"""

permission_classes = [IsBusiness]
serializer_class = InviteTeamMemberSerialiser

0 comments on commit abf939d

Please sign in to comment.