LoginSignup
9
10

More than 3 years have passed since last update.

Pythonistaで指紋認証

Last updated at Posted at 2019-10-25

概要

Pythonistaで指紋認証をしただけ

コード

touch_id.py

# coding: utf-8
from objc_util import *
import threading

NSBundle = ObjCClass('NSBundle')
LocalAuthentication = NSBundle.bundleWithPath_(
    '/System/Library/Frameworks/LocalAuthentication.framework')
LocalAuthentication.load()
LAContext = ObjCClass('LAContext')

class AuthFailedException(Exception):
    pass

class AuthCancelledException(AuthFailedException):
    pass

class AuthTimeoutException(AuthFailedException):
    pass

class AuthNotAvailableException(AuthFailedException):
    pass

class AuthFallbackMechanismSelectedException(AuthFailedException):
    pass


def is_available():
    context = LAContext.new().autorelease()
    return bool(context.canEvaluatePolicy_error_(1, None))


def authenticate(reason='', allow_passcode=True, timeout=None):
    if not is_available():
        raise AuthNotAvailableException('Touch ID is not available.')
    policy = 2 if allow_passcode else 1
    context = LAContext.new().autorelease()
    event = threading.Event()
    result = {}

    def callback(_cmd, success, _error):
        result['success'] = success
        if _error:
            error = ObjCInstance(_error)
            result['error'] = error
        event.set()

    handler = ObjCBlock(
        callback, restype=None, argtypes=[c_void_p, c_bool, c_void_p])
    context.evaluatePolicy_localizedReason_reply_(policy, reason, handler)
    if not event.wait(timeout):
        context.invalidate()
        raise AuthTimeoutException('Timeout')
    success = result.get('success', False)
    error = result.get('error')
    if success:
        return True
    elif error:
        error_code = error.code()
        if error_code == -2:
            raise AuthCancelledException('Cancelled by user')
        elif error_code == -3:
            raise AuthFallbackMechanismSelectedException(
                'Fallback authentication mechanism selected')
        else:
            desc = error.localizedDescription() or 'Unknown error'
            raise AuthFailedException(desc)
    else:
        raise AuthFailedException('Unknown error')


# 例
def main():
    try:
        reason = 'We need you fingerprint.'
        authenticate(reason,allow_passcode=True)
        print('Success!')
    except AuthFailedException as e:
        print(e)


if __name__ == '__main__':
    main()

感想

Pythonista強い!

9
10
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
9
10