Skip to content

Commit

Permalink
Release: 1.1.0
Browse files Browse the repository at this point in the history
  • Loading branch information
Sese-Schneider committed Jul 31, 2023
1 parent 327673c commit 6766cec
Show file tree
Hide file tree
Showing 5 changed files with 42 additions and 39 deletions.
15 changes: 15 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,18 @@
## 1.1.0 (2023-07-31)

### Bug Fixes

* Fix authentication after a [breaking change](https://developer.personio.de/changelog/authentication-api-improved-bearer-token) in the Personio API.

### Documentation

* Add HACS Default badges

### Chore

* Add `pt-PT` translation. (@ViPeR5000 - #5)
* Migrate to [POST body `client_secret` and `client_id`](https://developer.personio.de/changelog/auth-api-moved-client_secret-and-client_id-to-post-body) in the Personio API.

## 1.0.2 (2023-03-02)

### Bug Fixes
Expand Down
4 changes: 2 additions & 2 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
MIT License

Copyright (c) 2019 Custom cards for Home Assistant
Copyright (c) 2023 Sebastian Schneider

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
Expand All @@ -18,4 +18,4 @@ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
SOFTWARE.
16 changes: 9 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
A Home Assistant integration with the Personio API.


[![hacs_badge](https://img.shields.io/badge/HACS-Custom-41BDF5.svg?style=for-the-badge)](https://github.com/hacs/integration)
[![hacs_badge](https://img.shields.io/badge/HACS-Default-41BDF5.svg?style=for-the-badge)](https://my.home-assistant.io/redirect/hacs_repository/?owner=Sese-Schneider&repository=ha-personio&category=integration)
[![GitHub Release][releases-shield]][releases]
![GitHub Downloads][downloads-shield]

Expand All @@ -21,14 +21,16 @@ A Home Assistant integration with the Personio API.

### HACS

*This repo can be installed as a custom repository in HACS.*
*This repo is available for install through the HACS.*

* Go to HACS → Integration
* Click on the three-dot-menu → Custom repositories
* Add `Sese-Schneider/ha-personio` as Integration.
* Go to HACS → Integrations
* Use the FAB "Explore and download repositories" to search "Personio".
* Restart Home Assistant
* Install "Personio" as an integration in your settings.

_or_

Click here:

[![](https://my.home-assistant.io/badges/hacs_repository.svg)](https://my.home-assistant.io/redirect/hacs_repository/?owner=Sese-Schneider&repository=ha-personio&category=integration)


## Setup
Expand Down
42 changes: 14 additions & 28 deletions custom_components/personio/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
import logging
import time

import jwt
import requests
from requests import Response

Expand All @@ -19,46 +18,40 @@ class Authentication:

_current_config: dict = None
_current_token: str = None
_current_token_time: float = None

def set_config(self, config: dict):
"""Set the current API configuration."""
self._current_config = config["data"]

# self test current auth config, fetch initial token for usage
self.get_bearer(invalidate=False)
self.get_bearer()

def get_bearer(self, invalidate: bool = True):
def get_bearer(self):
"""Get a currently valid authentication bearer."""

if not self._current_config:
raise HomeAssistantError("Config not defined.")

if self._current_token:
jwt_token = jwt.decode(
self._current_token,
algorithms=["HS256"],
options={"verify_signature": False},
)
if jwt_token["exp"] > time.time():
_LOGGER.debug("Reusing existing JWT token")
# Bearers are valid for 24 hours
if self._current_token_time + (24 * 60 * 60) > time.time():
_LOGGER.debug("Using cached token")
bearer = "Bearer " + self._current_token
if invalidate:
# bearers are one-time use only
_LOGGER.debug("Invalidating JWT token")
self._current_token = None

return bearer

_LOGGER.debug("Requesting new JWT token")
_LOGGER.debug("Requesting new token")

self._current_token_time = time.time()
authentication = authenticate(
self._current_config["client_id"],
self._current_config["client_secret"],
self._current_config["partner_id"],
self._current_config["app_id"],
)

self._current_token = authentication.json()["data"]["token"]
return self.get_bearer(invalidate=invalidate)

return self.get_bearer()

def get_headers(self):
"""Returns all headers required for a successful Personio API request."""
Expand All @@ -73,12 +66,6 @@ def get_headers(self):
headers["X-Personio-App-ID"] = app_id
return headers

def set_response(self, response: Response):
"""Callback after receiving a new response.
Call this to set new authorization headers after each successful request."""
self._current_token = response.headers["authorization"].removeprefix("Bearer ")
_LOGGER.debug("New JWT token received")


class Employees:
"""Employees for the Persionio API."""
Expand All @@ -96,7 +83,6 @@ def get_employee_id_by_mail(self, employee_email: int) -> bool:
timeout=10000,
)
result.raise_for_status()
self._authentication.set_response(result)

return result.json()["data"][0]["attributes"]["id"]["value"]

Expand Down Expand Up @@ -145,9 +131,9 @@ def add_attendance(
json={"attendances": attendances},
)
result.raise_for_status()
self._authentication.set_response(result)

_LOGGER.info("Attendance for employee %s added successfully", employee_id)
_LOGGER.info(
"Attendance for employee %s added successfully", employee_id)


def authenticate(
Expand All @@ -165,7 +151,7 @@ def authenticate(

result = requests.post(
BASE_URL + "/auth",
params={"client_id": client_id, "client_secret": client_secret},
json={"client_id": client_id, "client_secret": client_secret},
headers=headers,
timeout=10000,
)
Expand Down
4 changes: 2 additions & 2 deletions custom_components/personio/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,6 @@
"integration_type": "hub",
"iot_class": "cloud_polling",
"issue_tracker": "https://github.com/Sese-Schneider/ha-personio/issues",
"requirements": ["pyjwt"],
"version": "1.0.2"
"requirements": [],
"version": "1.1.0"
}

0 comments on commit 6766cec

Please sign in to comment.