Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Graceful door #62

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,13 +43,26 @@ The intent is to have a documented process that depends only on the Raspberry
Pi hardware and thus can be easily tested or trialed. That being said, there
are several ways to speed up or otherwise improve on this in the future.

### The manual way (before pi-gen building image)
1. Start with a fresh raspian lite bullseye install image, with ssh enabled
1. Dont forget to change the passwords and set up any extra users on the pi
1. `sudo apt-get update && sudo apt-get -y upgrade`
1. `sudo apt install -y -f hackman_0.1.0-1_armhf.deb`
1. reboot to activate all changes
3. Never run anything manually again \o/

### The (more) Continuous Integration way
1. GitHub Actions should build a new .zip RaspberryPi Image on every new commit on master branch.
1. dump database: `pg_dump -Ft postgresql://hackman:hackman@localhost/hackman > /tmp/hackman_dump_<date>.tar`
1. dump `~/.ssh/authorized_keys`
1. create new database, user, and grant privileges:
* `sudo -u postgres psql`
* `create database hackman;`
* `create user hackman with encrypted password ‘hackman’;`
* `grant all privileges on database hackman to hackman;`
1. load database: `pg_restore -v -d postgresql://hackman:hackman@localhost/hackman /tmp/hackman_dump_<date>.tar`
1. load `~/.ssh/authorized_keys`

## Upgrades
1. This auto-updates from the latest Github release automatically.
1. If that were to fail you can manually install the updated deb.
Expand Down
2 changes: 2 additions & 0 deletions hackman/templates/payment_submit.jinja2
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@
<p> It may take a couple of days for someone to manually collect your
envelope and update the master database.

<p> You may open the door within the next 1 minute.

<hr>
<p>
&nbsp;&nbsp;<a href="{% url 'index' %}">Back to space actions</a>
Expand Down
2 changes: 1 addition & 1 deletion hackman/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -249,7 +249,7 @@ def payment_submit(request: HttpRequest, r: bool = False) -> HttpResponse:
return http.HttpResponseBadRequest("Form error")

year, month = form.cleaned_data["year_month"]
payment_api.payment_submit(user_id, year, month)
payment_api.payment_claim(user_id, year, month)

notification_api.notify_subject(
b"door_event",
Expand Down
36 changes: 36 additions & 0 deletions hackman_payments/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,9 @@ def get_valid_until(user_id: int) -> Optional[date]:

def has_paid(user_id: int) -> PaymentGrade:

if is_within_grace_period(user_id):
return PaymentGrade.GRACE

r = get_redis_connection("default")
user_model = get_user_model()

Expand Down Expand Up @@ -70,6 +73,28 @@ def has_paid(user_id: int) -> PaymentGrade:
return PaymentGrade.NOT_PAID


def is_within_grace_period(user_id: int) -> bool:
r = get_redis_connection("default")
user_claim_grace_at = r.get(f"user_claim_grace_{user_id}")

if not user_claim_grace_at:
return False

user_claim_grace_at = user_claim_grace_at.decode("utf-8")
try:
claim_at = datetime.strptime(user_claim_grace_at, "%Y-%m-%dT%H:%M:%S.%fZ")
print(claim_at, datetime.utcnow())
if claim_at <= datetime.utcnow() and datetime.utcnow() <= claim_at + timedelta(
minutes=1
):
return True
else:
return False
except (TypeError, ValueError) as e:
print("warning: parse error for grace period for user", user_id, e)
return False


def unpaid_users() -> Generator[User, None, None]:
"""Yield all user ids that have not paid in advance"""

Expand Down Expand Up @@ -97,3 +122,14 @@ def payment_submit(
r.set("payment_user_id_{}".format(user_id), valid_until.isoformat())
# FIXME - we only know to month accuracy the payment details, so
# storing a full datetime is wrong


def payment_claim(
user_id: int, year: int, month: int, _redis_pipe: typing.Any = None
) -> None:
if year == datetime.now().year and month == datetime.now().month:
r = _redis_pipe or get_redis_connection("default")
r.set(f"user_claim_grace_{user_id}", f"{datetime.utcnow().isoformat()}Z")
else:
pass
# supposedly I should log someone's payment-claim.
Loading