Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Deprecate out-maintained auth dependency #495

Merged
merged 2 commits into from
Nov 12, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
67 changes: 0 additions & 67 deletions src/agent/k8s-rest-agent/src/api/auth.py
Original file line number Diff line number Diff line change
@@ -1,67 +0,0 @@
import base64
import json
import logging

from django.contrib.auth import get_user_model
from django.utils.translation import ugettext as _
from rest_framework import authentication
from rest_framework import exceptions
from rest_framework_jwt.authentication import (
JSONWebTokenAuthentication as CoreJSONWebTokenAuthentication,
)
from rest_framework_jwt.settings import api_settings

jwt_decode_handler = api_settings.JWT_DECODE_HANDLER
jwt_get_username_from_payload = api_settings.JWT_PAYLOAD_GET_USERNAME_HANDLER
User = get_user_model()

LOG = logging.getLogger(__name__)


class JSONWebTokenAuthentication(CoreJSONWebTokenAuthentication):
@staticmethod
def _get_or_create_user(user_id, payload=None):
if payload is None:
payload = {}

user, _ = User.objects.get_or_create(
id=user_id, username=user_id, defaults={"password": user_id}
)

return user

def authenticate_credentials(self, payload):
"""
Returns an active user that matches the payload's user id and email.
"""
username = jwt_get_username_from_payload(payload)

if not username:
msg = _("Invalid payload.")
raise exceptions.AuthenticationFailed(msg)

user = self._get_or_create_user(username, payload)

if not user.is_active:
msg = _("User account is disabled.")
raise exceptions.AuthenticationFailed(msg)

return user


class IstioJWTAuthentication(authentication.BaseAuthentication):
def authenticate(self, request):
token = request.META.get("HTTP_TOKEN", None)
if token is None:
return None

token += "=" * (-len(token) % 4)
token = base64.b64decode(token)
token = json.loads(token)
user_id = token.get("sub", None)
if user_id is None:
return None
user, _ = User.objects.get_or_create(
id=user_id, username=user_id, defaults={"password": user_id}
)
return user, None
5 changes: 1 addition & 4 deletions src/agent/k8s-rest-agent/src/api/routes/hello/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,16 @@

from rest_framework import viewsets, status
from drf_yasg.utils import swagger_auto_schema
from rest_framework.decorators import action, permission_classes
from rest_framework.permissions import IsAuthenticated
from rest_framework.decorators import action
from rest_framework.response import Response

from api.auth import JSONWebTokenAuthentication, IstioJWTAuthentication
from api.utils.mixins import PermissionsPerMethodMixin

LOG = logging.getLogger(__name__)
APP_VERSION = os.getenv("APP_VERSION", "v1")


class HelloViewSet(PermissionsPerMethodMixin, viewsets.ViewSet):
authentication_classes = (IstioJWTAuthentication,)

@swagger_auto_schema(
operation_summary="Hello world", operation_description="Hello world"
Expand Down
41 changes: 0 additions & 41 deletions src/api-engine/api/auth.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,6 @@
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 All @@ -19,45 +17,6 @@
ADMIN_NAME = os.getenv("ADMIN_USERNAME")


class CustomAuthenticate(authentication.BaseAuthentication):
def authenticate(self, request):
authorization = request.META.get("HTTP_AUTHORIZATION", None)
if not authorization or not authorization.startswith("JWT"):
return None
token = authorization.split(" ")[-1]
if token == SUPER_USER_TOKEN:
username = ADMIN_NAME
try:
user = UserProfile.objects.get(username=username)
except ObjectDoesNotExist:
return None

return user, None
else:
return None


class TokenAuth(authentication.BaseAuthentication):

def authenticate(self, request):
try:
token = request.META.get('HTTP_AUTHORIZATION', None).split()[1]
token = {"token": token}

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('认证失败')
except Exception:
raise AuthenticationFailed('认证失败')


class IsAdminAuthenticated(BasePermission):
"""
Allows access only to authenticated users.
Expand Down
21 changes: 3 additions & 18 deletions src/api-engine/api/routes/agent/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,9 @@
from drf_yasg.utils import swagger_auto_schema
from rest_framework import viewsets, status
from rest_framework.decorators import action
from rest_framework.exceptions import PermissionDenied
from rest_framework.permissions import IsAuthenticated
from rest_framework.response import Response
from rest_framework_jwt.authentication import JSONWebTokenAuthentication

from api.auth import IsOperatorAuthenticated, IsAdminAuthenticated
from api.common.enums import HostType
from api.exceptions import (
ResourceNotFound,
Expand All @@ -22,7 +19,7 @@
NoResource,
ResourceInUse,
)
from api.models import Agent, KubernetesConfig, Organization
from api.models import Agent, KubernetesConfig
from api.routes.agent.serializers import (
AgentQuery,
AgentListResponse,
Expand All @@ -33,27 +30,15 @@
AgentInfoSerializer,
AgentApplySerializer,
)
from api.utils.common import with_common_response, any_of
from api.auth import TokenAuth
from api.utils.common import with_common_response
from api.common import ok, err

LOG = logging.getLogger(__name__)


class AgentViewSet(viewsets.ViewSet):
"""Class represents agent related operations."""
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]
permission_classes = [IsAuthenticated, ]

@swagger_auto_schema(
query_serializer=AgentQuery,
Expand Down
39 changes: 24 additions & 15 deletions src/api-engine/api/routes/chaincode/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
from rest_framework import viewsets, status
from rest_framework.response import Response
from rest_framework.decorators import action
from rest_framework_jwt.authentication import JSONWebTokenAuthentication
from rest_framework.permissions import IsAuthenticated
import os
import zipfile

Expand All @@ -20,7 +20,6 @@

from api.lib.peer.chaincode import ChainCode as PeerChainCode
from api.common.serializers import PageQuerySerializer
from api.auth import TokenAuth
from api.utils.common import with_common_response
from api.exceptions import ResourceNotFound

Expand All @@ -36,7 +35,7 @@

class ChainCodeViewSet(viewsets.ViewSet):
"""Class represents Channel related operations."""
authentication_classes = (JSONWebTokenAuthentication, TokenAuth)
permission_classes = [IsAuthenticated, ]

@swagger_auto_schema(
query_serializer=PageQuerySerializer,
Expand Down Expand Up @@ -74,7 +73,8 @@ def list(self, request):
}
for chaincode in chaincodes_pages
]
response = ChaincodeListResponse({"data": chanincodes_list, "total": chaincodes.count()})
response = ChaincodeListResponse(
{"data": chanincodes_list, "total": chaincodes.count()})
return Response(data=ok(response.data), status=status.HTTP_200_OK)
except Exception as e:
return Response(
Expand Down Expand Up @@ -143,7 +143,8 @@ def package(self, request):
envs = init_env_vars(peer_node, org)

peer_channel_cli = PeerChainCode("v2.2.0", **envs)
res = peer_channel_cli.lifecycle_package(name, version, chaincode_path, language)
res = peer_channel_cli.lifecycle_package(
name, version, chaincode_path, language)
os.system("rm -rf {}/*".format(file_path))
os.system("mv {}.tar.gz {}".format(name, file_path))
if res != 0:
Expand All @@ -162,8 +163,8 @@ def package(self, request):
err(e.args), status=status.HTTP_400_BAD_REQUEST
)
return Response(
ok("success"), status=status.HTTP_200_OK
)
ok("success"), status=status.HTTP_200_OK
)

@swagger_auto_schema(
method="post",
Expand Down Expand Up @@ -218,7 +219,8 @@ def query_installed(self, request):

timeout = "5s"
peer_channel_cli = PeerChainCode("v2.2.0", **envs)
res, installed_chaincodes = peer_channel_cli.lifecycle_query_installed(timeout)
res, installed_chaincodes = peer_channel_cli.lifecycle_query_installed(
timeout)
if res != 0:
return Response(err("query installed chaincode failed."), status=status.HTTP_400_BAD_REQUEST)
except Exception as e:
Expand Down Expand Up @@ -272,7 +274,8 @@ def approve_for_my_org(self, request):
try:
channel_name = serializer.validated_data.get("channel_name")
chaincode_name = serializer.validated_data.get("chaincode_name")
chaincode_version = serializer.validated_data.get("chaincode_version")
chaincode_version = serializer.validated_data.get(
"chaincode_version")
policy = serializer.validated_data.get("policy")
# Perhaps the orderer's port is best stored in the database
orderer_url = serializer.validated_data.get("orderer_url")
Expand Down Expand Up @@ -330,7 +333,8 @@ def query_approved(self, request):
cc_name = request.data.get("chaincode_name")

peer_channel_cli = PeerChainCode("v2.2.0", **envs)
code, content = peer_channel_cli.lifecycle_query_approved(channel_name, cc_name)
code, content = peer_channel_cli.lifecycle_query_approved(
channel_name, cc_name)
if code != 0:
return Response(err("query_approved failed."), status=status.HTTP_400_BAD_REQUEST)

Expand All @@ -355,7 +359,8 @@ def check_commit_readiness(self, request):
try:
channel_name = serializer.validated_data.get("channel_name")
chaincode_name = serializer.validated_data.get("chaincode_name")
chaincode_version = serializer.validated_data.get("chaincode_version")
chaincode_version = serializer.validated_data.get(
"chaincode_version")
policy = serializer.validated_data.get("policy")
# Perhaps the orderer's port is best stored in the database
orderer_url = serializer.validated_data.get("orderer_url")
Expand Down Expand Up @@ -409,7 +414,8 @@ def commit(self, request):
try:
channel_name = serializer.validated_data.get("channel_name")
chaincode_name = serializer.validated_data.get("chaincode_name")
chaincode_version = serializer.validated_data.get("chaincode_version")
chaincode_version = serializer.validated_data.get(
"chaincode_version")
policy = serializer.validated_data.get("policy")
# Perhaps the orderer's port is best stored in the database
orderer_url = serializer.validated_data.get("orderer_url")
Expand Down Expand Up @@ -444,7 +450,8 @@ def commit(self, request):
print(peer_node.port)
# port = peer_node.port.all()[0].internal
# port = ports[0].internal
peer_address = peer_node.name + "." + org.name + ":" + str(7051)
peer_address = peer_node.name + \
"." + org.name + ":" + str(7051)
peer_address_list.append(peer_address)
peer_root_certs.append(peer_tls_cert)

Expand Down Expand Up @@ -481,7 +488,8 @@ def query_committed(self, request):
peer_node = qs.first()
envs = init_env_vars(peer_node, org)
peer_channel_cli = PeerChainCode("v2.2.0", **envs)
code, chaincodes_commited = peer_channel_cli.lifecycle_query_committed(channel_name, chaincode_name)
code, chaincodes_commited = peer_channel_cli.lifecycle_query_committed(
channel_name, chaincode_name)
if code != 0:
return Response(err("query committed failed."), status=status.HTTP_400_BAD_REQUEST)
except Exception as e:
Expand Down Expand Up @@ -509,7 +517,8 @@ def init_env_vars(node, org):

envs = {
"CORE_PEER_TLS_ENABLED": "true",
"CORE_PEER_LOCALMSPID": "{}MSP".format(org_name.capitalize()), # "Org1.cello.comMSP"
# "Org1.cello.comMSP"
"CORE_PEER_LOCALMSPID": "{}MSP".format(org_name.capitalize()),
"CORE_PEER_TLS_ROOTCERT_FILE": "{}/{}/peers/{}/tls/ca.crt".format(dir_node, org_name, node.name + "." + org_name),
"CORE_PEER_ADDRESS": "{}:{}".format(
node.name + "." + org_name, str(7051)),
Expand Down
5 changes: 2 additions & 3 deletions src/api-engine/api/routes/channel/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@
from rest_framework import viewsets, status
from rest_framework.decorators import action
from rest_framework.response import Response
from rest_framework_jwt.authentication import JSONWebTokenAuthentication
from rest_framework.parsers import MultiPartParser, FormParser, JSONParser
from rest_framework.permissions import IsAuthenticated
#

from drf_yasg.utils import swagger_auto_schema
Expand All @@ -20,7 +20,6 @@
from api.config import CELLO_HOME
from api.common.serializers import PageQuerySerializer
from api.utils.common import with_common_response, parse_block_file, to_dict
from api.auth import TokenAuth
from api.lib.configtxgen import ConfigTX, ConfigTxGen
from api.lib.peer.channel import Channel as PeerChannel
from api.lib.configtxlator.configtxlator import ConfigTxLator
Expand Down Expand Up @@ -61,7 +60,7 @@

class ChannelViewSet(viewsets.ViewSet):
"""Class represents Channel related operations."""
authentication_classes = (JSONWebTokenAuthentication, TokenAuth)
permission_classes = [IsAuthenticated, ]
parser_classes = [MultiPartParser, FormParser, JSONParser]

@ swagger_auto_schema(
Expand Down
2 changes: 0 additions & 2 deletions src/api-engine/api/routes/file/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
from rest_framework import viewsets, status
from rest_framework.permissions import IsAuthenticated
from rest_framework.response import Response
from rest_framework_jwt.authentication import JSONWebTokenAuthentication

from api.auth import IsOperatorAuthenticated, IsAdminAuthenticated
from api.exceptions import CustomError
Expand All @@ -25,7 +24,6 @@


class FileViewSet(viewsets.ViewSet):
authentication_classes = (JSONWebTokenAuthentication,)
permission_classes = (
IsAuthenticated,
any_of(IsAdminAuthenticated, IsOperatorAuthenticated),
Expand Down
11 changes: 8 additions & 3 deletions src/api-engine/api/routes/general/serializers.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#
# SPDX-License-Identifier: Apache-2.0
#

from api.routes.user.serializers import UserInfoSerializer
from rest_framework import serializers


Expand All @@ -23,6 +24,10 @@ class RegisterResponse(serializers.Serializer):


class LoginBody(serializers.Serializer):
orgName = serializers.CharField(help_text="name of Organization")
username = serializers.CharField(help_text="name of user")
email = serializers.CharField(help_text="email of user")
password = serializers.CharField(help_text="password of user")


class LoginSuccessBody(serializers.Serializer):
token = serializers.CharField(help_text="access token")
user = UserInfoSerializer()
Loading