예제 #1
0
    def confirm_join(self, group_signature):
        """
        Sends a confirm join to the group server. This completes the joining
        process. It assumes that both the inviter and group signatures have
        already been verified. DO NOT CALL THIS METHOD WITH NON-VERIFIED
        SIGNATURES!

        :param group_signature: invite signed by the group server
        """
        request = self._make_request(
            request_type=msg.ConfirmJoin,
            signature_params={'group_server_signature': group_signature}
        )

        with connect(self.group_server_url) as connection:
            connection.request(request)

            try:
                # response can be ignored since it is only an acknowledgement
                connection.get_response(msg.ConfirmJoin)

            except ConflictError:
                raise UserExistsError("User is already confirmed")
            except ForbiddenError:
                raise PermissionDeniedError("User can not confirm join of "
                                            "another user")
            except UnauthorizedError:
                raise AuthenticationError("Signature verification failed")
예제 #2
0
    def invite(self, invitee_id: str, invitee_email: str):
        """
        Invites a new user to the group.

        :param invitee_id: invited user's ID.
        :param invitee_email: invited user's email.
        :raise ClientExistsError: if invitee is already registered
        """
        # parameters that are common to the request and user signature
        parameters = {
            'invitee': invitee_id,
            'invitee_email': invitee_email
        }

        request = self._make_request(
            request_type=msg.UserInvite,
            request_params=parameters,
            signature_params=parameters
        )

        with connect(self.group_server_url) as connection:
            connection.request(request)

            try:
                # response can be ignored since it is only an acknowledgement
                connection.get_response(msg.UserInvite)

            except ConflictError:
                raise UserExistsError("Invited client is already registered")
            except ForbiddenError:
                raise PermissionDeniedError("Inviter is not registered")
            except UnauthorizedError:
                raise AuthenticationError("Signature verification failed")
예제 #3
0
    def join(self, secret_code: str, inviter_id: str):
        """
        Tries to have the client join a group.

        :param secret_code: secret code provided by email.
        :param inviter_id: ID of the inviter.
        """
        # parameters that are common to the request and user signature
        parameters = {'secret_code': secret_code}

        request = self._make_request(
            request_type=msg.GroupServerJoin,
            request_params=parameters,
            signature_params=parameters
        )

        with connect(self.group_server_url) as connection:
            connection.request(request)

            try:
                response = connection.get_response(msg.GroupServerJoin)

            except ConflictError:
                raise UserExistsError("User is already registered")
            except ForbiddenError:
                raise PermissionDeniedError("Secret code was not accepted")
            except UnauthorizedError:
                raise AuthenticationError("Signature verification failed")

            try:
                msg.GroupServerJoin.verify(
                    key=inviter_id,
                    signature_name='invite',
                    signature=response.inviter_signature,
                    group_uuid=self.GROUP_ID,
                    inviter=inviter_id,
                    user=self.id,
                    user_email=self.email,
                )

            except rsa.InvalidSignature:
                raise AuthenticationError("Inviter signature is invalid")

            try:
                msg.GroupServerJoin.verify(
                    key=self.group_server_pubkey,
                    signature_name='group',
                    signature=response.group_signature,
                    group_uuid=self.GROUP_ID,
                    inviter_signature=response.inviter_signature,
                )

            except rsa.InvalidSignature:
                raise AuthenticationError("Group server signature is invalid")

            return response.inviter_signature, response.group_signature
예제 #4
0
    def totals(self):
        request = self._make_request(request_type=msg.CheckTotals)

        with connect(self.proxy_server_url) as connection:
            connection.request(request)

            try:
                response = connection.get_response(msg.CheckTotals)

            except ForbiddenError:
                raise PermissionDeniedError("User can not check totals")
            except UnauthorizedError:
                raise AuthenticationError("Signature verification failed")

            return response.user_balance, response.suggested_transactions
예제 #5
0
    def pending_UOMes(self):
        request = self._make_request(request_type=msg.GetPendingUOMes)

        with connect(self.proxy_server_url) as connection:
            connection.request(request)

            try:
                response = connection.get_response(msg.GetPendingUOMes)

            except UnauthorizedError:
                raise AuthenticationError("Signature verification failed")

            issued_by_user = list(map(uome.from_list, response.issued_by_user))
            waiting_for_user = list(map(uome.from_list, response.waiting_for_user))

            return issued_by_user, waiting_for_user
예제 #6
0
    def confirm_UOMe(self, uome_uuid, borrower, value, description):

        request = self._make_request(
            request_type=msg.ConfirmUOMe,
            request_params={'uome_uuid': uome_uuid},
            signature_params={
                'uome_uuid': uome_uuid,
                'borrower': borrower,
                'value': value,
                'description': description,
            }
        )

        with connect(self.proxy_server_url) as connection:
            connection.request(request)

            # response can be ignored since it is only an acknowledgement
            connection.get_response(msg.ConfirmUOMe)
예제 #7
0
    def accept_UOMe(self, uome_uuid, loaner: str, value: int, description: str):
        # parameters that are common to the request and user signature

        request = self._make_request(
            request_type=msg.AcceptUOMe,
            request_params={'uome_uuid': uome_uuid},
            signature_params={
                'uome_uuid': uome_uuid,
                'issuer': loaner,
                'value': value,
                'description': description
            }
        )

        with connect(self.proxy_server_url) as connection:
            connection.request(request)

            try:
                response = connection.get_response(msg.AcceptUOMe)

            except NotFoundError:
                raise UOMeNotFoundError("There is not a UOMe with that ID")
            except ForbiddenError:
                raise PermissionDeniedError("User can not accept the UOMe")
            except UnauthorizedError:
                raise AuthenticationError("Signature verification failed")

            try:
                msg.AcceptUOMe.verify(
                    key=self.main_server_pubkey,
                    signature_name='main',
                    signature=response.main_signature,
                    group_uuid=self.GROUP_ID,
                    user=self.id,
                    uome_uuid=uome_uuid,
                )

                # TODO store signature
                # TODO store the UOMe-ID

            except rsa.InvalidSignature:
                raise AuthenticationError("Main server signature is invalid")
예제 #8
0
    def issue_UOMe(self, borrower: str, value: int, description: str):
        # parameters that are common to the request and user signature
        parameters = {
            'borrower': borrower,
            'value': value,
            'description': description
        }

        request = self._make_request(
            request_type=msg.IssueUOMe,
            request_params=parameters,
            signature_params=parameters
        )

        with connect(self.proxy_server_url) as connection:
            connection.request(request)

            try:
                response = connection.get_response(msg.IssueUOMe)

            except ForbiddenError:
                raise PermissionDeniedError("User can not issue UOMes")
            except UnauthorizedError:
                raise AuthenticationError("Signature verification failed")

            try:
                msg.IssueUOMe.verify(
                    key=self.main_server_pubkey,
                    signature_name='main',
                    signature=response.main_signature,
                    uome_uuid=response.uome_uuid,
                    group_uuid=self.GROUP_ID,
                    user=self.id,
                    borrower=borrower,
                    value=str(value),
                    description=description,
                )

            except rsa.InvalidSignature:
                raise AuthenticationError("Main server signature is invalid")

            return response.uome_uuid, response.main_signature
예제 #9
0
    def cancel_UOMe(self, UOMe_number):
        # parameters that are common to the request and user signature
        parameters = {'uome_uuid': UOMe_number}

        request = self._make_request(
            request_type=msg.CancelUOMe,
            request_params=parameters,
            signature_params=parameters
        )

        with connect(self.proxy_server_url) as connection:
            connection.request(request)

            try:
                response = connection.get_response(msg.CancelUOMe)

            except NotFoundError:
                raise UOMeNotFoundError("There is not a UOMe with that ID")
            except ForbiddenError:
                raise PermissionDeniedError("User can not cancel the UOMe")
            except UnauthorizedError:
                raise AuthenticationError("Signature verification failed")

            try:
                msg.CancelUOMe.verify(
                    key=self.main_server_pubkey,
                    signature_name='main',
                    signature=response.main_signature,
                    group_uuid=self.GROUP_ID,
                    user=self.id,
                    uome_uuid=UOMe_number,
                )

                # TODO store signature
                # TODO store the UOMe-ID

            except rsa.InvalidSignature:
                raise AuthenticationError("Main server signature is invalid")
예제 #10
0
def confirm_join(request):

    message_class = msg.ConfirmJoin

    try:  # convert the message into the request object
        request = message_class.load_request(request.POST['data'])
    except DecodeError:
        return HttpResponseBadRequest()

    try:
        user = User.objects.get(key=request.user, group_id=request.group_uuid)
        group = Group.objects.get(pk=request.group_uuid)
    except (ValueError,
            ObjectDoesNotExist):  # ValueError if the uuid is not valid
        return HttpResponseBadRequest()

    try:
        invitation = Invitation.objects.get(invitee=user, group=group)
        message_class.verify(user.key,
                             'user',
                             request.user_signature,
                             group_uuid=str(group.uuid),
                             user=user.key,
                             group_server_signature=invitation.signature_group)
    except InvalidSignature:
        return HttpResponse('401 Unauthorized', status=401)

    if user.confirmed:
        return HttpResponse('409 Conflict', status=409)

    #Confirm to main server successfull registration of user
    main_server_url = 'localhost:8000'  #TODO: change to real address

    group_signature = msg.MainServerJoin.sign(settings.PRIVATE_KEY,
                                              'group',
                                              group_uuid=str(group.uuid),
                                              user=user.key)

    with connect(main_server_url) as connection:
        request_main = msg.MainServerJoin.make_request(
            group_uuid=str(group.uuid),
            user=user.key,
            group_signature=group_signature)
        connection.request(request_main)

        try:
            response = connection.get_response(msg.MainServerJoin)

        except DecodeError:
            raise SecurityException('Response format not correct')

        try:
            msg.MainServerJoin.verify(settings.MAIN_PUBLIC_KEY,
                                      'main',
                                      response.main_signature,
                                      group_uuid=str(group.uuid),
                                      user=user.key)
        except InvalidSignature:
            raise SecurityException('Signature of the response is invalid')

    #Save user_signature
    invitation.signature_invitee = request.user_signature
    invitation.save()

    #Change user status to confirmed
    user.confirmed = True
    user.save()

    response = message_class.make_response(group_uuid=str(group.uuid),
                                           user=user.key)

    return HttpResponse(response.dumps(), status=200)