コード例 #1
0
ファイル: otp.py プロジェクト: andrewkrug/oss2fa
    def enrollment_complete(self, enrollment, data):
        with transaction.atomic():
            assert enrollment.status == Enrollment.STATUS_IN_PROGRESS
            assert not enrollment.is_expired()

            # mark the enrollment as failed
            enrollment.status = Enrollment.STATUS_FAILED

            private_details, err = self.get_enrollment_private_details_model(
                enrollment.private_details)
            if err:
                logger.error(
                    'failed to retrieve private details for OTP enrollment `{0}`: {1}'
                    .format(enrollment.pk, err))
                return False, err

            # create the provisioning uri
            totp = pyotp.TOTP(s=private_details['secret'],
                              digits=private_details['digits'],
                              interval=private_details['interval'])

            ok = totp.verify(data['token'],
                             valid_window=self._configuration['valid_window'])
            if not ok:
                logger.error(
                    'failed to verify OTP `{0}` as valid for enrollment `{1}`'.
                    format(data['token'], enrollment.pk))
                return False, errors.MFASecurityError(
                    'token mismatch: `{0}` is not a valid OTP token for enrollment `{1}`'
                    .format(data['token'], enrollment.pk))

            # extract the device details
            details = OTPDeviceDetails(
                data={
                    'issuer_name': private_details['issuer_name'],
                    'digits': private_details['digits'],
                    'interval': private_details['interval'],
                    'secret': private_details['secret'],
                    'valid_window': private_details['valid_window'],
                    'algorithm': private_details['algorithm']
                })

            if not details.is_valid():
                logger.info(
                    'could not validate OTP device details: {0}'.format(
                        details.errors))

            # create the device
            device = Device()
            device.name = 'OTP [{0}]'.format(enrollment.username)
            device.kind = enrollment.device_selection.kind
            device.enrollment = enrollment

            # save the device details
            device.details = details.validated_data

            return device, None
コード例 #2
0
ファイル: email.py プロジェクト: andrewkrug/oss2fa
    def enrollment_complete(self, enrollment, data):
        assert enrollment.status == Enrollment.STATUS_IN_PROGRESS
        assert not enrollment.is_expired()

        # compare given token to privately stored token
        private_details = EmailDeviceEnrollmentPrivateDetails(
            data=enrollment.private_details)
        if not private_details.is_valid():
            return None, errors.MFAInconsistentStateError(
                'enrollment private details is invalid: {0}'.format(
                    private_details.errors))

        # if the token don't match, fail.
        if private_details.validated_data['token'] != data['token']:
            return None, errors.MFASecurityError(
                'token mismatch, expected `{0}` however received `{1}`'.format(
                    private_details.validated_data['token'], data['token']))

        # extract the device details
        details = EmailDeviceDetails(
            data={'address': private_details.validated_data['address']})

        assert details.is_valid()

        # create the device
        device = Device()

        device.name = u'Email [@{0}]'.format(
            EmailDeviceKindModule.mask_address(
                private_details.validated_data['address']))

        device.kind = enrollment.device_selection.kind
        device.enrollment = enrollment

        # save the device details
        device.details = details.validated_data

        return device, None