-
Notifications
You must be signed in to change notification settings - Fork 3
Code
The callback class handles the callbacks to the bunq api via Peter's pyhton wrapper. Because the wrapper is not aware of the endpoints I had to come up whit a solution which is this class.
https://github.com/OGKevin/ComBunqWebApp/blob/master/BunqAPI/callbacks.py
callback(f, user, password [userID,[accountID]])
parameter | explanation |
---|---|
f | Encrypted json file containing a key called secret
|
user | The currently logged in user |
password | The password used to encrypt the secret
|
userID | Specify an user id to get data from the bunq api |
accountID | Specify an account or card id to get data from the bunq api |
Registers a device to the API key. The ip address where this POST request came from will be bound to the API key as well.
https://doc.bunq.com/api/1/call/device-server/method/post
Starts a server-session with the bunq servers. In the respone there will be a session token. This session token is needed to make future API calls to the API. Therefore its getting stored in the database in the user profile.
From the docs:
A session expires after the same amount of time you have set for auto logout in your user account. If a request is made 30 seconds before a session expires, it will automatically be extended.
When the session expires the token will be unusable.
https://doc.bunq.com/api/1/call/session-server/method/post
Returns a list of all the users registered to this API key. If an userID
is given, data from that specific user returned.
https://doc.bunq.com/api/1/call/user
To make this request an userID
must be given.
Will return all accounts belonging to a specific user. If an accountID
is given, account details about that specific account is returned.
https://doc.bunq.com/api/1/call/monetary-account
To make this request an userID
and accountID
must be given.
Will return all the transactions belonging to the user's account.
https://doc.bunq.com/api/1/call/payment
To make this request an userID
must be given.
Will return all cards belonging to the user. If a card id is given, information about that specific card will be returned. Card id's can be given via accountID
.
https://doc.bunq.com/api/1/call/card
The Installation class handles the information that needs to be created for the encoded json file. It generates:
- GUID
- installation token
- RSA key pair
installation(username, password, API_KEY)
parameter | explanation |
---|---|
username | The username of the logged in user |
password | The password that is going to be used to encrypted the file, this passwords is needed to decrypt the file later. |
API_KEY | The bunq API key generated from the bunq app |
https://github.com/OGKevin/ComBunqWebApp/blob/master/BunqAPI/installation.py#L14
During the generating process the user inputs his/her API key and a password to encrypt the file. The file before encryption containts the following information:
- API key
- Server public key
- Installation token
- RSA private key
A decrypted file will look like this:
{"API": "API_KEY",
"ServerPublicKey": {"server_public_key": "-----BEGIN PUBLIC KEY-----\n
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsFG6Ih4xnmiJC2MA5ExI\n
B0vcUngrAMRR7d0t5cu9FlpHeVC7yA2C20jm744l2NGCXQfrrwiJbYL6FV21Z+p7\n
1kwEZTGMjuz6EFmavwu3BcXv73DKfmXg4JfDGh+QnvQRMI8dyE+jilJrXEo/nJXL\n
YujJqboC7DPkSDG00VpnL2JMHn/cjHvGRs2FUd2Kcr0RQjGJF0kF45zH0KVqgUB2\n
Mwf5G5QK4R6+uEvHJlJddIy8dfnPCL0MZh7S9crhtVLh7umjbUbI6JsBgonFpP0E\n
riEEjo+orsbjUuiesikr+WpDggxCSXXtDq1gsRWjlYbBbmd8AziLGKXejcKKIxQD\n
iwIDAQAB\n
-----END PUBLIC KEY-----\n"},
"Token": {"created": "2017-05-12 06:15:49.535008",
"id": 22378,
"token": "846ffffccccec8320ad827862bf868b9b1d845b74fbc729ab45fff8aacf1cc53",
"updated": "2017-05-12 06:15:49.535008"},
"privateKey": "-----BEGIN PRIVATE KEY-----\n"
"MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDLKQ7s/BQf7z/5\n"
"iOs3AwR4K55PTH+II1y5DWj3XFQbCycS/3/O2olhzyrZ6nimWyhnQNL/CtENW4+U\n"
"/sxi21bE1wlLo4eD5Jsg8CzetgQA6X9u+9sDPN/oAtsmHBXFq7kLQ/okihQlIC2F\n"
"4GSKzUFdti8U/8U74G3Bnej0QqNcm6xIuVOZ3Ncp9KCFRDBrZ5zQF4dIt7FAzgx2\n"
"xzKH+YEuVqEdS6r+/01WO2ESI9EPL3qO7THXEX2b0eJM7lbFLy54UUMCyBlHjY4n\n"
"WaKJ0GhkIn/Mq6U8kNamUolw0Q6uk6dZICULP/9+sMMBan1H19l6T5biu43Mrje2\n"
"xxYDD1/VAgMBAAECggEAUFmszY3lZ7v4UXkVjmxjGCQoOLTIu89AnO/w0+RwX0HJ\n"
"8nma0vUb4NNO32Ec1q63DB9XVAezJtVPtF4R+AdIChICWygSMNf5gs168ZqLetDe\n"
"1cZGmME6zUhT5H63HbcNOKdqB4mU7hoL5ycYnM0RTT8A4A1ItKXOwwTxXan9cmJq\n"
"yI4TXy8fH9Qqlv8056tC9wec8ITGEo4JI1tT/X1eoa9ByeNHbOXGKLdzbGeXKjK4\n"
"RYTlyWjahYGlrebQCAO9Ze2RZHWsXSd86BRjUnDwsjeOOB1QPiDT8cHOKs9yCqmi\n"
"eRLe7HXM2QLJtaQ/9a382y8QRUTNSnaYU0XWaL8vAQKBgQDyM6vurr/FJ3cU5L6I\n"
"1rC7ckWotHiX7h6sYASInNSsTvbZD845b1YQEbLncL8dSUlKZVI3jgnm9nxrP2AB\n"
"7mBIJ8KYJEznu7yrADuC3A5LgCUb4rBslJWTJm7Ieqmg3zdIeMHP2lFay89e7MAH\n"
"4mpHbjkl+Vyx4NWlaoJ0BADtcwKBgQDWu/82VARvaaXll0KI2zEWH8UHvkOd1VS2\n"
"Mtg9laObC3vgI+Ek6t52pUSQCCieGyKHeAN6dcOZWTQrXRO5gy0HZ4VFjiKIlv9n\n"
"vWLo70vhIEYTzHmO+5DkgE6URiNZ9QNuVgtKc7rgmhL72/SET3ucEfmRQ41zeWXR\n"
"aQv23psrlwKBgE6RzJilP7ipUMwKWHTzkGl+bHKJ+QTwTisFCvN2TNeI1jMcGX4w\n"
"S+7yjuLdhGHvwELOE5nKDhRKqZnw+SgnODywCURpojkagd3HOYb98/UyINem9iyD\n"
"FvKhaRbIE/cH8lskMVtIK1QVAbR9gN4N6QQ7EXbsKdHaafQ7VQ5lrhdZAoGBALFb\n"
"4bWLu4YSKrXxM0E6Wda+Mszsd4i7lRZP9I8ZM2JyH8THncQSQeCZLIISWwoLu39M\n"
"vwK8levo49AVNp95Gw4MkOUcOqW6ogWbRUDDtVaig38C2jwgyFITL9QEAlrgpg7R\n"
"/s1lvSqZ16gyykkmJSCJMCqtMv33fQNz0i/7OQrNAoGAcXQ//uYN8hyeg33zUWZe\n"
"QLIOMCqpnazjq4KQ55VwhYry27QcDc8rU5VK+b/0cEGehaxjjyQTv0acg8Z7uiEZ\n"
"xxdKaXRWc0jaYz/ORRMlxr0HipT7KAKdbDkSM6dVZWhxki+jK81CtZ8sR14J5qZ1\n"
"gaPqIPZsgn0aSAJDr048U3k=\n"
"-----END PRIVATE KEY-----\n"}
All this data will get encrypted, and gets transformed into a secret
. The encrypted file will look like this:
"secret": "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",
"userID": "e7f707bb-0bf9-4429-8a22-d91b08a74df2\r\n",
"username": "OGKevin"
}
Whit this setup the user is in full control of their API key. This also means that if an user wants to make API calls, the encrypted json file must be provided and decrypted successfully. Before any decryption attempts, the code will check if the userID
matches the one of the logged in user.
Uses UUID Generator to generate GUID(Globally Unique Identifier) each time a user generates a new file.
Gets the installation token and the server public key from bunq api. These are needed for the first few API calls.
Generates an RSA key pair that will be used for making API calls.
Collects all the data, except the GUID, from the above functions into one json, encrypts it and paste the encrypted string in a new json under secret
. The GUID generated will also be stored in the database under the users's profile.