Skip to content

Commit fd9568b

Browse files
Add files via upload
1 parent e7f120e commit fd9568b

File tree

8 files changed

+419
-0
lines changed

8 files changed

+419
-0
lines changed

Dockerfile

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
FROM ghcr.io/oracle/oraclelinux:8
2+
3+
RUN yum install -y oracle-release-el8 \
4+
&& yum-config-manager --enable ol8_oracle_instantclient \
5+
&& yum install -y oracle-instantclient19.10-basic
6+
7+
8+
RUN dnf -y module disable python36 && \
9+
dnf -y module enable python39 && \
10+
dnf -y install python39 python39-pip python39-setuptools python39-wheel && \
11+
rm -rf /var/cache/dnf
12+
13+
RUN yum install -y postgresql-devel
14+
15+
RUN yum install -y gcc \
16+
&& yum install -y libaio-devel
17+
18+
ADD requirements.txt .
19+
COPY requirements.txt ./requirements.txt
20+
RUN pip3 install -r requirements.txt
21+
22+
23+
# Set the environment variable for LD_LIBRARY_PATH
24+
ENV LD_LIBRARY_PATH /usr/lib/oracle/19.10/client64/lib/
25+
26+
ADD main.py .
27+
28+
ADD key.pem .
29+
30+
ADD cert.pem .
31+
32+
ADD add_employee.html .
33+
34+
ADD get_employees.html .
35+
36+
ADD update_employee.html .
37+
38+
ADD confirm_delete_employee.html .
39+
40+
ADD crud_options.html .
41+
42+
ADD search_employee.html .
43+
44+
ADD employee_not_found.html .
45+
46+
CMD ["python3", "./main.py"]

add_employee.html

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
<!-- Use Bootstrap for styling -->
2+
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css">
3+
4+
<!-- Create a banner -->
5+
<div class="jumbotron">
6+
<h1 class="display-4">Employee Management System</h1>
7+
<p class="lead">Add new employees to the system</p>
8+
</div>
9+
10+
<!-- Use a container to center the form -->
11+
<div class="container">
12+
<form action="/api/add_employee" method="post">
13+
<div class="form-group">
14+
<label for="name">Name:</label>
15+
<input type="text" class="form-control" id="name" name="name" required>
16+
</div>
17+
<div class="form-group">
18+
<label for="email">Email:</label>
19+
<input type="email" class="form-control" id="email" name="email" required>
20+
</div>
21+
<div class="form-group">
22+
<label for="department">Department:</label>
23+
<input type="text" class="form-control" id="department" name="department" required>
24+
</div>
25+
<button type="submit" class="btn btn-primary">Add Employee</button>
26+
</form>
27+
</div>

cleanup.sql

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
-- Cleanup
2+
drop table employees;
3+
drop table employees_salary;
4+
drop procedure generate_employees_salary;
5+
drop procedure add_employees;

crud_options.html

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
<!DOCTYPE html>
2+
<html>
3+
<head>
4+
<title>EMS Main Page</title>
5+
<!-- Use Bootstrap for styling -->
6+
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css">
7+
<script>
8+
function updateEmployee() {
9+
var id = prompt("Enter ID:");
10+
if (id != null) {
11+
window.location.href = "/api/update_employee/" + id;
12+
}
13+
}
14+
15+
function deleteEmployee() {
16+
var id = prompt("Enter ID:");
17+
if (id != null) {
18+
window.location.href = "/api/delete_employee/" + id;
19+
}
20+
}
21+
22+
function searchEmployee() {
23+
var id = prompt("Enter ID:");
24+
if (id != null) {
25+
window.location.href = "/api/search_employee/" + id;
26+
}
27+
}
28+
</script>
29+
</head>
30+
<body>
31+
<!-- Create a banner -->
32+
<div class="jumbotron">
33+
<h1 class="display-4">Employee Management System</h1>
34+
<p class="lead">Select an Employee Operation to Perform</p>
35+
</div>
36+
37+
<!-- Use a container to center the form -->
38+
<div class="container">
39+
<div class="row">
40+
<div class="col-md-3">
41+
<a href="{{ url_for('add_employee_form') }}" class="btn btn-primary btn-block">Create</a>
42+
</div>
43+
<div class="col-md-3">
44+
<a href="{{ url_for('get_all') }}" class="btn btn-primary btn-block">Read</a>
45+
</div>
46+
<div class="col-md-3">
47+
<button class="btn btn-primary btn-block" onclick="updateEmployee()">Update</button>
48+
</div>
49+
<div class="col-md-3">
50+
<button class="btn btn-primary btn-block" onclick="deleteEmployee()">Delete</button>
51+
</div>
52+
</div>
53+
<div class="row mt-3">
54+
<div class="col-md-3">
55+
<button class="btn btn-primary btn-block" onclick="searchEmployee()">Search</button>
56+
</div>
57+
</div>
58+
</div>
59+
</body>
60+
</html>
61+

crud_options.html.bak

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
<!DOCTYPE html>
2+
<html>
3+
<head>
4+
<title>EMS Main Page</title>
5+
<!-- Use Bootstrap for styling -->
6+
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css">
7+
<script>
8+
function updateEmployee() {
9+
var id = prompt("Enter ID:");
10+
if (id != null) {
11+
window.location.href = "/api/update_employee/" + id;
12+
}
13+
}
14+
15+
function deleteEmployee() {
16+
var id = prompt("Enter ID:");
17+
if (id != null) {
18+
window.location.href = "/api/delete_employee/" + id;
19+
}
20+
}
21+
22+
function searchEmployee() {
23+
var id = prompt("Enter ID:");
24+
if (id != null) {
25+
window.location.href = "/api/search_employee/" + id;
26+
}
27+
}
28+
</script>
29+
</head>
30+
<body>
31+
<!-- Create a banner -->
32+
<div class="jumbotron">
33+
<h1 class="display-4">Employee Management System</h1>
34+
<p class="lead">Select an Employee Operation to Perform</p>
35+
</div>
36+
37+
<!-- Use a container to center the form -->
38+
<div class="container">
39+
<div class="d-flex flex-column justify-content-start">
40+
<div class="mb-2">
41+
<a href="{{ url_for('add_employee_form') }}" class="btn btn-primary btn-block mr-2">Create</a>
42+
<a href="{{ url_for('get_all') }}" class="btn btn-primary btn-block mr-2">Read</a>
43+
</div>
44+
<div class="mb-2">
45+
<button class="btn btn-primary btn-block mr-2" onclick="updateEmployee()">Update</button>
46+
<button class="btn btn-primary btn-block mr-2" onclick="deleteEmployee()">Delete</button>
47+
</div>
48+
<div class="mb-2">
49+
<button class="btn btn-primary btn-block mr-2" onclick="searchEmployee()">Search</button>
50+
</div>
51+
</div>
52+
</div>
53+
</body>
54+
</html>
55+

employee_not_found.html

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
<!DOCTYPE html>
2+
<html>
3+
<head>
4+
<title>Employee Not Found</title>
5+
<!-- Use Bootstrap for styling -->
6+
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css">
7+
</head>
8+
<body>
9+
<!-- Create a banner -->
10+
<div class="jumbotron">
11+
<h1 class="display-4">Employee Management System</h1>
12+
<p class="lead">Employee Not Found</p>
13+
</div>
14+
15+
<!-- Use a container to center the message -->
16+
<div class="container">
17+
<p>The employee with ID {{ id }} could not be found.</p>
18+
<a href="{{ url_for('search_employee') }}" class="btn btn-primary">Back to Search</a>
19+
</div>
20+
</body>
21+
</html>
22+

main.py

Lines changed: 167 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,167 @@
1+
import os
2+
import flask
3+
from flask import Flask, jsonify, request
4+
from flask import render_template
5+
from flask_cors import CORS
6+
from flask import session, redirect, url_for, request, Response
7+
import oracledb
8+
9+
# Environment Variables for Oracle Database Connectivity
10+
user = os.environ['ORACLE_USER']
11+
password = os.environ['ORACLE_PASSWORD']
12+
dsn = os.environ['ORACLE_DSN']
13+
14+
app = Flask(__name__, template_folder='/')
15+
CORS(app)
16+
17+
# List of API User and Auth Token
18+
VALID_USERS = {'user1': 'password1', 'user2': 'password2'}
19+
20+
# Connect to the Oracle database
21+
con = oracledb.connect(user=user, password=password, dsn=dsn)
22+
23+
# HTML Form Method to Create a New Employee
24+
@app.route('/api/add_employee', methods=['GET', 'POST'])
25+
def add_employee_form():
26+
# Require authentication for all requests
27+
auth = request.authorization
28+
if not auth or not check_auth(auth.username, auth.password):
29+
return authenticate()
30+
31+
if request.method == 'POST':
32+
# Extract the employee data from the form
33+
name = request.form['name']
34+
email = request.form['email']
35+
department = request.form['department']
36+
37+
# Insert the employee into the database
38+
cur = con.cursor()
39+
cur.execute("INSERT INTO employees (name, email, department) VALUES (:name, :email, :department)",
40+
{'name': name, 'email': email, 'department': department})
41+
con.commit()
42+
43+
# Return the ID of the new employee
44+
return redirect(url_for('get_all'))
45+
else:
46+
return render_template('add_employee.html')
47+
48+
49+
# HTML Method to Get a List of All Employees
50+
@app.route('/api/getall')
51+
def get_all():
52+
# Require authentication for all requests
53+
auth = request.authorization
54+
if not auth or not check_auth(auth.username, auth.password):
55+
return authenticate()
56+
57+
cur = con.cursor()
58+
cur.prefetchrows = 100
59+
cur.arraysize = 100
60+
cur.execute("SELECT * FROM employees")
61+
rows = cur.fetchall()
62+
employees = []
63+
for row in rows:
64+
employee = {'id': row[0], 'name': row[1], 'email': row[2], 'department': row[3]}
65+
employees.append(employee)
66+
return render_template('get_employees.html', employees=employees)
67+
68+
69+
# HTML Method to Update en Employee
70+
@app.route('/api/update_employee/<int:id>', methods=['GET','POST'])
71+
def update_employee(id):
72+
73+
# Require authentication for all requests
74+
auth = request.authorization
75+
if not auth or not check_auth(auth.username, auth.password):
76+
return authenticate()
77+
78+
cur = con.cursor()
79+
if request.method == 'POST':
80+
name = request.form['name']
81+
email = request.form['email']
82+
department = request.form['department']
83+
cur.execute('UPDATE employees SET name=:name, email=:email, department=:department WHERE id=:id',
84+
{'name': name, 'email': email, 'department': department, 'id': id})
85+
con.commit()
86+
cur.close()
87+
return redirect(url_for('get_all'))
88+
else:
89+
cur.execute('SELECT * FROM employees WHERE id=:id', {'id': id})
90+
employee = cur.fetchone()
91+
cur.close()
92+
return render_template('update_employee.html', employee=employee)
93+
94+
95+
# HTML Method to Delete an Employee
96+
@app.route('/api/delete_employee/<int:id>', methods=['GET', 'POST'])
97+
def delete_employee(id):
98+
# Require authentication for all requests
99+
auth = request.authorization
100+
if not auth or not check_auth(auth.username, auth.password):
101+
return authenticate()
102+
103+
if request.method == 'POST':
104+
cur = con.cursor()
105+
cur.execute('DELETE FROM employees WHERE id=:id', {'id': id})
106+
con.commit()
107+
cur.close()
108+
return redirect(url_for('get_all'))
109+
else:
110+
cur = con.cursor()
111+
cur.execute('SELECT * FROM employees WHERE id=:id', {'id': id})
112+
employee = cur.fetchone()
113+
cur.close()
114+
return render_template('confirm_delete_employee.html', employee=employee)
115+
116+
# Main Page for Listing All Methods
117+
@app.route('/api/main', methods=['GET'])
118+
def crud_options():
119+
# Require authentication for all requests
120+
auth = request.authorization
121+
if not auth or not check_auth(auth.username, auth.password):
122+
return authenticate()
123+
124+
return render_template('crud_options.html')
125+
126+
# HTML Method to Search for an Employee by ID
127+
@app.route('/api/search_employee/<int:id>', methods=['GET', 'POST'])
128+
def search_employee(id):
129+
# Require authentication for all requests
130+
auth = request.authorization
131+
if not auth or not check_auth(auth.username, auth.password):
132+
return authenticate()
133+
134+
if request.method == 'POST':
135+
cur = con.cursor()
136+
cur.execute('SELECT * FROM employees WHERE id=:id', {'id': id})
137+
employee = cur.fetchone()
138+
cur.close()
139+
140+
if employee is None:
141+
# Display a message if the employee is not found
142+
return render_template('employee_not_found.html', id=id)
143+
else:
144+
# Display the employee details if found
145+
return render_template('search_employee.html', employee=employee)
146+
else:
147+
# Create an empty employee object if a GET request is received
148+
return render_template('search_employee.html', employee=None)
149+
150+
151+
def check_auth(username, password):
152+
"""Check if a username/password combination is valid."""
153+
return username in VALID_USERS and password == VALID_USERS[username]
154+
155+
def authenticate():
156+
"""Send a 401 Unauthorized response that prompts the user to authenticate."""
157+
return Response('Could not verify your access level for that URL.\n'
158+
'You have to login with proper credentials', 401,
159+
{'WWW-Authenticate': 'Basic realm="Login Required"'})
160+
161+
if __name__ == '__main__':
162+
# Print out all the routes and their associated URLs
163+
for rule in app.url_map.iter_rules():
164+
print(f"{rule.endpoint:50s} {rule.methods} {rule.rule}")
165+
166+
# Start the HTTPS server
167+
app.run(host='0.0.0.0', port=4443, ssl_context=('cert.pem', 'key.pem'))

0 commit comments

Comments
 (0)