Closed fxbrit closed 2 years ago
I would do this:
Service to keep statistics about transits.
Turnstiles can work without any internet connection. When a ticket is scanned, its validity is checked (locally). If it's valid then a new transit message will be sent with Kafka to TransitService, which will update its stats.
The entity exchanged will have fields like {ticketID, userID, turnstileID, time}
We can create one example endpoint like transits per turnstile.
Kafka messages
I would do this
sounds good
New table: turnstiles [id, name, public_key] Each turnstile has a pair of asymmetric keys, the public key is registered manually in the table turnstiles New endpoints: GET /turnstile/login -> generates a random number and sends it to the turnstile, saved provisionally in a table like validate POST /turnstile/login -> sends the number encrypted with its private key, if ok then it's authenticated
Actually, let's make it simpler. Turnstiles login is not the focus of our application. Let's use the standard username/password that we know how to use.
we could recycle some code from the admin enrollment, allowing only administrators to add new turnstiles with a username (id), psw and maybe even a key that we could use for symmetric encryption of the secret (just to keep it as simple as possible, although not great for security).
Yes, exactly, I'm currently doing that then I'm off to holidays 😜
So, to recap what has been done and what is missing.
Done:
User {
username,
password,
email = null,
role = TURNSTILE,
enabled = 1
}
In this way, turnstiles can login normally with the same endpoint as users. Want to move everything to a new microservice? We can discuss it, it probably is a better solution. EDIT: See next comment.
═════════════════════════════════════════
Still to be done 🥺:
Want to move everything to a new microservice? We can discuss it, it probably is a better solution.
Yeah, I see that you were proposing this solution, so let's do it.
Since the turnstile generates data for TransitService, it requires:
I agree with your above comment, this seems like the best solution. although it's worth noting that this probably requires to start from scratch with #23 as most of the changes in there are treating turnstiles as users.
Yeah probably. I'm currently working on TurnstileService and it should be ready in a few hours. Then I'll do the remaining endpoints for the other services. I'll let you do Kafka however because you have much more experience 😝
In general, everything should be finished by tomorrow evening. Then we can add tests as you said and that's it.
I'll let you do Kafka however because you have much more experience 😝 In general, everything should be finished by tomorrow evening.
k, I'll work on the kafka part tomorrow morning then 🎉
GET /turnstile/key -> gets the key used to validate the JWS, required role TURNSTILE
Ok so this is wrong because the key is not in the LoginService. But apart from that there is a choice to be made.
The JWT signing key is currently in TravelerService, which receives ticket orders and saves all the complete tickets in its own database. TravelerService uses the signing key to return tickets via GET my/tickets/{ticketID} (QR or string). This key is also necessary for TurnstileService in order to check if the transit is valid (and the ticket is not fake).
Since the project file says:
These devices will interact with the overall system authenticating themselves as embedded systems, in order to get the secret used to check the validity of the JWS and provide transit count information.
We need to provide to TurnstileService this key.
We can:
What do you think we should do? @fxbrit
Manually insert into TurnstileService the key (but then it cannot be changed, seems very bad)
you mean by declaring it in application.properties
? actually I don't hate this idea because:
just to be sure, the only interaction that should be implemented using Kafka is:
/generateTransit
TurnstileService
produces a Kafka message and adds an entry to TransitService
is there any other exchange happening that I missed?
is there any other exchange happening that I missed?
Nope, that is right. Kafka in TurnstileService
to send and Kafka in TransitService
to receive.
I also found out what is a JWS😝
a signed JWT (aka a 'JWS')
two tasks left to do, see OP.
I think there's a problem with the signature verification, I tried the following steps:
Login as admin
http -v POST :8081/user/login username=admin password=PassWord123!
Create a turnstile
http -A bearer -a <admin_token> -v POST :8086/register username=test123turn password=psW1111!
Buy a ticket
http -A bearer -a <admin_token> -v POST :8080/shop/1 amount=1 paymentInformations\[creditCardNumber\]=12345678 paymentInformations\[cvv\]=123 paymentInformations\[expirationDate\]='2023-11-11'
Get tickets to take JWS
http -A bearer -a <admin_token> GET :8082/my/tickets
Login as turnstile
http -v POST :8086/login username=test123turn password=psW1111!
Generate a transit
http -A bearer -a <turnstile_token> -v POST :8086/generateTransit jws=<jws>
I ended up with:
HTTP/1.1 400 Bad Request
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Content-Length: 84
Content-Type: application/json
Expires: 0
Pragma: no-cache
Referrer-Policy: no-referrer
X-Content-Type-Options: nosniff
X-Frame-Options: DENY
X-XSS-Protection: 1 ; mode=block
{
"errorMessage": "Error during ticket validation: Illegal base64url character: '\"'"
}
meanwhile when checking manually the ticket is valid and properly signed.
In the last request /generateTransit
accepts the JWS as plaintext, the jws=
part is what is wrong.
yup yup, thx. I have some local changes that accept a DTO instead of a String, I will push them soon.
https://github.com/fxbrit/ticketing-system/issues/10#issuecomment-1225784062 could be useful for #21
we will need a new service in order to: