First Code Commit
This commit is contained in:
+16
@@ -0,0 +1,16 @@
|
|||||||
|
# Lucas Mathews - Fontys Student ID: 5023572
|
||||||
|
# Banking System DockerFile
|
||||||
|
|
||||||
|
FROM python:3.12.3
|
||||||
|
|
||||||
|
LABEL maintainer="522499@student.fontys.nl"
|
||||||
|
|
||||||
|
WORKDIR /bank
|
||||||
|
|
||||||
|
COPY / /bank/
|
||||||
|
|
||||||
|
EXPOSE 81
|
||||||
|
|
||||||
|
RUN pip install --no-cache-dir --upgrade -r /bank/requirements.txt
|
||||||
|
|
||||||
|
ENTRYPOINT [ "python", "./api.py", "--host", "0.0.0.0", "--port", "81"]
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
import argparse
|
||||||
|
|
||||||
|
parser = argparse.ArgumentParser()
|
||||||
|
parser.add_argument('--x', type=int, required=True)
|
||||||
|
parser.add_argument('--y', type=int, required=True)
|
||||||
|
args = parser.parse_args()
|
||||||
|
product = args.x * args.y
|
||||||
|
print(f"{args.x} * {args.y} = {product}")
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
from flask import Flask, render_template, request
|
||||||
|
import requests
|
||||||
|
|
||||||
|
SERVER_URL = "http://127.0.0.1:8000"
|
||||||
|
|
||||||
|
app = Flask(__name__)
|
||||||
|
|
||||||
|
@app.route("/", methods=["GET"])
|
||||||
|
def loginGET():
|
||||||
|
return render_template("login.html")
|
||||||
|
|
||||||
|
@app.route("/", methods=["POST"])
|
||||||
|
def loginPOST():
|
||||||
|
username = request.form["username"]
|
||||||
|
password = request.form["password"]
|
||||||
|
response = requests.get( f"{SERVER_URL}/login?username={username}&password={password}")
|
||||||
|
return render_template("succes.html", data = response.content)
|
||||||
|
|
||||||
|
app.run()
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>Login</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<form method="post">
|
||||||
|
<label>Username:</label>
|
||||||
|
<input type="text" name="username">
|
||||||
|
<label>Password:</label>
|
||||||
|
<input type="password" name="password">
|
||||||
|
<input type="submit" value="Login">
|
||||||
|
</form>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>Document</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<p>{{data}}</p>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
+686
@@ -0,0 +1,686 @@
|
|||||||
|
openapi: 3.0.3
|
||||||
|
info:
|
||||||
|
title: Banking System - OpenAPI 3.0
|
||||||
|
description: |-
|
||||||
|
This is the banking system API for the programming project.
|
||||||
|
contact:
|
||||||
|
email: 522499@student.fontys.nl
|
||||||
|
version: 1.0.11
|
||||||
|
servers:
|
||||||
|
- url: /
|
||||||
|
tags:
|
||||||
|
- name: accounts
|
||||||
|
description: Everything about your Accounts
|
||||||
|
- name: user
|
||||||
|
description: Operations about user
|
||||||
|
paths:
|
||||||
|
/Accounts:
|
||||||
|
put:
|
||||||
|
tags:
|
||||||
|
- accounts
|
||||||
|
summary: Update an existing account
|
||||||
|
description: Update an existing account by Id
|
||||||
|
operationId: updateAccount
|
||||||
|
requestBody:
|
||||||
|
description: Update an existing bank account
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/Account'
|
||||||
|
application/xml:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/Account'
|
||||||
|
text/html:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/Account'
|
||||||
|
required: true
|
||||||
|
responses:
|
||||||
|
'200':
|
||||||
|
description: Successful operation
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/Account'
|
||||||
|
application/xml:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/Account'
|
||||||
|
'400':
|
||||||
|
description: Invalid ID supplied
|
||||||
|
'404':
|
||||||
|
description: Pet not found
|
||||||
|
'422':
|
||||||
|
description: Validation exception
|
||||||
|
security:
|
||||||
|
- petstore_auth:
|
||||||
|
- write:pets
|
||||||
|
- read:pets
|
||||||
|
post:
|
||||||
|
tags:
|
||||||
|
- accounts
|
||||||
|
summary: Add a new pet to the store
|
||||||
|
description: Add a new pet to the store
|
||||||
|
operationId: addPet
|
||||||
|
requestBody:
|
||||||
|
description: Create a new pet in the store
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/Account'
|
||||||
|
application/xml:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/Account'
|
||||||
|
application/x-www-form-urlencoded:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/Account'
|
||||||
|
required: true
|
||||||
|
responses:
|
||||||
|
'200':
|
||||||
|
description: Successful operation
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/Account'
|
||||||
|
application/xml:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/Account'
|
||||||
|
'400':
|
||||||
|
description: Invalid input
|
||||||
|
'422':
|
||||||
|
description: Validation exception
|
||||||
|
security:
|
||||||
|
- petstore_auth:
|
||||||
|
- write:pets
|
||||||
|
- read:pets
|
||||||
|
/pet/findByStatus:
|
||||||
|
get:
|
||||||
|
tags:
|
||||||
|
- accounts
|
||||||
|
summary: Finds Pets by status
|
||||||
|
description: Multiple status values can be provided with comma separated strings
|
||||||
|
operationId: findPetsByStatus
|
||||||
|
parameters:
|
||||||
|
- name: status
|
||||||
|
in: query
|
||||||
|
description: Status values that need to be considered for filter
|
||||||
|
required: false
|
||||||
|
explode: true
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
default: available
|
||||||
|
enum:
|
||||||
|
- available
|
||||||
|
- pending
|
||||||
|
- sold
|
||||||
|
responses:
|
||||||
|
'200':
|
||||||
|
description: successful operation
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
type: array
|
||||||
|
items:
|
||||||
|
$ref: '#/components/schemas/Account'
|
||||||
|
application/xml:
|
||||||
|
schema:
|
||||||
|
type: array
|
||||||
|
items:
|
||||||
|
$ref: '#/components/schemas/Account'
|
||||||
|
'400':
|
||||||
|
description: Invalid status value
|
||||||
|
security:
|
||||||
|
- petstore_auth:
|
||||||
|
- write:pets
|
||||||
|
- read:pets
|
||||||
|
/pet/findByTags:
|
||||||
|
get:
|
||||||
|
tags:
|
||||||
|
- accounts
|
||||||
|
summary: Finds Pets by tags
|
||||||
|
description: Multiple tags can be provided with comma separated strings. Use tag1, tag2, tag3 for testing.
|
||||||
|
operationId: findPetsByTags
|
||||||
|
parameters:
|
||||||
|
- name: tags
|
||||||
|
in: query
|
||||||
|
description: Tags to filter by
|
||||||
|
required: false
|
||||||
|
explode: true
|
||||||
|
schema:
|
||||||
|
type: array
|
||||||
|
items:
|
||||||
|
type: string
|
||||||
|
responses:
|
||||||
|
'200':
|
||||||
|
description: successful operation
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
type: array
|
||||||
|
items:
|
||||||
|
$ref: '#/components/schemas/Account'
|
||||||
|
application/xml:
|
||||||
|
schema:
|
||||||
|
type: array
|
||||||
|
items:
|
||||||
|
$ref: '#/components/schemas/Account'
|
||||||
|
'400':
|
||||||
|
description: Invalid tag value
|
||||||
|
security:
|
||||||
|
- petstore_auth:
|
||||||
|
- write:pets
|
||||||
|
- read:pets
|
||||||
|
/pet/{petId}:
|
||||||
|
get:
|
||||||
|
tags:
|
||||||
|
- accounts
|
||||||
|
summary: Find pet by ID
|
||||||
|
description: Returns a single pet
|
||||||
|
operationId: getPetById
|
||||||
|
parameters:
|
||||||
|
- name: petId
|
||||||
|
in: path
|
||||||
|
description: ID of pet to return
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
type: integer
|
||||||
|
format: int64
|
||||||
|
responses:
|
||||||
|
'200':
|
||||||
|
description: successful operation
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/Account'
|
||||||
|
application/xml:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/Account'
|
||||||
|
'400':
|
||||||
|
description: Invalid ID supplied
|
||||||
|
'404':
|
||||||
|
description: Pet not found
|
||||||
|
security:
|
||||||
|
- api_key: []
|
||||||
|
- petstore_auth:
|
||||||
|
- write:pets
|
||||||
|
- read:pets
|
||||||
|
post:
|
||||||
|
tags:
|
||||||
|
- accounts
|
||||||
|
summary: Updates a pet in the store with form data
|
||||||
|
description: ''
|
||||||
|
operationId: updatePetWithForm
|
||||||
|
parameters:
|
||||||
|
- name: petId
|
||||||
|
in: path
|
||||||
|
description: ID of pet that needs to be updated
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
type: integer
|
||||||
|
format: int64
|
||||||
|
- name: name
|
||||||
|
in: query
|
||||||
|
description: Name of pet that needs to be updated
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
- name: status
|
||||||
|
in: query
|
||||||
|
description: Status of pet that needs to be updated
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
responses:
|
||||||
|
'400':
|
||||||
|
description: Invalid input
|
||||||
|
security:
|
||||||
|
- petstore_auth:
|
||||||
|
- write:pets
|
||||||
|
- read:pets
|
||||||
|
delete:
|
||||||
|
tags:
|
||||||
|
- accounts
|
||||||
|
summary: Deletes a pet
|
||||||
|
description: delete a pet
|
||||||
|
operationId: deletePet
|
||||||
|
parameters:
|
||||||
|
- name: api_key
|
||||||
|
in: header
|
||||||
|
description: ''
|
||||||
|
required: false
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
- name: petId
|
||||||
|
in: path
|
||||||
|
description: Pet id to delete
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
type: integer
|
||||||
|
format: int64
|
||||||
|
responses:
|
||||||
|
'400':
|
||||||
|
description: Invalid pet value
|
||||||
|
security:
|
||||||
|
- petstore_auth:
|
||||||
|
- write:pets
|
||||||
|
- read:pets
|
||||||
|
/pet/{petId}/uploadImage:
|
||||||
|
post:
|
||||||
|
tags:
|
||||||
|
- accounts
|
||||||
|
summary: uploads an image
|
||||||
|
description: ''
|
||||||
|
operationId: uploadFile
|
||||||
|
parameters:
|
||||||
|
- name: petId
|
||||||
|
in: path
|
||||||
|
description: ID of pet to update
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
type: integer
|
||||||
|
format: int64
|
||||||
|
- name: additionalMetadata
|
||||||
|
in: query
|
||||||
|
description: Additional Metadata
|
||||||
|
required: false
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
requestBody:
|
||||||
|
content:
|
||||||
|
application/octet-stream:
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
format: binary
|
||||||
|
responses:
|
||||||
|
'200':
|
||||||
|
description: successful operation
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/ApiResponse'
|
||||||
|
security:
|
||||||
|
- petstore_auth:
|
||||||
|
- write:pets
|
||||||
|
- read:pets
|
||||||
|
/user:
|
||||||
|
post:
|
||||||
|
tags:
|
||||||
|
- user
|
||||||
|
summary: Create user
|
||||||
|
description: This can only be done by the logged in user.
|
||||||
|
operationId: createUser
|
||||||
|
requestBody:
|
||||||
|
description: Created user object
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/User'
|
||||||
|
application/xml:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/User'
|
||||||
|
application/x-www-form-urlencoded:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/User'
|
||||||
|
responses:
|
||||||
|
default:
|
||||||
|
description: successful operation
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/User'
|
||||||
|
application/xml:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/User'
|
||||||
|
/user/createWithList:
|
||||||
|
post:
|
||||||
|
tags:
|
||||||
|
- user
|
||||||
|
summary: Creates list of users with given input array
|
||||||
|
description: Creates list of users with given input array
|
||||||
|
operationId: createUsersWithListInput
|
||||||
|
requestBody:
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
type: array
|
||||||
|
items:
|
||||||
|
$ref: '#/components/schemas/User'
|
||||||
|
responses:
|
||||||
|
'200':
|
||||||
|
description: Successful operation
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/User'
|
||||||
|
application/xml:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/User'
|
||||||
|
default:
|
||||||
|
description: successful operation
|
||||||
|
/user/login:
|
||||||
|
get:
|
||||||
|
tags:
|
||||||
|
- user
|
||||||
|
summary: Logs user into the system
|
||||||
|
description: ''
|
||||||
|
operationId: loginUser
|
||||||
|
parameters:
|
||||||
|
- name: username
|
||||||
|
in: query
|
||||||
|
description: The user name for login
|
||||||
|
required: false
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
- name: password
|
||||||
|
in: query
|
||||||
|
description: The password for login in clear text
|
||||||
|
required: false
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
responses:
|
||||||
|
'200':
|
||||||
|
description: successful operation
|
||||||
|
headers:
|
||||||
|
X-Rate-Limit:
|
||||||
|
description: calls per hour allowed by the user
|
||||||
|
schema:
|
||||||
|
type: integer
|
||||||
|
format: int32
|
||||||
|
X-Expires-After:
|
||||||
|
description: date in UTC when token expires
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
format: date-time
|
||||||
|
content:
|
||||||
|
application/xml:
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
'400':
|
||||||
|
description: Invalid username/password supplied
|
||||||
|
/user/logout:
|
||||||
|
get:
|
||||||
|
tags:
|
||||||
|
- user
|
||||||
|
summary: Logs out current logged in user session
|
||||||
|
description: ''
|
||||||
|
operationId: logoutUser
|
||||||
|
parameters: []
|
||||||
|
responses:
|
||||||
|
default:
|
||||||
|
description: successful operation
|
||||||
|
/user/{username}:
|
||||||
|
get:
|
||||||
|
tags:
|
||||||
|
- user
|
||||||
|
summary: Get user by user name
|
||||||
|
description: ''
|
||||||
|
operationId: getUserByName
|
||||||
|
parameters:
|
||||||
|
- name: username
|
||||||
|
in: path
|
||||||
|
description: 'The name that needs to be fetched. Use user1 for testing. '
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
responses:
|
||||||
|
'200':
|
||||||
|
description: successful operation
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/User'
|
||||||
|
application/xml:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/User'
|
||||||
|
'400':
|
||||||
|
description: Invalid username supplied
|
||||||
|
'404':
|
||||||
|
description: User not found
|
||||||
|
put:
|
||||||
|
tags:
|
||||||
|
- user
|
||||||
|
summary: Update user
|
||||||
|
description: This can only be done by the logged in user.
|
||||||
|
operationId: updateUser
|
||||||
|
parameters:
|
||||||
|
- name: username
|
||||||
|
in: path
|
||||||
|
description: name that need to be deleted
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
requestBody:
|
||||||
|
description: Update an existent user in the store
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/User'
|
||||||
|
application/xml:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/User'
|
||||||
|
application/x-www-form-urlencoded:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/User'
|
||||||
|
responses:
|
||||||
|
default:
|
||||||
|
description: successful operation
|
||||||
|
delete:
|
||||||
|
tags:
|
||||||
|
- user
|
||||||
|
summary: Delete user
|
||||||
|
description: This can only be done by the logged in user.
|
||||||
|
operationId: deleteUser
|
||||||
|
parameters:
|
||||||
|
- name: username
|
||||||
|
in: path
|
||||||
|
description: The name that needs to be deleted
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
responses:
|
||||||
|
'400':
|
||||||
|
description: Invalid username supplied
|
||||||
|
'404':
|
||||||
|
description: User not found
|
||||||
|
components:
|
||||||
|
schemas:
|
||||||
|
Order:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
id:
|
||||||
|
type: integer
|
||||||
|
format: int64
|
||||||
|
example: 10
|
||||||
|
petId:
|
||||||
|
type: integer
|
||||||
|
format: int64
|
||||||
|
example: 198772
|
||||||
|
quantity:
|
||||||
|
type: integer
|
||||||
|
format: int32
|
||||||
|
example: 7
|
||||||
|
shipDate:
|
||||||
|
type: string
|
||||||
|
format: date-time
|
||||||
|
status:
|
||||||
|
type: string
|
||||||
|
description: Order Status
|
||||||
|
example: approved
|
||||||
|
enum:
|
||||||
|
- placed
|
||||||
|
- approved
|
||||||
|
- delivered
|
||||||
|
complete:
|
||||||
|
type: boolean
|
||||||
|
xml:
|
||||||
|
name: order
|
||||||
|
Customer:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
id:
|
||||||
|
type: integer
|
||||||
|
format: int64
|
||||||
|
example: 100000
|
||||||
|
username:
|
||||||
|
type: string
|
||||||
|
example: fehguy
|
||||||
|
address:
|
||||||
|
type: array
|
||||||
|
xml:
|
||||||
|
name: addresses
|
||||||
|
wrapped: true
|
||||||
|
items:
|
||||||
|
$ref: '#/components/schemas/Address'
|
||||||
|
xml:
|
||||||
|
name: customer
|
||||||
|
Address:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
street:
|
||||||
|
type: string
|
||||||
|
example: 437 Lytton
|
||||||
|
city:
|
||||||
|
type: string
|
||||||
|
example: Palo Alto
|
||||||
|
state:
|
||||||
|
type: string
|
||||||
|
example: CA
|
||||||
|
zip:
|
||||||
|
type: string
|
||||||
|
example: '94301'
|
||||||
|
xml:
|
||||||
|
name: address
|
||||||
|
Category:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
id:
|
||||||
|
type: integer
|
||||||
|
format: int64
|
||||||
|
example: 1
|
||||||
|
name:
|
||||||
|
type: string
|
||||||
|
example: Dogs
|
||||||
|
xml:
|
||||||
|
name: category
|
||||||
|
User:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
id:
|
||||||
|
type: integer
|
||||||
|
format: int64
|
||||||
|
example: 10
|
||||||
|
username:
|
||||||
|
type: string
|
||||||
|
example: theUser
|
||||||
|
firstName:
|
||||||
|
type: string
|
||||||
|
example: John
|
||||||
|
lastName:
|
||||||
|
type: string
|
||||||
|
example: James
|
||||||
|
email:
|
||||||
|
type: string
|
||||||
|
example: john@email.com
|
||||||
|
password:
|
||||||
|
type: string
|
||||||
|
example: '12345'
|
||||||
|
phone:
|
||||||
|
type: string
|
||||||
|
example: '12345'
|
||||||
|
userStatus:
|
||||||
|
type: integer
|
||||||
|
description: User Status
|
||||||
|
format: int32
|
||||||
|
example: 1
|
||||||
|
xml:
|
||||||
|
name: user
|
||||||
|
Tag:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
id:
|
||||||
|
type: integer
|
||||||
|
format: int64
|
||||||
|
name:
|
||||||
|
type: string
|
||||||
|
xml:
|
||||||
|
name: tag
|
||||||
|
Account:
|
||||||
|
required:
|
||||||
|
- name
|
||||||
|
- photoUrls
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
id:
|
||||||
|
type: integer
|
||||||
|
format: int64
|
||||||
|
example: 10
|
||||||
|
name:
|
||||||
|
type: string
|
||||||
|
example: doggie
|
||||||
|
category:
|
||||||
|
$ref: '#/components/schemas/Category'
|
||||||
|
photoUrls:
|
||||||
|
type: array
|
||||||
|
xml:
|
||||||
|
wrapped: true
|
||||||
|
items:
|
||||||
|
type: string
|
||||||
|
xml:
|
||||||
|
name: photoUrl
|
||||||
|
tags:
|
||||||
|
type: array
|
||||||
|
xml:
|
||||||
|
wrapped: true
|
||||||
|
items:
|
||||||
|
$ref: '#/components/schemas/Tag'
|
||||||
|
status:
|
||||||
|
type: string
|
||||||
|
description: pet status in the store
|
||||||
|
enum:
|
||||||
|
- available
|
||||||
|
- pending
|
||||||
|
- sold
|
||||||
|
xml:
|
||||||
|
name: pet
|
||||||
|
ApiResponse:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
code:
|
||||||
|
type: integer
|
||||||
|
format: int32
|
||||||
|
type:
|
||||||
|
type: string
|
||||||
|
message:
|
||||||
|
type: string
|
||||||
|
xml:
|
||||||
|
name: '##default'
|
||||||
|
requestBodies:
|
||||||
|
Pet:
|
||||||
|
description: Pet object that needs to be added to the store
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/Account'
|
||||||
|
application/xml:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/Account'
|
||||||
|
UserArray:
|
||||||
|
description: List of user object
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
type: array
|
||||||
|
items:
|
||||||
|
$ref: '#/components/schemas/User'
|
||||||
|
securitySchemes:
|
||||||
|
petstore_auth:
|
||||||
|
type: oauth2
|
||||||
|
flows:
|
||||||
|
implicit:
|
||||||
|
authorizationUrl: https://petstore3.swagger.io/oauth/authorize
|
||||||
|
scopes:
|
||||||
|
write:pets: modify pets in your account
|
||||||
|
read:pets: read your pets
|
||||||
|
api_key:
|
||||||
|
type: apiKey
|
||||||
|
name: api_key
|
||||||
|
in: header
|
||||||
@@ -0,0 +1,59 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class Transaction:
|
||||||
|
def __init__(self, trans_id, from_id, to_id, amount, time, date, description, t_type):
|
||||||
|
self.trans_id = trans_id
|
||||||
|
self.from_id = from_id
|
||||||
|
self.to_id = to_id
|
||||||
|
self.amount = amount
|
||||||
|
self.time = time
|
||||||
|
self.date = date
|
||||||
|
self.description = description
|
||||||
|
self.t_type = t_type
|
||||||
|
|
||||||
|
|
||||||
|
class Account:
|
||||||
|
def __init__(self, account_id, name, balance, created_t, created_d, last_modified, closed, closure_t, closure_d,
|
||||||
|
notes, transactions=None):
|
||||||
|
if transactions is None:
|
||||||
|
transactions = []
|
||||||
|
self.account_id = account_id
|
||||||
|
self.name = name
|
||||||
|
self.balance = balance
|
||||||
|
self.created_t = created_t
|
||||||
|
self.created_d = created_d
|
||||||
|
self.last_modified = last_modified
|
||||||
|
self.closed = closed
|
||||||
|
self.closure_t = closure_t
|
||||||
|
self.closure_d = closure_d
|
||||||
|
self.notes = notes
|
||||||
|
self.transactions = transactions
|
||||||
|
|
||||||
|
|
||||||
|
class Customer:
|
||||||
|
def __init__(self, customer_id, f_name, l_name, phone, email, birthday, address, signup_d, signup_t, notes,
|
||||||
|
accounts=None):
|
||||||
|
if accounts is None:
|
||||||
|
accounts = []
|
||||||
|
self.customer_id = customer_id
|
||||||
|
self.f_name = f_name
|
||||||
|
self.l_name = l_name
|
||||||
|
self.phone = phone
|
||||||
|
self.email = email
|
||||||
|
self.birthday = birthday
|
||||||
|
self.address = address
|
||||||
|
self.signup_d = signup_d
|
||||||
|
self.signup_t = signup_t
|
||||||
|
self.notes = notes
|
||||||
|
self.accounts = accounts
|
||||||
|
|
||||||
|
#calculate the balance of an account
|
||||||
|
def calc_balance(account):
|
||||||
|
balance = 0
|
||||||
|
for transaction in account.transactions:
|
||||||
|
if transaction.from_id == account.account_id:
|
||||||
|
balance -= transaction.amount
|
||||||
|
elif transaction.to_id == account.account_id:
|
||||||
|
balance += transaction.amount
|
||||||
|
return balance
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
# Lucas Mathews - Fontys Student ID: 5023572
|
||||||
|
# Banking System Manager for Account Class - Version 1
|
||||||
|
|
||||||
|
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
# Lucas Mathews - Fontys Student ID: 5023572
|
||||||
|
# Banking System Manager for Transaction Class - Version 1
|
||||||
|
|
||||||
|
|
||||||
|
def add_transaction(transaction_id, transaction_type, amount, timestamp, description, account_number, recipient_account_number):
|
||||||
|
from api import session, Transaction
|
||||||
|
new_transaction = Transaction(transaction_id, transaction_type, amount, timestamp, description, account_number, recipient_account_number)
|
||||||
|
session.add(new_transaction)
|
||||||
|
session.commit()
|
||||||
|
return new_transaction
|
||||||
|
|
||||||
|
def delete_transaction(transaction_id:int):
|
||||||
|
DELETE_TRANSACTION = "DELETE FROM transaction WHERE transaction_id=?"
|
||||||
|
from api import session, Transaction
|
||||||
|
for transaction in session.query(Transaction).all():
|
||||||
|
if transaction.transaction_id == transaction_id:
|
||||||
|
input(f"Are you sure you would like permanenty delete transaction ID: {transaction_id}? WARNING: This action can not be reversed. (Y/N) ")
|
||||||
|
if input == "Y"or input == "y":
|
||||||
|
session.execute(DELETE_TRANSACTION, (transaction_id))
|
||||||
|
print(f"Transaction ID: {transaction_id} has been removed.")
|
||||||
|
else:
|
||||||
|
return f"Transaction ID: {transaction_id} has NOT been removed."
|
||||||
|
return
|
||||||
|
return f"Transaction ID: {transaction_id} is not found."
|
||||||
+196
@@ -0,0 +1,196 @@
|
|||||||
|
# Lucas Mathews - Fontys Student ID: 5023572
|
||||||
|
# Banking System Classes - Version 2
|
||||||
|
|
||||||
|
###############
|
||||||
|
### Modules ###
|
||||||
|
###############
|
||||||
|
|
||||||
|
import sqlite3
|
||||||
|
import os.path
|
||||||
|
import datetime
|
||||||
|
import connexion
|
||||||
|
from config import CONFIG
|
||||||
|
|
||||||
|
#################
|
||||||
|
### Functions ###
|
||||||
|
#################
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
###############
|
||||||
|
### Classes ###
|
||||||
|
###############
|
||||||
|
|
||||||
|
class Manager:
|
||||||
|
def __init__():
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class Client:
|
||||||
|
def __init__(self, client_id, name, opening_timestamp, birthdate, address, phone_number, email:str, password, accounts, notes):
|
||||||
|
self.client_id = client_id
|
||||||
|
self.name = name
|
||||||
|
self.birthdate = birthdate
|
||||||
|
self.opening_timestamp = opening_timestamp
|
||||||
|
self.address = address
|
||||||
|
self.phone_number = phone_number
|
||||||
|
self.email = email
|
||||||
|
self.password = password
|
||||||
|
self.accounts = accounts
|
||||||
|
self.notes = notes
|
||||||
|
|
||||||
|
#If you call a print function on the object, it will return the following string (does not include password for security reasons)
|
||||||
|
def __str__(self):
|
||||||
|
return f"Client ID: {self.client_id}, Name: {self.name}, Birthdate: {self.birthdate}, Address: {self.address}, Phone Number: {self.phone_number}, Email: {self.email}"
|
||||||
|
|
||||||
|
#This function will return the account list
|
||||||
|
def get_accounts(self)->str:
|
||||||
|
return f"Accounts: {self.accounts}"
|
||||||
|
|
||||||
|
#Change details (name, birthdate, address, phone number, email, password)
|
||||||
|
#Change password
|
||||||
|
|
||||||
|
class Account:
|
||||||
|
def __init__(self, account_id, description, open_timestamp, account_type, balance, enabled, notes, transactions):
|
||||||
|
self.account_id = account_id
|
||||||
|
self.description = description
|
||||||
|
self.open_timestamp = open_timestamp
|
||||||
|
self.account_type = account_type
|
||||||
|
self.balance = balance
|
||||||
|
self.enabled = enabled
|
||||||
|
self.notes = notes
|
||||||
|
self.transactions = transactions
|
||||||
|
|
||||||
|
#If you call a print function on the object, it will return the following string
|
||||||
|
def __str__(self):
|
||||||
|
return f"Account ID: {self.account_id}, Description: {self.description}, Open Timestamp: {self.open_timestamp}, Account Type: {self.account_type}, Balance: {self.balance}, Enabled: {self.enabled}, Notes: {self.notes}, Transactions: {self.transactions}"
|
||||||
|
|
||||||
|
# This function will return the transaction history of an account
|
||||||
|
def transaction_history(self, account_id:int):
|
||||||
|
return self.transactions
|
||||||
|
|
||||||
|
#This function will remove the account
|
||||||
|
def remove_account(self, account_id:int):
|
||||||
|
REMOVE_ACCOUNT = "DELETE FROM account WHERE account_id=?"
|
||||||
|
for account in self.accounts:
|
||||||
|
if account.balance != 0: #If the account has a balance, it can not be removed
|
||||||
|
return f"Account ID: {account_id} has a balance of {account.balance} and can not be removed."
|
||||||
|
if account.account_id == account_id: #Check if account exists
|
||||||
|
input(f"Are you sure you would like permanenty delete account ID: {account_id}? WARNING: This action can not be reversed. (Y/N) ")
|
||||||
|
if input == "Y"or input == "y": #If the user inputs Y or y, the account will be removed
|
||||||
|
db_conn = get_db_connection()
|
||||||
|
cursor = db_conn.cursor()
|
||||||
|
cursor.execute(REMOVE_ACCOUNT, (account_id, ) )
|
||||||
|
db_conn.commit()
|
||||||
|
print(f"Account ID: {account_id} has been removed.")
|
||||||
|
else:
|
||||||
|
return f"Account ID: {account_id} has NOT been removed."
|
||||||
|
return
|
||||||
|
return f"Account ID: {account_id} is not found."
|
||||||
|
|
||||||
|
#This function will return the account balance
|
||||||
|
def account_balance(account_id:int):
|
||||||
|
GET_ACCOUNT = "SELECT balance FROM account WHERE account_id = ?"
|
||||||
|
|
||||||
|
db_conn = get_db_connection()
|
||||||
|
cursor = db_conn.cursor()
|
||||||
|
cursor.execute(GET_ACCOUNT, (account_id) )
|
||||||
|
resultset = cursor.fetchall()
|
||||||
|
db_conn.close()
|
||||||
|
|
||||||
|
if len(resultset) < 1:
|
||||||
|
return "Not found", 404
|
||||||
|
elif len(resultset) > 2:
|
||||||
|
return "Too many results found.", 500
|
||||||
|
|
||||||
|
class Transaction:
|
||||||
|
def __init__(self, transaction_id, transaction_type, amount, timestamp, description, account_number, recipient_account_number = None):
|
||||||
|
self.transaction_id = transaction_id
|
||||||
|
self.transaction_type = transaction_type
|
||||||
|
self.amount = amount
|
||||||
|
self.timestamp = timestamp
|
||||||
|
self.description = description
|
||||||
|
self.account_number = account_number
|
||||||
|
self.recipient_account_number = recipient_account_number
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return f"Transaction ID: {self.transaction_id}, Transaction Type: {self.transaction_type}, Amount: {self.amount}, Timestamp: {self.timestamp}, Description: {self.description} From Account Number: {self.account_number}, Recipient Account Number: {self.recipient_account_number}"
|
||||||
|
|
||||||
|
################
|
||||||
|
### Database ###
|
||||||
|
################
|
||||||
|
|
||||||
|
def Database():
|
||||||
|
CLIENT_TABLE_CREATION_QUERY = """
|
||||||
|
CREATE TABLE IF NOT EXISTS client (
|
||||||
|
client_id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
|
name TEXT NOT NULL,
|
||||||
|
birthdate DATE NOT NULL,
|
||||||
|
opening_timestamp TIMESTAMP NOT NULL,
|
||||||
|
address TEXT NOT NULL,
|
||||||
|
phone_number TEXT NOT NULL,
|
||||||
|
email TEXT NOT NULL,
|
||||||
|
password TEXT NOT NULL,
|
||||||
|
notes TEXT NOT NULL
|
||||||
|
)
|
||||||
|
"""
|
||||||
|
ACCOUNT_TABLE_CREATION_QUERY = """
|
||||||
|
CREATE TABLE IF NOT EXISTS account (
|
||||||
|
account_id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
|
description TEXT NOT NULL,
|
||||||
|
open_timestamp TIMESTAMP NOT NULL,
|
||||||
|
account_type TEXT NOT NULL,
|
||||||
|
balance REAL NOT NULL,
|
||||||
|
enabled BOOLEAN NOT NULL,
|
||||||
|
notes TEXT NOT NULL,
|
||||||
|
client_id INTEGER NOT NULL,
|
||||||
|
FOREIGN KEY (client_id) REFERENCES client(client_id)
|
||||||
|
)
|
||||||
|
"""
|
||||||
|
TRANSACT_TABLE_CREATION_QUERY = """
|
||||||
|
CREATE TABLE IF NOT EXISTS transact (
|
||||||
|
transaction_id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
|
transaction_type TEXT NOT NULL,
|
||||||
|
amount REAL NOT NULL,
|
||||||
|
timestamp TIMESTAMP NOT NULL,
|
||||||
|
description TEXT NOT NULL,
|
||||||
|
account_id INTEGER NOT NULL,
|
||||||
|
recipient_account_id INTEGER,
|
||||||
|
FOREIGN KEY (account_id) REFERENCES account(account_id)
|
||||||
|
)
|
||||||
|
"""
|
||||||
|
# Check if the database exists
|
||||||
|
if os.path.exists('bank.db'):
|
||||||
|
print("Database already exists.")
|
||||||
|
else:
|
||||||
|
print("Database does not exist. Creating database.")
|
||||||
|
|
||||||
|
# Create the database and the tables if they do not exist, or connect to the database if it does exist
|
||||||
|
db_connection = sqlite3.connect('bank.db')
|
||||||
|
db_cursor = db_connection.cursor()
|
||||||
|
db_cursor.execute(CLIENT_TABLE_CREATION_QUERY)
|
||||||
|
db_cursor.execute(ACCOUNT_TABLE_CREATION_QUERY)
|
||||||
|
db_cursor.execute(TRANSACT_TABLE_CREATION_QUERY)
|
||||||
|
db_connection.commit()
|
||||||
|
|
||||||
|
|
||||||
|
#################
|
||||||
|
### Connexion ###
|
||||||
|
#################
|
||||||
|
|
||||||
|
def API():
|
||||||
|
app = connexion.App(__name__)
|
||||||
|
app.add_api('api.yml')
|
||||||
|
app.run(host=CONFIG["server"]["listen_address"], port=CONFIG["server"]["port"], debug=CONFIG["server"]["debug"])
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
################
|
||||||
|
### Run Code ###
|
||||||
|
################
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
Database()
|
||||||
|
API()
|
||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,26 @@
|
|||||||
|
# Lucas Mathews - Fontys Student ID: 5023572
|
||||||
|
# Banking System API
|
||||||
|
|
||||||
|
###############
|
||||||
|
### Modules ###
|
||||||
|
###############
|
||||||
|
|
||||||
|
import connexion # Imports connexion module
|
||||||
|
from config import CONFIG # Imports the configuration file
|
||||||
|
from manager import * # Imports the Manager file that contains the functions for the API
|
||||||
|
|
||||||
|
#################
|
||||||
|
### Connexion ###
|
||||||
|
#################
|
||||||
|
|
||||||
|
def API():
|
||||||
|
app = connexion.FlaskApp(__name__)
|
||||||
|
app.add_api(CONFIG["api_file"]["name"])
|
||||||
|
app.run(host=CONFIG["server"]["listen_ip"], port=CONFIG["server"]["port"], debug=CONFIG["server"]["debug"]) # Runs the API using the configuration file
|
||||||
|
|
||||||
|
################
|
||||||
|
### Run Code ###
|
||||||
|
################
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
API()
|
||||||
@@ -0,0 +1,701 @@
|
|||||||
|
openapi: 3.0.3
|
||||||
|
info:
|
||||||
|
title: Banking API
|
||||||
|
description: |-
|
||||||
|
Lucas Mathews - Fontys Student ID: 5023572
|
||||||
|
contact:
|
||||||
|
email: 522499@student.fontys.nl
|
||||||
|
version: 2.0.0
|
||||||
|
servers:
|
||||||
|
- url: http://127.0.0.1:81
|
||||||
|
tags:
|
||||||
|
- name: client
|
||||||
|
description: Operations for Client Accounts
|
||||||
|
- name: account
|
||||||
|
description: Operations for Bank Accounts
|
||||||
|
- name: transaction
|
||||||
|
description: Operations for Transactions
|
||||||
|
- name: manager
|
||||||
|
description: Operations for Bank Managers
|
||||||
|
paths:
|
||||||
|
/Client/Login:
|
||||||
|
post:
|
||||||
|
tags:
|
||||||
|
- client
|
||||||
|
summary: Log in to the system
|
||||||
|
description: Log in to the system
|
||||||
|
operationId: manager.login_user
|
||||||
|
requestBody:
|
||||||
|
description: Credentials for logging in
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
username:
|
||||||
|
type: string
|
||||||
|
password:
|
||||||
|
type: string
|
||||||
|
required: true
|
||||||
|
responses:
|
||||||
|
'200':
|
||||||
|
description: Successful operation
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/Client'
|
||||||
|
'400':
|
||||||
|
description: Invalid username/password supplied
|
||||||
|
'401':
|
||||||
|
description: Unauthorized
|
||||||
|
/Client/Logout:
|
||||||
|
post:
|
||||||
|
tags:
|
||||||
|
- client
|
||||||
|
summary: Log out from the system
|
||||||
|
description: Log out from the system
|
||||||
|
operationId: manager.logout_user
|
||||||
|
responses:
|
||||||
|
'200':
|
||||||
|
description: Successful operation
|
||||||
|
'401':
|
||||||
|
description: Unauthorized
|
||||||
|
/Client/Password:
|
||||||
|
put:
|
||||||
|
tags:
|
||||||
|
- client
|
||||||
|
summary: Change password
|
||||||
|
description: Change password
|
||||||
|
operationId: manager.change_password
|
||||||
|
parameters:
|
||||||
|
- name: client_id
|
||||||
|
in: query
|
||||||
|
description: ID of client to change password
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
type: integer
|
||||||
|
format: int32
|
||||||
|
- name: password
|
||||||
|
in: query
|
||||||
|
description: New password
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
- name: new_password
|
||||||
|
in: query
|
||||||
|
description: New password
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
responses:
|
||||||
|
'200':
|
||||||
|
description: Password changed successfully
|
||||||
|
'400':
|
||||||
|
description: Old password incorrect
|
||||||
|
'404':
|
||||||
|
description: client_id not found
|
||||||
|
/Client:
|
||||||
|
post:
|
||||||
|
tags:
|
||||||
|
- client
|
||||||
|
summary: Add a new client
|
||||||
|
description: Add a new client to the system
|
||||||
|
operationId: manager.add_client
|
||||||
|
parameters:
|
||||||
|
- name: name
|
||||||
|
in: query
|
||||||
|
description: Client Name
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
- name: birthdate
|
||||||
|
in: query
|
||||||
|
description: Client Birthdate (dd-mm-yyyy)
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
- name: address
|
||||||
|
in: query
|
||||||
|
description: Client Address
|
||||||
|
required: false
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
- name: phone_number
|
||||||
|
in: query
|
||||||
|
description: Client Phone Number
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
- name: email
|
||||||
|
in: query
|
||||||
|
description: Client Email Address
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
- name: password
|
||||||
|
in: query
|
||||||
|
description: Client Email Address
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
- name: notes
|
||||||
|
in: query
|
||||||
|
description: Notes about client
|
||||||
|
required: false
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
responses:
|
||||||
|
'200':
|
||||||
|
description: "Client created"
|
||||||
|
'400':
|
||||||
|
description: Invalid input
|
||||||
|
'422':
|
||||||
|
description: Validation exception
|
||||||
|
put:
|
||||||
|
tags:
|
||||||
|
- client
|
||||||
|
summary: Update an existing client
|
||||||
|
description: Update an existing client Id
|
||||||
|
operationId: manager.update_client
|
||||||
|
requestBody:
|
||||||
|
description: Update an existing client's details
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/Client'
|
||||||
|
required: true
|
||||||
|
responses:
|
||||||
|
'200':
|
||||||
|
description: Successful operation
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/Client'
|
||||||
|
'400':
|
||||||
|
description: Invalid Client ID supplied
|
||||||
|
'404':
|
||||||
|
description: Client not found
|
||||||
|
'422':
|
||||||
|
description: Validation exception
|
||||||
|
get:
|
||||||
|
tags:
|
||||||
|
- client
|
||||||
|
summary: Get a client by ID
|
||||||
|
description: Get a client by ID
|
||||||
|
operationId: manager.get_client
|
||||||
|
parameters:
|
||||||
|
- name: client_id
|
||||||
|
in: query
|
||||||
|
description: ID of client to return
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
type: integer
|
||||||
|
format: int32
|
||||||
|
responses:
|
||||||
|
'200':
|
||||||
|
description: Successful operation
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/Client'
|
||||||
|
'400':
|
||||||
|
description: Invalid Client ID supplied
|
||||||
|
'404':
|
||||||
|
description: Client not found
|
||||||
|
delete:
|
||||||
|
tags:
|
||||||
|
- client
|
||||||
|
summary: Delete a client by ID
|
||||||
|
description: Delete a client by ID
|
||||||
|
operationId: manager.delete_client
|
||||||
|
parameters:
|
||||||
|
- name: client_id
|
||||||
|
in: query
|
||||||
|
description: ID of client to delete
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
format: int32
|
||||||
|
responses:
|
||||||
|
'200':
|
||||||
|
description: Successful operation
|
||||||
|
'400':
|
||||||
|
description: Invalid Client ID supplied
|
||||||
|
'404':
|
||||||
|
description: Client not found
|
||||||
|
/Account:
|
||||||
|
post:
|
||||||
|
tags:
|
||||||
|
- account
|
||||||
|
summary: Add a new account
|
||||||
|
description: Add a new account to the system
|
||||||
|
operationId: manager.add_account
|
||||||
|
parameters:
|
||||||
|
- name: description
|
||||||
|
in: query
|
||||||
|
description: Account description
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
- name: account_type
|
||||||
|
in: query
|
||||||
|
description: Type of account
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
- name: notes
|
||||||
|
in: query
|
||||||
|
description: Notes about account
|
||||||
|
required: false
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
responses:
|
||||||
|
'200':
|
||||||
|
description: Successful operation
|
||||||
|
'400':
|
||||||
|
description: Invalid input
|
||||||
|
'422':
|
||||||
|
description: Validation exception
|
||||||
|
put:
|
||||||
|
tags:
|
||||||
|
- account
|
||||||
|
summary: Update an existing account
|
||||||
|
description: Update an existing account
|
||||||
|
operationId: manager.update_account
|
||||||
|
parameters:
|
||||||
|
- name: account_id
|
||||||
|
in: query
|
||||||
|
description: ID of account to update
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
type: integer
|
||||||
|
format: int32
|
||||||
|
requestBody:
|
||||||
|
description: Update an existing account
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/Account'
|
||||||
|
required: true
|
||||||
|
responses:
|
||||||
|
'200':
|
||||||
|
description: Successful operation
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/Account'
|
||||||
|
'400':
|
||||||
|
description: Invalid Account ID supplied
|
||||||
|
'404':
|
||||||
|
description: Account not found
|
||||||
|
'422':
|
||||||
|
description: Validation exception
|
||||||
|
get:
|
||||||
|
tags:
|
||||||
|
- account
|
||||||
|
summary: Get an account by ID
|
||||||
|
description: Get an account by ID
|
||||||
|
operationId: manager.get_account
|
||||||
|
parameters:
|
||||||
|
- name: account_id
|
||||||
|
in: query
|
||||||
|
description: ID of account to return
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
type: integer
|
||||||
|
format: int32
|
||||||
|
responses:
|
||||||
|
'200':
|
||||||
|
description: Successful operation
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/Account'
|
||||||
|
'400':
|
||||||
|
description: Invalid Account ID supplied
|
||||||
|
'404':
|
||||||
|
description: Account not found
|
||||||
|
delete:
|
||||||
|
tags:
|
||||||
|
- account
|
||||||
|
summary: Delete an account by ID
|
||||||
|
description: Delete an account by ID
|
||||||
|
operationId: manager.delete_account
|
||||||
|
parameters:
|
||||||
|
- name: account_id
|
||||||
|
in: query
|
||||||
|
description: ID of account to delete
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
format: int32
|
||||||
|
responses:
|
||||||
|
'200':
|
||||||
|
description: Successful operation
|
||||||
|
'400':
|
||||||
|
description: Invalid account_id supplied
|
||||||
|
'404':
|
||||||
|
description: Account not found
|
||||||
|
/Transaction:
|
||||||
|
get:
|
||||||
|
tags:
|
||||||
|
- transaction
|
||||||
|
summary: Get a transaction by ID
|
||||||
|
description: Get a transaction by ID
|
||||||
|
operationId: manager.get_transaction
|
||||||
|
parameters:
|
||||||
|
- name: transaction_id
|
||||||
|
in: query
|
||||||
|
description: ID of transaction to return
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
type: integer
|
||||||
|
format: int32
|
||||||
|
responses:
|
||||||
|
'200':
|
||||||
|
description: Successful operation
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/Transaction'
|
||||||
|
'400':
|
||||||
|
description: Invalid Transaction ID supplied
|
||||||
|
'404':
|
||||||
|
description: Transaction not found
|
||||||
|
post:
|
||||||
|
tags:
|
||||||
|
- transaction
|
||||||
|
summary: Add a new transaction
|
||||||
|
description: Add a new transaction to the system
|
||||||
|
operationId: manager.add_transaction
|
||||||
|
parameters:
|
||||||
|
- name: amount
|
||||||
|
in: query
|
||||||
|
description: Amount of transaction
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
type: integer
|
||||||
|
format: int32
|
||||||
|
- name: account_from
|
||||||
|
in: query
|
||||||
|
description: Account number the money paid from
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
- name: account_to
|
||||||
|
in: query
|
||||||
|
description: Recipient account number
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
- name: description
|
||||||
|
in: query
|
||||||
|
description: Description of transaction
|
||||||
|
required: false
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
responses:
|
||||||
|
'200':
|
||||||
|
description: Successful operation
|
||||||
|
'400':
|
||||||
|
description: Invalid input
|
||||||
|
'422':
|
||||||
|
description: Validation exception
|
||||||
|
/Transaction/History:
|
||||||
|
get:
|
||||||
|
tags:
|
||||||
|
- transaction
|
||||||
|
summary: Get transaction history
|
||||||
|
description: Get transaction history
|
||||||
|
operationId: manager.transaction_history
|
||||||
|
parameters:
|
||||||
|
- name: account_id
|
||||||
|
in: query
|
||||||
|
description: ID of account to return
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
type: integer
|
||||||
|
format: int32
|
||||||
|
responses:
|
||||||
|
'200':
|
||||||
|
description: Successful operation
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/Transaction'
|
||||||
|
'400':
|
||||||
|
description: Invalid input
|
||||||
|
'404':
|
||||||
|
description: No transactions found
|
||||||
|
/Manager/Interest:
|
||||||
|
post:
|
||||||
|
tags:
|
||||||
|
- manager
|
||||||
|
summary: Apply interest
|
||||||
|
description: Apply interest to account
|
||||||
|
operationId: manager.apply_interest
|
||||||
|
requestBody:
|
||||||
|
description: Apply interest to account
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/Account'
|
||||||
|
required: true
|
||||||
|
responses:
|
||||||
|
'200':
|
||||||
|
description: Successful operation
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/Account'
|
||||||
|
'400':
|
||||||
|
description: Invalid input
|
||||||
|
'422':
|
||||||
|
description: Validation exception
|
||||||
|
put:
|
||||||
|
tags:
|
||||||
|
- manager
|
||||||
|
summary: Apply fee
|
||||||
|
description: Apply fee to account
|
||||||
|
operationId: manager.apply_fee
|
||||||
|
requestBody:
|
||||||
|
description: Apply fee to account
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/Account'
|
||||||
|
required: true
|
||||||
|
responses:
|
||||||
|
'200':
|
||||||
|
description: Successful operation
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/Account'
|
||||||
|
'400':
|
||||||
|
description: Invalid input
|
||||||
|
'422':
|
||||||
|
description: Validation exception
|
||||||
|
/Manager/Clients:
|
||||||
|
get:
|
||||||
|
tags:
|
||||||
|
- manager
|
||||||
|
summary: Get all clients
|
||||||
|
description: Get all clients
|
||||||
|
operationId: manager.get_all_clients
|
||||||
|
responses:
|
||||||
|
'200':
|
||||||
|
description: Successful operation
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/Client'
|
||||||
|
'400':
|
||||||
|
description: Invalid input
|
||||||
|
'404':
|
||||||
|
description: No clients found
|
||||||
|
/Manager/Accounts:
|
||||||
|
get:
|
||||||
|
tags:
|
||||||
|
- manager
|
||||||
|
summary: Get all accounts
|
||||||
|
description: Get all accounts
|
||||||
|
operationId: manager.get_all_accounts
|
||||||
|
responses:
|
||||||
|
'200':
|
||||||
|
description: Successful operation
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/Account'
|
||||||
|
'400':
|
||||||
|
description: Invalid input
|
||||||
|
'404':
|
||||||
|
description: No accounts found
|
||||||
|
/Manager/Transactions:
|
||||||
|
get:
|
||||||
|
tags:
|
||||||
|
- manager
|
||||||
|
summary: Get all transactions
|
||||||
|
description: Get all transactions
|
||||||
|
operationId: manager.get_all_transactions
|
||||||
|
responses:
|
||||||
|
'200':
|
||||||
|
description: Successful operation
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/Transaction'
|
||||||
|
'400':
|
||||||
|
description: Invalid input
|
||||||
|
'404':
|
||||||
|
description: No transactions found
|
||||||
|
put:
|
||||||
|
tags:
|
||||||
|
- manager
|
||||||
|
summary: Update an existing transaction
|
||||||
|
description: Update an existing transaction
|
||||||
|
operationId: manager.update_transaction
|
||||||
|
requestBody:
|
||||||
|
description: Update an existing transaction
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/Transaction'
|
||||||
|
required: true
|
||||||
|
responses:
|
||||||
|
'200':
|
||||||
|
description: Successful operation
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/Transaction'
|
||||||
|
'400':
|
||||||
|
description: Invalid Transaction ID supplied
|
||||||
|
'404':
|
||||||
|
description: Transaction not found
|
||||||
|
'422':
|
||||||
|
description: Validation exception
|
||||||
|
/Manager/Hash:
|
||||||
|
get:
|
||||||
|
tags:
|
||||||
|
- manager
|
||||||
|
summary: Hash password
|
||||||
|
description: Pass a string through the hashing algorithm
|
||||||
|
operationId: manager.password_hash
|
||||||
|
parameters:
|
||||||
|
- name: password
|
||||||
|
in: query
|
||||||
|
description: Password to hash
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
responses:
|
||||||
|
'200':
|
||||||
|
description: Successful operation
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
'400':
|
||||||
|
description: Invalid input
|
||||||
|
'401':
|
||||||
|
description: Unauthorized
|
||||||
|
/Manager/Timestamp:
|
||||||
|
get:
|
||||||
|
tags:
|
||||||
|
- manager
|
||||||
|
summary: Get the timestamp
|
||||||
|
description: Gets the date and time in the appropriate format
|
||||||
|
operationId: manager.timestamp
|
||||||
|
responses:
|
||||||
|
'200':
|
||||||
|
description: Successful operation
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
'400':
|
||||||
|
description: Invalid input
|
||||||
|
'401':
|
||||||
|
description: Unauthorized
|
||||||
|
components:
|
||||||
|
schemas:
|
||||||
|
Client:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
client_id:
|
||||||
|
type: integer
|
||||||
|
format: int32
|
||||||
|
name:
|
||||||
|
type: string
|
||||||
|
birthdate:
|
||||||
|
type: string
|
||||||
|
opening_timestamp:
|
||||||
|
type: string
|
||||||
|
address:
|
||||||
|
type: string
|
||||||
|
phone_number:
|
||||||
|
type: string
|
||||||
|
email:
|
||||||
|
type: string
|
||||||
|
password:
|
||||||
|
type: string
|
||||||
|
notes:
|
||||||
|
type: string
|
||||||
|
enabled:
|
||||||
|
type: boolean
|
||||||
|
administator:
|
||||||
|
type: boolean
|
||||||
|
accounts:
|
||||||
|
type: array
|
||||||
|
example:
|
||||||
|
client_id: 1
|
||||||
|
name: "Lucas Mathews"
|
||||||
|
birthdate: "21-05-1980"
|
||||||
|
opening_timestamp: "17-04-2022 16:21:12"
|
||||||
|
address: "Rachelsmolen 1, 5612MA, Eindhoven"
|
||||||
|
phone_number: "0612345678"
|
||||||
|
email: "john.d@fontys.nl"
|
||||||
|
password: "password"
|
||||||
|
notes: "This is a test client"
|
||||||
|
enabled: true
|
||||||
|
administator: false
|
||||||
|
accounts: []
|
||||||
|
Account:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
account_id:
|
||||||
|
type: integer
|
||||||
|
format: int32
|
||||||
|
decription:
|
||||||
|
type: string
|
||||||
|
opening_timestamp:
|
||||||
|
type: string
|
||||||
|
account_type:
|
||||||
|
type: string
|
||||||
|
balance:
|
||||||
|
type: number
|
||||||
|
enabled:
|
||||||
|
type: boolean
|
||||||
|
notes:
|
||||||
|
type: string
|
||||||
|
transactons:
|
||||||
|
type: array
|
||||||
|
example:
|
||||||
|
account_id: 1
|
||||||
|
description: "Savings Account"
|
||||||
|
opening_timestamp: "17-04-2022 16:21:12"
|
||||||
|
account_type: "Rachelsmolen 1, 5612MA, Eindhoven"
|
||||||
|
balance: 2314.23
|
||||||
|
enabled: true
|
||||||
|
notes: "This is a savings account"
|
||||||
|
transactions: []
|
||||||
|
Transaction:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
transaction_id:
|
||||||
|
type: integer
|
||||||
|
format: int32
|
||||||
|
transaction_type:
|
||||||
|
type: string
|
||||||
|
amount:
|
||||||
|
type: integer
|
||||||
|
format: int32
|
||||||
|
timestamp:
|
||||||
|
type: string
|
||||||
|
description:
|
||||||
|
type: string
|
||||||
|
account_number:
|
||||||
|
type: string
|
||||||
|
recipient_account_number:
|
||||||
|
type: string
|
||||||
|
example:
|
||||||
|
transaction_id: 1
|
||||||
|
transaction_type: "Deposit"
|
||||||
|
amount: 100.00
|
||||||
|
timestamp: "17-04-2022 16:21:12"
|
||||||
|
description: "Deposit to Savings Account"
|
||||||
|
account_number: "NL12ABNA0123456789"
|
||||||
|
recipient_account_number: "NL12ABNA1234567890"
|
||||||
|
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
[database]
|
||||||
|
name=bank.db
|
||||||
|
add_sample_data=True
|
||||||
|
|
||||||
|
[api_file]
|
||||||
|
name=api.yml
|
||||||
|
|
||||||
|
[server]
|
||||||
|
listen_ip=127.0.0.1
|
||||||
|
port=81
|
||||||
|
debug=True
|
||||||
|
|
||||||
|
[frontend]
|
||||||
|
listen_ip=127.0.0.1
|
||||||
|
port=80
|
||||||
|
debug=True
|
||||||
|
|
||||||
|
[api]
|
||||||
|
url=http://127.0.0.1:81/
|
||||||
|
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
# Lucas Mathews - Fontys Student ID: 5023572
|
||||||
|
# Banking System Account Class
|
||||||
|
|
||||||
|
from sqlalchemy import ForeignKey, Column, String, Integer, Boolean
|
||||||
|
|
||||||
|
|
||||||
|
from class_base import Base
|
||||||
|
|
||||||
|
class Account(Base):
|
||||||
|
__tablename__ = 'accounts'
|
||||||
|
account_id = Column("account_id", String, primary_key=True)
|
||||||
|
description = Column("description", String)
|
||||||
|
open_timestamp = Column("open_timestamp", String)
|
||||||
|
account_type = Column("account_type", String)
|
||||||
|
balance = Column("balance", Integer)
|
||||||
|
enabled = Column("enabled", Boolean)
|
||||||
|
notes = Column("notes", String)
|
||||||
|
transactions = ("transactions", String, ForeignKey("transactions.transaction_id"))
|
||||||
|
|
||||||
|
def __init__(self, account_id, description, open_timestamp, account_type, balance, enabled, notes, transactions):
|
||||||
|
self.account_id = account_id
|
||||||
|
self.description = description
|
||||||
|
self.open_timestamp = open_timestamp
|
||||||
|
self.account_type = account_type
|
||||||
|
self.balance = balance
|
||||||
|
self.enabled = enabled
|
||||||
|
self.notes = notes
|
||||||
|
self.transactions = transactions
|
||||||
|
|
||||||
|
def __repr__(self):
|
||||||
|
return f"Account ID: {self.account_id}, Description: {self.description}, Open Timestamp: {self.open_timestamp}, Account Type: {self.account_type}, Balance: {self.balance}, Enabled: {self.enabled}, Notes: {self.notes}, Transactions: {self.transactions}"
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
# Lucas Mathews - Fontys Student ID: 5023572
|
||||||
|
# Banking System Base Class
|
||||||
|
|
||||||
|
from sqlalchemy.orm import declarative_base
|
||||||
|
|
||||||
|
Base = declarative_base()
|
||||||
@@ -0,0 +1,38 @@
|
|||||||
|
# Lucas Mathews - Fontys Student ID: 5023572
|
||||||
|
# Banking System Client Class
|
||||||
|
|
||||||
|
from sqlalchemy import Column, String, Boolean
|
||||||
|
|
||||||
|
from class_base import Base
|
||||||
|
|
||||||
|
class Client(Base):
|
||||||
|
__tablename__ = 'clients'
|
||||||
|
client_id = Column("client_id", String, primary_key=True)
|
||||||
|
name = Column("name", String)
|
||||||
|
birthdate = Column("birthdate", String)
|
||||||
|
opening_timestamp = Column("opening_timestamp", String)
|
||||||
|
address = Column("address", String)
|
||||||
|
phone_number = Column("phone_number", String)
|
||||||
|
email = Column("email", String)
|
||||||
|
hash = Column("hash", String)
|
||||||
|
notes = Column("notes", String)
|
||||||
|
enabled = Column("enabled", Boolean)
|
||||||
|
administrator = Column("administrator", Boolean)
|
||||||
|
accounts = Column("accounts", String)
|
||||||
|
|
||||||
|
def __init__(self, client_id, name, birthdate, opening_timestamp, address, phone_number, email, hash, notes, enabled, administrator, accounts):
|
||||||
|
self.client_id = client_id
|
||||||
|
self.name = name
|
||||||
|
self.birthdate = birthdate
|
||||||
|
self.opening_timestamp = opening_timestamp
|
||||||
|
self.address = address
|
||||||
|
self.phone_number = phone_number
|
||||||
|
self.email = email
|
||||||
|
self.hash = hash
|
||||||
|
self.notes = notes
|
||||||
|
self.enabled = enabled
|
||||||
|
self.administrator = administrator
|
||||||
|
self.accounts = accounts
|
||||||
|
|
||||||
|
def __repr__(self):
|
||||||
|
return f"Client ID: {self.client_id}, Name: {self.name}, Birthdate: {self.birthdate}, Address: {self.address}, Phone Number: {self.phone_number}, Email: {self.email}, Enabled: {self.enabled}, Accounts: {self.accounts}"
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
# Lucas Mathews - Fontys Student ID: 5023572
|
||||||
|
# Banking System Transaction Class
|
||||||
|
|
||||||
|
from sqlalchemy import Column, String, Integer
|
||||||
|
|
||||||
|
from class_base import Base
|
||||||
|
|
||||||
|
class Transaction(Base):
|
||||||
|
__tablename__ = 'transactions'
|
||||||
|
transaction_id = Column("transaction_id", String, primary_key=True)
|
||||||
|
transaction_type = Column("transaction_type", String)
|
||||||
|
amount = Column("amount", Integer)
|
||||||
|
timestamp = Column("timestamp", String)
|
||||||
|
description = Column("description", String)
|
||||||
|
account_number = Column("account_number", Integer)
|
||||||
|
recipient_account_number = Column("recipient_account_number", Integer)
|
||||||
|
|
||||||
|
def __init__(self, transaction_id, transaction_type, amount, timestamp, description, account_number, recipient_account_number = None):
|
||||||
|
self.transaction_id = transaction_id
|
||||||
|
self.transaction_type = transaction_type
|
||||||
|
self.amount = amount
|
||||||
|
self.timestamp = timestamp
|
||||||
|
self.description = description
|
||||||
|
self.account_number = account_number
|
||||||
|
self.recipient_account_number = recipient_account_number
|
||||||
|
|
||||||
|
def __repr__(self):
|
||||||
|
return f"Transaction ID: {self.transaction_id}, Transaction Type: {self.transaction_type}, Amount: {self.amount}, Timestamp: {self.timestamp}, Description: {self.description} From Account Number: {self.account_number}, Recipient Account Number: {self.recipient_account_number}"
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
# Lucas Mathews - Fontys Student ID: 5023572
|
||||||
|
# Banking System CLI Utility
|
||||||
|
|
||||||
|
import requests
|
||||||
|
|
||||||
|
SERVER_URL = "http://127.0.0.1:5000"
|
||||||
|
|
||||||
|
def main():
|
||||||
|
username = "john"
|
||||||
|
password = "doe"
|
||||||
|
print(f"Login with {username} and {password}:")
|
||||||
|
response = requests.get( f"{SERVER_URL}/login?username={username}&password={password}")
|
||||||
|
print(f"{response}, {response.content}")
|
||||||
|
|
||||||
|
print(f"Logout:")
|
||||||
|
response = requests.get( f"{SERVER_URL}/logout")
|
||||||
|
print(f"{response}, {response.content}")
|
||||||
|
print(f"Closing")
|
||||||
|
main()
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
# Lucas Mathews - Fontys Student ID: 5023572
|
||||||
|
# Banking System Config Parser
|
||||||
|
|
||||||
|
import configparser
|
||||||
|
|
||||||
|
CONFIG = configparser.ConfigParser()
|
||||||
|
CONFIG.read("bank.ini")
|
||||||
+58
@@ -0,0 +1,58 @@
|
|||||||
|
# Lucas Mathews - Fontys Student ID: 5023572
|
||||||
|
# Banking System Manager File
|
||||||
|
|
||||||
|
import os.path
|
||||||
|
|
||||||
|
from sqlalchemy import create_engine
|
||||||
|
from sqlalchemy.orm import sessionmaker
|
||||||
|
|
||||||
|
#Import Config
|
||||||
|
from config import CONFIG
|
||||||
|
|
||||||
|
# Check if the database exists
|
||||||
|
if os.path.exists(CONFIG["database"]["name"]):
|
||||||
|
print(f"Database {CONFIG["database"]["name"]} already exists.")
|
||||||
|
else:
|
||||||
|
print(f"Database {CONFIG["database"]["name"]} does not exist. Creating it now.")
|
||||||
|
|
||||||
|
# Sets the database file to be used from the configuration file
|
||||||
|
db_url : str = "sqlite:///" + CONFIG["database"]["name"]
|
||||||
|
print(f"Database file set to: {db_url}")
|
||||||
|
|
||||||
|
# Creates the database engine (does not create the database file if it already exists)
|
||||||
|
engine = create_engine(db_url, echo=True)
|
||||||
|
|
||||||
|
#Import Classes
|
||||||
|
from class_base import Base # Imports the base class required by SQLAlchemy
|
||||||
|
from class_client import Client
|
||||||
|
from class_account import Account
|
||||||
|
from class_transaction import Transaction
|
||||||
|
|
||||||
|
# Create the tables in the database
|
||||||
|
Base.metadata.create_all(bind=engine) # Creates the tables in the database from the classes
|
||||||
|
|
||||||
|
# Creates a session to interact with the database
|
||||||
|
Session = sessionmaker(bind=engine) # Creates a session to interact with the database
|
||||||
|
session = Session() # Creates a session object
|
||||||
|
|
||||||
|
# Add sample data if enabled in the configuration file if the database is empty
|
||||||
|
if CONFIG["database"]["add_sample_data"] == "True": # Checks if sample data addition is enabled
|
||||||
|
if session.query(Client).count() == 0: # Checks if the database is empty
|
||||||
|
print(f"Sample data addition is disabled because the database is not empty.")
|
||||||
|
print(f"Adding sample data to new database file {CONFIG["database"]["name"]}.")
|
||||||
|
session.add(Client("f9a16945-b570-4153-ba63-413f2cc2768a", "Lucas Mathews", "24/08/1998", "17/04/2024", "Rachelsmolen 1, 5612MA, Eindhoven", "0612345678", "522499@student.fontys.nl", "7835062ec36ed529fe22cc63baf3ec18d347dacb21c9801da8ba0848cc18efdf1e51717dd5b1240f7556aca3947aa0722452858be6002c1d46b1f1c311b0e9d8", "Notes", True, True, "1, 2"))
|
||||||
|
session.add(Client("5be2a74d-d55c-4de6-85a1-2ed6a355f2cd", "Rigby", "16/03/2018", "06/05/2024", "Rachelsmolen 1, 5612MA, Eindhoven", "0612345678", "522499@cat.fontys.nl", "d3e7df3c78682fbb51e8c6110b3926349bb426bc9834c640cd666519901aef3dfab7822d66fb2dd9e39eb5a8492f6801c2e17ba4c16b8fbcd159c036fe27d8bd", "Is a cat", True, False, "3"))
|
||||||
|
session.add(Account("4c227b02-348c-4611-99a2-8967680cdee6", "Savings Account", "17/04/2024", "Savings", 3000, True, "Savings account", "1"))
|
||||||
|
session.add(Account("b9d9b801-eaab-45be-a4d1-1f7b0bbf798f", "Spending Account", "17/04/2024", "Spending", 150, True, "Spending account", "1"))
|
||||||
|
session.add(Account("f182f186-0a88-4f98-8a02-3a568c65aba7", "Cat Account", "06/05/2024", "Cat Account", 497, True, "Food savings", "2"))
|
||||||
|
session.add(Transaction("9d989788-f983-4590-8de2-9aa0c8bec7d2", "Deposit", 5000, "17/04/2024", "Initial Deposit", 1, "23542335"))
|
||||||
|
session.add(Transaction("153cee93-51c7-4114-b9ef-e307fbf0bf87", "Deposit", 100, "17/04/2024", "Initial Deposit", 2, "23542335"))
|
||||||
|
session.add(Transaction("4bec761a-0f36-452f-a48a-127dcf526e47", "Deposit", 500, "06/05/2024", "Initial Deposit", 3, "23542335"))
|
||||||
|
session.add(Transaction("227a2a9e-a13b-484b-b037-78deeeb0258c", "Withdrawal", 2000, "06/05/2024", "Uni Fees", 3, "Fontys University"))
|
||||||
|
session.add(Transaction("7248a706-29a8-478b-a674-c12ebf9a904a", "Withdrawal", 50, "06/05/2024", "Groceries", 3, "Aldi"))
|
||||||
|
session.add(Transaction("ba367c28-41e6-4f8a-9bfa-3819f7b89a58", "Withdrawal", 3, "06/05/2024", "Treats", 3, "ZooPlus"))
|
||||||
|
session.commit()
|
||||||
|
else:
|
||||||
|
print(f"The database is not empty, skipping sample data addition.")
|
||||||
|
else:
|
||||||
|
print(f"Sample data addition is disabled.")
|
||||||
+249
@@ -0,0 +1,249 @@
|
|||||||
|
# Lucas Mathews - Fontys Student ID: 5023572
|
||||||
|
# Banking System Manager File
|
||||||
|
|
||||||
|
from class_client import Client
|
||||||
|
from class_account import Account
|
||||||
|
from class_transaction import Transaction
|
||||||
|
from flask import jsonify
|
||||||
|
import hashlib # hashlib for password hashing
|
||||||
|
import datetime # datetime for timestamps
|
||||||
|
import uuid # uuid for unique identifiers
|
||||||
|
|
||||||
|
|
||||||
|
from database import * # Importing the database connection
|
||||||
|
|
||||||
|
##############
|
||||||
|
### System ###
|
||||||
|
##############
|
||||||
|
|
||||||
|
def timestamp(): # Returns the current timestamp
|
||||||
|
return (datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S"))
|
||||||
|
|
||||||
|
def password_hash(password:str): # Converts a string to SHA512 hash
|
||||||
|
return hashlib.sha512(password.encode()).hexdigest()
|
||||||
|
|
||||||
|
def generate_uuid(): # Generates a unique identifier for transactions
|
||||||
|
return str(uuid.uuid4())
|
||||||
|
|
||||||
|
def generate_uuid_short(): # Generates a short uuid
|
||||||
|
return str(uuid.uuid4())[:8]
|
||||||
|
|
||||||
|
##############
|
||||||
|
### Client ###
|
||||||
|
##############
|
||||||
|
|
||||||
|
def get_client(client_id:int): # Returns a specific client in the database
|
||||||
|
client = session.query(Client).filter_by(client_id=client_id).one_or_none()
|
||||||
|
if client is None:
|
||||||
|
return jsonify({"error": "Client not found"}), 404
|
||||||
|
if client is not None:
|
||||||
|
return jsonify({"name": client.name, "birthdate": client.birthdate, "opening_timestamp": client.opening_timestamp, "address": client.address, "phone_number": client.phone_number, "email": client.email}), 200
|
||||||
|
|
||||||
|
def change_password(client_id, password:str, new_password:str): # Changes the password of a client
|
||||||
|
old_hash = password_hash(password)
|
||||||
|
new_hash = password_hash(new_password)
|
||||||
|
for client in session.query(Client).all():
|
||||||
|
if client.client_id == client_id:
|
||||||
|
if client.hash == old_hash:
|
||||||
|
client.hash = new_hash
|
||||||
|
session.commit()
|
||||||
|
return "Password changed successfully.", 200
|
||||||
|
return "Incorrect old password.", 400
|
||||||
|
return f"client_id: {client_id} is not found.", 404
|
||||||
|
|
||||||
|
def add_client(name:str, birthdate:str, address:str, phone_number:str, email:str, password:str, **kwargs): # Adds a new client to the database
|
||||||
|
client_id = generate_uuid_short()
|
||||||
|
notes = kwargs.get("notes", None)
|
||||||
|
new_client = Client(client_id, name, birthdate, timestamp(), address, phone_number, email, password_hash(password), notes, 1, 0, None)
|
||||||
|
session.add(new_client)
|
||||||
|
session.commit()
|
||||||
|
return f"New client has been added: name: {name}, uuid: {client_id} ", 200
|
||||||
|
|
||||||
|
def delete_client(client_id): # Deletes a client from the database
|
||||||
|
for client in session.query(Client).all():
|
||||||
|
if client.client_id == client_id:
|
||||||
|
if client.accounts == None:
|
||||||
|
session.delete(client)
|
||||||
|
session.commit()
|
||||||
|
return f"client_id: {client_id} has been removed.", 200
|
||||||
|
else:
|
||||||
|
return f"client_id: {client_id} has active accounts and can not be removed.", 400
|
||||||
|
return f"client_id: {client_id} is not found.", 404
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def login_user(email:str, password:str):
|
||||||
|
for client in session.query(Client).all():
|
||||||
|
if client.email == email and client.password == password:
|
||||||
|
return f"Welcome {client.name}."
|
||||||
|
return "Invalid email or password."
|
||||||
|
|
||||||
|
def logout_user():
|
||||||
|
return "You have been logged out."
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def update_client(client_id, name, birthdate, address, phone_number, email, notes):
|
||||||
|
for client in session.query(Client).all():
|
||||||
|
if client.client_id == client_id:
|
||||||
|
client.name = name
|
||||||
|
client.birthdate = birthdate
|
||||||
|
client.address = address
|
||||||
|
client.phone_number = phone_number
|
||||||
|
client.email = email
|
||||||
|
client.notes = notes
|
||||||
|
session.commit()
|
||||||
|
return f"client_id: {client_id} has been updated."
|
||||||
|
return f"Client ID: {client_id} is not found."
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
###############
|
||||||
|
### Account ###
|
||||||
|
###############
|
||||||
|
|
||||||
|
def get_account(account_id:int): # Returns a specific account in the database
|
||||||
|
account = session.query(Account).filter_by(account_id=account_id).one_or_none()
|
||||||
|
if account is None:
|
||||||
|
return jsonify({"error": "Account not found"}), 404
|
||||||
|
if account is not None:
|
||||||
|
for account in account:
|
||||||
|
return jsonify({"description": account.description, "account_type": account.account_type, "balance": account.balance, "enabled": account.enabled, "notes": account.notes}), 200
|
||||||
|
|
||||||
|
def add_account(description:str, account_type, **kwargs): # Adds a new account to the database
|
||||||
|
account_id = generate_uuid_short()
|
||||||
|
notes = kwargs.get("notes", None)
|
||||||
|
new_account = Account(account_id, description, timestamp(), account_type, 0, 1, notes, None)
|
||||||
|
session.add(new_account)
|
||||||
|
session.commit()
|
||||||
|
return f"New account has been added: description: {description}, uuid: {account_id} ", 200
|
||||||
|
|
||||||
|
def delete_account(account_id): # Deletes an account from the database
|
||||||
|
for account in session.query(Account).all():
|
||||||
|
if account.account_id == account_id:
|
||||||
|
if account.balance == 0:
|
||||||
|
session.delete(account)
|
||||||
|
session.commit()
|
||||||
|
return f"account_id: {account_id} has been removed.", 200
|
||||||
|
else:
|
||||||
|
return f"account_id: {account_id} has a balance and can not be removed.", 400
|
||||||
|
return f"account_id: {account_id} is not found.", 404
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def update_account(account_id:int, update:dict):
|
||||||
|
for account in session.query(Account).all():
|
||||||
|
if account.account_id == account_id:
|
||||||
|
account.description = update["description"]
|
||||||
|
account.account_type = update["account_type"]
|
||||||
|
account.balance = update["balance"]
|
||||||
|
account.enabled = update["enabled"]
|
||||||
|
account.notes = update["notes"]
|
||||||
|
session.commit()
|
||||||
|
return f"account_id: {update['account_id']} has been updated."
|
||||||
|
return f"account_id: {update['account_id']} is not found."
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
###################
|
||||||
|
### Transaction ###
|
||||||
|
###################
|
||||||
|
|
||||||
|
def get_transaction(transaction_id:int): # Returns a specific transaction in the database
|
||||||
|
transaction = session.query(Transaction).filter_by(transaction_id=transaction_id).one_or_none()
|
||||||
|
if transaction is None:
|
||||||
|
return jsonify({"error": "Transaction not found"}), 404
|
||||||
|
if transaction is not None:
|
||||||
|
return jsonify({"transaction_type": transaction.transaction_type, "amount": transaction.amount, "timestamp": transaction.timestamp, "description": transaction.description, "account_number": transaction.account_number, "recipient_account_number": transaction.recipient_account_number}), 200
|
||||||
|
|
||||||
|
def transaction_history(account_id:int): # Returns all transactions for a specific account
|
||||||
|
result = session.query(Transaction).filter(Transaction.account_number == account_id)
|
||||||
|
return jsonify([{"transaction_id": transaction.transaction_id, "transaction_type": transaction.transaction_type, "amount": transaction.amount, "timestamp": transaction.timestamp, "description": transaction.description, "account_number": transaction.account_number, "recipient_account_number": transaction.recipient_account_number} for transaction in result]), 200
|
||||||
|
|
||||||
|
def add_transaction(amount:int, account_from, account_to, **kwargs): # Adds a new transaction to the database
|
||||||
|
transaction_id = generate_uuid()
|
||||||
|
for account in session.query(Account).all():
|
||||||
|
if account.account_id == account_from:
|
||||||
|
if account.balance < amount:
|
||||||
|
return f"Account ID: {account_from} does not have enough funds to transfer {amount}.", 401
|
||||||
|
account.balance -= amount
|
||||||
|
transaction_type = "withdraw"
|
||||||
|
session.commit()
|
||||||
|
if account.account_id == account_to:
|
||||||
|
account.balance += amount
|
||||||
|
transaction_type = "transfer"
|
||||||
|
session.commit()
|
||||||
|
description = kwargs.get("description", None)
|
||||||
|
new_transaction = Transaction(transaction_id, transaction_type, amount, timestamp(), description, account_from, account_to)
|
||||||
|
session.add(new_transaction)
|
||||||
|
session.commit()
|
||||||
|
return f"New transaction has been added: description: {description}, uuid: {transaction_id} ", 200
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#####################
|
||||||
|
### Administrator ###
|
||||||
|
#####################
|
||||||
|
|
||||||
|
def get_all_clients(): # Returns all clients in the database
|
||||||
|
clients = session.query(Client).all()
|
||||||
|
return jsonify([{"client_id": client.client_id, "name": client.name, "birthdate": client.birthdate, "opening_timestamp": client.opening_timestamp, "address": client.address, "phone_number": client.phone_number, "email": client.email} for client in clients])
|
||||||
|
|
||||||
|
def get_all_accounts(): # Returns all accounts in the database
|
||||||
|
accounts = session.query(Account).all()
|
||||||
|
return jsonify([{"account_id": account.account_id, "description": account.description, "open_timestamp": account.open_timestamp, "account_type": account.account_type, "balance": account.balance, "enabled": account.enabled, "notes": account.notes} for account in accounts])
|
||||||
|
|
||||||
|
def get_all_transactions(): # Returns all transactions in the database
|
||||||
|
transactions = session.query(Transaction).all()
|
||||||
|
return jsonify([{"transaction_id": transaction.transaction_id, "transaction_type": transaction.transaction_type, "amount": transaction.amount, "timestamp": transaction.timestamp, "description": transaction.description, "account_number": transaction.account_number, "recipient_account_number": transaction.recipient_account_number} for transaction in transactions])
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def update_transaction(transaction_id, transaction_type, amount, description, account_number, recipient_account_number):
|
||||||
|
for transaction in session.query(Transaction).all():
|
||||||
|
if transaction.transaction_id == transaction_id:
|
||||||
|
transaction.transaction_type = transaction_type
|
||||||
|
transaction.amount = amount
|
||||||
|
transaction.description = description
|
||||||
|
transaction.account_number = account_number
|
||||||
|
transaction.recipient_account_number = recipient_account_number
|
||||||
|
session.commit()
|
||||||
|
return f"Transaction ID: {transaction_id} has been updated."
|
||||||
|
return f"Transaction ID: {transaction_id} is not found."
|
||||||
|
|
||||||
|
def apply_interest(account_id:int, interest_rate:float):
|
||||||
|
for account in session.query(Account).filter(Account.account_id == account_id):
|
||||||
|
if account.account_id == account_id:
|
||||||
|
account.balance += account.balance * interest_rate
|
||||||
|
session.commit()
|
||||||
|
return f"Interest has been applied to Account ID: {account_id}."
|
||||||
|
return f"Account ID: {account_id} is not found."
|
||||||
|
|
||||||
|
def apply_fee(account_id:int, fee:float):
|
||||||
|
for account in session.query(Account).all():
|
||||||
|
if account.account_id == account_id:
|
||||||
|
account.balance -= fee
|
||||||
|
session.commit()
|
||||||
|
return f"Fee has been applied to Account ID: {account_id}."
|
||||||
|
return f"Account ID: {account_id} is not found."
|
||||||
|
|
||||||
|
def delete_transaction(transaction_id:int):
|
||||||
|
DELETE_TRANSACTION = "DELETE FROM transaction WHERE transaction_id=?"
|
||||||
|
from api import session, Transaction
|
||||||
|
for transaction in session.query(Transaction).all():
|
||||||
|
if transaction.transaction_id == transaction_id:
|
||||||
|
input(f"Are you sure you would like permanenty delete transaction ID: {transaction_id}? WARNING: This action can not be reversed. (Y/N) ")
|
||||||
|
if input == "Y"or input == "y":
|
||||||
|
session.execute(DELETE_TRANSACTION, (transaction_id))
|
||||||
|
print(f"Transaction ID: {transaction_id} has been removed.")
|
||||||
|
else:
|
||||||
|
return f"Transaction ID: {transaction_id} has NOT been removed."
|
||||||
|
return
|
||||||
|
return f"Transaction ID: {transaction_id} is not found."
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
flask
|
||||||
|
connexion[swagger-ui]==2.14.2
|
||||||
|
requests
|
||||||
|
sqlalchemy
|
||||||
Reference in New Issue
Block a user