diff --git a/.docker/database/initial_setup.sql b/.docker/database/initial_setup.sql index 8e315492e75d6f4bb91cd9b0e63c6269b8f09d0d..7e6ade3b29c581e67577a082bc5e1e287474117c 100644 --- a/.docker/database/initial_setup.sql +++ b/.docker/database/initial_setup.sql @@ -3,11 +3,11 @@ CREATE DATABASE "web-sec"; \c web-sec; CREATE TABLE "benutzer" ( - customerID SERIAL NOT NULL, + customerid SERIAL NOT NULL, vorname text NOT NULL, nachname text NOT NULL, email varchar(255) NOT NULL, - PRIMARY KEY(customerID) + PRIMARY KEY(customerid) ); INSERT INTO diff --git a/README.adoc b/README.adoc index cc2b416aac3c6f876862508c00442fea383c2ee5..5c74bd3a0595b12ed1f5086f228a13c9b95afb30 100644 --- a/README.adoc +++ b/README.adoc @@ -53,11 +53,13 @@ Die Routen sind Passwort geschützt. # passwort: admin ---- +* Dies kann via `curl --user admin:admin -X GET http://localhost:5000/benutzer/1` getestet werden. Ohne Zugangsdaten bekommt man ein `Unauthorized Access` zurück. + === GET * `http://localhost:5000/api/user/:customerID` ** Gibt die E-Mail Adresse eines Benutzers zurück - +*** `curl --user admin:admin -X GET http://localhost:5000/benutzer/1` === POST @@ -67,9 +69,19 @@ Die Routen sind Passwort geschützt. [source,bash] ---- { - "vorname":"max", - "nachname":"mustermann", - "email":"max@mustermann.net" +# Benutzer1 +curl http://localhost:5000/benutzer \ + --user admin:admin \ + -X POST \ + -H "Content-Type: application/json" \ + -d '{"vorname":"maxime", "nachname":"musterfrau", "email":"maxime@musterfrau.net"}' + +# Benutzer2 +curl http://localhost:5000/benutzer \ + --user admin:admin \ + -X POST \ + -H "Content-Type: application/json" \ + -d '{"vorname":"hans", "nachname":"meier", "email":"hans@meier.net"}' } ---- @@ -77,4 +89,6 @@ Die Routen sind Passwort geschützt. === DELETE * `http://localhost:5000/api/user/:customerID` -** Löscht einen Benutzer anhand seiner `customerID` \ No newline at end of file +** Löscht einen Benutzer anhand seiner `customerID` +*** `curl --user admin:admin -X DELETE http://localhost:5000/benutzer/1` + diff --git a/app/app.py b/app/app.py index 4834b42720f5203678c88d35aa6861562fd880e1..31a5b74cf5d8ec5a5a1652b97611ea71b6029a55 100644 --- a/app/app.py +++ b/app/app.py @@ -1,12 +1,64 @@ +from flask_migrate import Migrate +from models import db, Benutzer +#from sqlalchemy import create_engine +from flask_httpauth import HTTPBasicAuth +from sqlalchemy.orm.exc import NoResultFound +from werkzeug.security import generate_password_hash, check_password_hash +from flask import Flask, jsonify, request +from sqlalchemy import select import json -from flask import Flask + +auth = HTTPBasicAuth() app = Flask(__name__) +autorisierte_benutzer = { + "admin": generate_password_hash("admin") +} + +#engine = create_engine("postgresql://postgres:postgres@postgres:5432/web-sec",echo = True) +#conn = engine.connect() + +app.config['SQLALCHEMY_DATABASE_URI'] = "postgresql://postgres:postgres@postgres:5432/web-sec" +app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False + +db.init_app(app) +migrate = Migrate(app, db) + +@auth.verify_password +def verify_password(username, password): + if username in autorisierte_benutzer and \ + check_password_hash(autorisierte_benutzer.get(username), password): + return username @app.route('/') +@auth.login_required def index(): - return json.dumps({'name': 'alice', - 'email': 'alice@outlook.com'}) + return json.dumps({'Aufgabe1': 'Security of web applications'}) + +@app.route("/benutzer/<id>", methods=["GET"]) +@auth.login_required +def get_email(id): + benutzer_email = db.session.query(Benutzer.email).filter(Benutzer.customerid == id).first()[0] + return jsonify(email=benutzer_email) + +@app.route("/benutzer", methods=["POST"]) +@auth.login_required +def create_user(): + new_user = Benutzer( + vorname=request.json['vorname'], + nachname=request.json['nachname'], + email=request.json['email'] + ) + db.session.add(new_user) + db.session.commit() + return jsonify(benutzer=new_user) + +@app.route("/benutzer/<id>", methods=["DELETE"]) +@auth.login_required +def delete_user(id): + benutzer = db.session.query(Benutzer).filter(Benutzer.customerid == id).first()[0] + db.session.delete(benutzer) + db.session.commit() if __name__ == "__main__": - app.run() \ No newline at end of file + app.run(debug=True) \ No newline at end of file diff --git a/app/models.py b/app/models.py new file mode 100644 index 0000000000000000000000000000000000000000..9ae1883643b210b389a4ed7f92cb88f96ff0e2d1 --- /dev/null +++ b/app/models.py @@ -0,0 +1,20 @@ +from flask_sqlalchemy import SQLAlchemy + +db = SQLAlchemy() + +class Benutzer(db.Model): + + __tablename__ = 'benutzer' + + customerid = db.Column(db.Integer, primary_key = True) + vorname = db.Column(db.String()) + nachname = db.Column(db.Integer()) + email = db.Column(db.String(20)) + + def __init__(self, vorname, nachname, email): + self.vorname = vorname + self.nachname = nachname + self.email = email + + def __repr__(self): + return f"{self.customerID}:{self.vorname}:{self.nachname}:{self.email}" \ No newline at end of file diff --git a/docker-compose.yml b/docker-compose.yml index cae7187d2e42b4374044abea7a40913b83e88fce..280a2d9a868b6f749dfbcb236617f8db3d8f3c75 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -31,4 +31,8 @@ services: - database ports: - 5000:5000 + environment: + FLASK_DEBUG: 1 + volumes: + - "./app:/app" \ No newline at end of file diff --git a/requirements.txt b/requirements.txt index fb0dec5b667552bb10defa307c3deb82cf282eb0..b866d4f7ea983aeff0e410e87e1c769dc588b561 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1 +1,5 @@ -Flask==2.0.3 \ No newline at end of file +Flask==2.0.3 +psycopg2==2.9.3 +Flask-SQLAlchemy==2.5.1 +Flask-Migrate==3.1.0 +Flask-HTTPAuth==4.5.0 \ No newline at end of file