Skip to content

Commit

Permalink
Merge changes into master. (#64)
Browse files Browse the repository at this point in the history
* Expose QR code helper explicitly.

This simplifies making use of it without having access to a client instance.

* Update README.rst - use pytest instead of py.test

pytest is the "new" name :)

* Version 1.0.1 - Docfix and QR method separate

---------

Co-authored-by: David Svenson <[email protected]>
Co-authored-by: Andreas Pelme <[email protected]>
  • Loading branch information
3 people authored Apr 12, 2024
1 parent 16039a3 commit 1d89b37
Show file tree
Hide file tree
Showing 6 changed files with 40 additions and 19 deletions.
6 changes: 5 additions & 1 deletion README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,9 @@ PyBankID can generate QR codes for you, and there is an example application in t
`examples folder of the repo <https://github.com/hbldh/pybankid/tree/master/examples>`_ where a
Flask application called ``qrdemo`` shows one way to do authentication with animated QR codes.

The QR code content generation is done with the ``generate_qr_code_content`` method on the BankID Client instances, or diectly
through the identically named method in ``bankid.qr`` module.

Certificates
------------

Expand Down Expand Up @@ -226,4 +229,5 @@ The PyBankID solution can be tested with `pytest <https://pytest.org/>`_:

.. code-block:: bash
py.test tests/
pytest tests/

2 changes: 2 additions & 0 deletions bankid/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,14 @@
from bankid.certutils import create_bankid_test_server_cert_and_key
from bankid.syncclient import BankIDClient
from bankid.asyncclient import BankIDAsyncClient
from bankid.qr import generate_qr_code_content

__all__ = [
"BankIDClient",
"BankIDAsyncClient",
"exceptions",
"create_bankid_test_server_cert_and_key",
"generate_qr_code_content",
"__version__",
"version",
]
20 changes: 3 additions & 17 deletions bankid/baseclient.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,9 @@
import base64
from datetime import datetime
import hashlib
import hmac
from math import floor
import time
from typing import Tuple, Optional, Dict, Any
from urllib.parse import urljoin

from bankid.qr import generate_qr_code_content
from bankid.certutils import resolve_cert_path


Expand Down Expand Up @@ -42,19 +39,8 @@ def __init__(
self.client = None

@staticmethod
def generate_qr_code_content(qr_start_token: str, start_t: [float, datetime], qr_start_secret: str):
"""Given QR start token, time.time() or UTC datetime when initiated authentication call was made and the
QR start secret, calculate the current QR code content to display.
"""
if isinstance(start_t, datetime):
start_t = start_t.timestamp()
elapsed_seconds_since_call = int(floor(time.time() - start_t))
qr_auth_code = hmac.new(
qr_start_secret.encode(),
msg=str(elapsed_seconds_since_call).encode(),
digestmod=hashlib.sha256,
).hexdigest()
return f"bankid.{qr_start_token}.{elapsed_seconds_since_call}.{qr_auth_code}"
def generate_qr_code_content(qr_start_token: str, start_t: [float, datetime], qr_start_secret: str) -> str:
return generate_qr_code_content(qr_start_token, start_t, qr_start_secret)

@staticmethod
def _encode_user_data(user_data):
Expand Down
20 changes: 20 additions & 0 deletions bankid/qr.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import hashlib
import hmac
import time
from datetime import datetime
from math import floor


def generate_qr_code_content(qr_start_token: str, start_t: [float, datetime], qr_start_secret: str) -> str:
"""Given QR start token, time.time() or UTC datetime when initiated authentication call was made and the
QR start secret, calculate the current QR code content to display.
"""
if isinstance(start_t, datetime):
start_t = start_t.timestamp()
elapsed_seconds_since_call = int(floor(time.time() - start_t))
qr_auth_code = hmac.new(
qr_start_secret.encode(),
msg=str(elapsed_seconds_since_call).encode(),
digestmod=hashlib.sha256,
).hexdigest()
return f"bankid.{qr_start_token}.{elapsed_seconds_since_call}.{qr_auth_code}"
8 changes: 7 additions & 1 deletion docs/api_reference.rst
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ API Reference
=============

Base Client
~~~~~~~~~~~~~~~~~~~~
~~~~~~~~~~~

.. automodule:: bankid.baseclient
:members:
Expand All @@ -22,6 +22,12 @@ Asynchronous Client
.. automodule:: bankid.asyncclient
:members:

QR Utils
~~~~~~~~

.. automodule:: bankid.qr
:members:

Exceptions
~~~~~~~~~~
.. automodule:: bankid.exceptions
Expand Down
3 changes: 3 additions & 0 deletions docs/examples.rst
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ PyBankID can generate QR codes for you. There is an demo application in the
`examples folder of the repo <https://github.com/hbldh/pybankid/tree/master/examples>`_ where a
Flask application called ``qrdemo`` shows one way to do authentication with animated QR codes.

The QR code content generation is done with the ``generate_qr_code_content`` method on the BankID Client instances, or diectly
through the identically named method in ``bankid.qr`` module.

Below follows the app's README file, for your convenience.

QR Authentication Example
Expand Down

0 comments on commit 1d89b37

Please sign in to comment.