Skip to content

Commit

Permalink
Merge pull request #240 from XuHugo/master
Browse files Browse the repository at this point in the history
Add login and register interfaces
  • Loading branch information
yeasy authored Apr 9, 2021
2 parents 567eb7c + 9c7f88d commit f5201d8
Show file tree
Hide file tree
Showing 11 changed files with 163 additions and 31 deletions.
19 changes: 18 additions & 1 deletion src/api-engine/api/auth.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@
from django.core.exceptions import ObjectDoesNotExist
from rest_framework import authentication
from rest_framework.permissions import BasePermission

from rest_framework.exceptions import AuthenticationFailed
from rest_framework_jwt.serializers import VerifyJSONWebTokenSerializer
from api.common.enums import UserRole
from api.models import UserProfile

Expand Down Expand Up @@ -33,6 +34,22 @@ def authenticate(self, request):
return None


class TokenAuth(authentication.BaseAuthentication):

def authenticate(self, request):
token = {"token": request.META.get('HTTP_AUTHORIZATION', None)}
valid_data = VerifyJSONWebTokenSerializer().validate(token)
user = valid_data['user']
organization = user.organization
#organization_id = user.organization.id
#organization_name = user.organization.name
#request.user.
if user:
return
else:
raise AuthenticationFailed('认证失败')


class IsAdminAuthenticated(BasePermission):
"""
Allows access only to authenticated users.
Expand Down
9 changes: 7 additions & 2 deletions src/api-engine/api/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ class UserProfile(AbstractUser):
max_length=64,
)
organization = models.ForeignKey(
Organization, null=True, on_delete=models.CASCADE
Organization, null=True, on_delete=models.CASCADE, related_name="users",
)

class Meta:
Expand Down Expand Up @@ -196,6 +196,11 @@ class Agent(models.Model):
help_text="Create time of agent", auto_now_add=True
)

free_port = models.IntegerField(
help_text="Agent free port.",
default=30000,
)

def delete(self, using=None, keep_parents=False):
if self.config_file:
if os.path.isfile(self.config_file.path):
Expand Down Expand Up @@ -491,7 +496,7 @@ class Node(models.Model):
Agent,
help_text="Agent of node",
null=True,
related_name="network",
related_name="agent",
on_delete=models.CASCADE
)
# network = models.ForeignKey(
Expand Down
25 changes: 13 additions & 12 deletions src/api-engine/api/routes/agent/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,24 +34,25 @@
AgentApplySerializer,
)
from api.utils.common import with_common_response, any_of
from api.auth import TokenAuth

LOG = logging.getLogger(__name__)


class AgentViewSet(viewsets.ViewSet):
"""Class represents agent related operations."""
authentication_classes = (JSONWebTokenAuthentication,)

def get_permissions(self):
if self.action in ["apply", "list", "release", "retrieve"]:
permission_classes = (
IsAuthenticated,
any_of(IsAdminAuthenticated, IsOperatorAuthenticated),
)
else:
permission_classes = (IsAuthenticated, IsOperatorAuthenticated)

return [permission() for permission in permission_classes]
authentication_classes = (JSONWebTokenAuthentication, TokenAuth)

# def get_permissions(self):
# if self.action in ["apply", "list", "release", "retrieve"]:
# permission_classes = (
# IsAuthenticated,
# any_of(IsAdminAuthenticated, IsOperatorAuthenticated),
# )
# else:
# permission_classes = (IsAuthenticated, IsOperatorAuthenticated)
#
# return [permission() for permission in permission_classes]

@swagger_auto_schema(
query_serializer=AgentQuery,
Expand Down
Empty file.
21 changes: 21 additions & 0 deletions src/api-engine/api/routes/general/serializers.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
#
# SPDX-License-Identifier: Apache-2.0
#
from rest_framework import serializers
from api.models import UserProfile


class RegisterBody(serializers.ModelSerializer):
organization = serializers.CharField(help_text="name of Organization")
username = serializers.CharField(help_text="name of Administrator", default="Administator")
password = serializers.CharField(help_text="password of Administrator", default="666666")

class Meta:
model = UserProfile
fields = ("organization", "username", "password")
extra_kwargs = {"organization": {"required": True}}


class RegisterIDSerializer(serializers.Serializer):
id = serializers.UUIDField(help_text="ID of Organization")

80 changes: 80 additions & 0 deletions src/api-engine/api/routes/general/views.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
#
# SPDX-License-Identifier: Apache-2.0
#
import logging
import base64

from rest_framework import viewsets, status
from django.core.exceptions import ObjectDoesNotExist
from rest_framework.response import Response
from api.models import UserProfile, Organization
from api.exceptions import ResourceExists, ResourceNotFound, ResourceInUse
from api.routes.general.serializers import (
RegisterBody,
RegisterIDSerializer,
)
from api.lib.pki import CryptoGen, CryptoConfig
from api.utils import zip_dir, zip_file
from api.config import CELLO_HOME


class RegisterViewSet(viewsets.ViewSet):

def create(self, request):
serializer = RegisterBody(data=request.data)
if serializer.is_valid(raise_exception=True):
username = serializer.validated_data.get("username")
organization = serializer.validated_data.get("organization")
password = serializer.validated_data.get("password")
try:
Organization.objects.get(name=organization)
except ObjectDoesNotExist:
pass
else:
raise ResourceExists

CryptoConfig(organization).create()
CryptoGen(organization).generate()

msp, tls = self._conversion_msp_tls(organization)

organization = Organization(name=organization, msp=msp, tls=tls)
organization.save()

user = UserProfile(
username=username,
role="Admin",
organization=organization,
)
user.set_password(password)
user.save()

response = RegisterIDSerializer(data=organization.__dict__)
if response.is_valid(raise_exception=True):
return Response(
response.validated_data, status=status.HTTP_201_CREATED
)

def _conversion_msp_tls(self, name):
"""
msp and tls from zip file to byte
:param name: organization name
:return: msp, tls
:rtype: bytes
"""
try:
dir_org = "{}/{}/crypto-config/peerOrganizations/{}/" \
.format(CELLO_HOME, name, name)

zip_dir("{}msp".format(dir_org), "{}msp.zip".format(dir_org))
with open("{}msp.zip".format(dir_org), "rb") as f_msp:
msp = base64.b64encode(f_msp.read())

zip_dir("{}tlsca".format(dir_org), "{}tls.zip".format(dir_org))
with open("{}tls.zip".format(dir_org), "rb") as f_tls:
tls = base64.b64encode(f_tls.read())
except Exception as e:
raise e

return msp, tls
4 changes: 4 additions & 0 deletions src/api-engine/api/routes/network/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
from drf_yasg.utils import swagger_auto_schema
from django.core.paginator import Paginator
from django.core.exceptions import ObjectDoesNotExist
from rest_framework_jwt.authentication import JSONWebTokenAuthentication
from api.routes.network.serializers import (
NetworkQuery,
NetworkListResponse,
Expand All @@ -26,12 +27,15 @@
from api.models import Network, Node, Organization
from api.config import CELLO_HOME
from api.utils import zip_dir, zip_file
from api.auth import TokenAuth

LOG = logging.getLogger(__name__)


class NetworkViewSet(viewsets.ViewSet):

authentication_classes = (JSONWebTokenAuthentication, TokenAuth)

def _genesis2base64(self, network):
"""
convert genesis.block to Base64
Expand Down
4 changes: 2 additions & 2 deletions src/api-engine/api/routes/node/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@
)
from api.tasks import operate_node
from api.utils.common import with_common_response
from api.auth import CustomAuthenticate
from api.auth import CustomAuthenticate, TokenAuth
from api.lib.pki import CryptoGen, CryptoConfig
from api.utils import zip_dir, zip_file
from api.config import CELLO_HOME
Expand All @@ -64,7 +64,7 @@


class NodeViewSet(viewsets.ViewSet):
#authentication_classes = (CustomAuthenticate, JSONWebTokenAuthentication)
authentication_classes = (TokenAuth, JSONWebTokenAuthentication)

# Only operator can update node info
# def get_permissions(self):
Expand Down
3 changes: 2 additions & 1 deletion src/api-engine/api/routes/organization/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,14 +30,15 @@
from api.lib.pki import CryptoGen, CryptoConfig
from api.utils import zip_dir, zip_file
from api.config import CELLO_HOME
from api.auth import TokenAuth


LOG = logging.getLogger(__name__)


class OrganizationViewSet(viewsets.ViewSet):
"""Class represents orgnization related operations."""
#authentication_classes = (JSONWebTokenAuthentication,)
authentication_classes = (JSONWebTokenAuthentication, TokenAuth)
#permission_classes = (IsAuthenticated, IsOperatorAuthenticated)

@swagger_auto_schema(
Expand Down
25 changes: 13 additions & 12 deletions src/api-engine/api/routes/user/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,25 +24,26 @@
)
from api.utils.common import any_of
from api.utils.common import with_common_response
from api.auth import TokenAuth

LOG = logging.getLogger(__name__)

ADMIN_USERNAME = os.getenv("ADMIN_USERNAME")


class UserViewSet(viewsets.ViewSet):
authentication_classes = (JSONWebTokenAuthentication,)

def get_permissions(self):
permission_classes = []

if self.action not in ["auth"]:
permission_classes = (
IsAuthenticated,
any_of(IsAdminAuthenticated, IsOperatorAuthenticated),
)

return [permission() for permission in permission_classes]
authentication_classes = (JSONWebTokenAuthentication, TokenAuth)

# def get_permissions(self):
# permission_classes = []
#
# if self.action not in ["auth"]:
# permission_classes = (
# IsAuthenticated,
# any_of(IsAdminAuthenticated, IsOperatorAuthenticated),
# )
#
# return [permission() for permission in permission_classes]

@swagger_auto_schema(
query_serializer=UserQuerySerializer,
Expand Down
4 changes: 3 additions & 1 deletion src/api-engine/api_engine/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
from api.routes.organization.views import OrganizationViewSet
from api.routes.user.views import UserViewSet
from api.routes.file.views import FileViewSet
from api.routes.general.views import RegisterViewSet

DEBUG = getattr(settings, "DEBUG")
API_VERSION = os.getenv("API_VERSION")
Expand Down Expand Up @@ -63,11 +64,12 @@
router.register("users", UserViewSet, basename="user")
router.register("files", FileViewSet, basename="file")
# router.register("clusters", ClusterViewSet, basename="cluster")
router.register("register", RegisterViewSet, basename="register"),

urlpatterns = router.urls

urlpatterns += [
path("auth", obtain_jwt_token),
path("login", obtain_jwt_token),
path("token-verify", verify_jwt_token),
path("docs/", SchemaView.with_ui("swagger", cache_timeout=0), name="docs"),
path("redoc/", SchemaView.with_ui("redoc", cache_timeout=0), name="redoc"),
Expand Down

0 comments on commit f5201d8

Please sign in to comment.