9
10

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 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

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?