From 47e898713958b094ce885d9649da4064936a15cb Mon Sep 17 00:00:00 2001
From: Mart van Santen <mart@greenhost.nl>
Date: Fri, 19 Nov 2021 12:07:24 +0100
Subject: [PATCH] Removed old panels and update gitlab ci to stop building
 those

---
 .gitlab-ci.yml                                |  33 ------
 .gitmodules                                   |   3 -
 consent_provider/Dockerfile                   |  22 ----
 consent_provider/app.py                       |  67 -----------
 consent_provider/db.py                        |  84 --------------
 consent_provider/requirements.txt             |   3 -
 consent_provider/templates/base.html          |  11 --
 consent_provider/templates/consent.html       |  15 ---
 docker-compose.yml                            |  29 -----
 ...al_dev_remote_kratos.md => development.md} |   0
 docs/index.rst                                |   8 +-
 docs/usage.md                                 |  28 -----
 login_provider/.envrc.example                 |   6 -
 login_provider/Dockerfile                     |  20 ----
 login_provider/README.md                      |  22 ----
 login_provider/app.py                         | 106 ------------------
 login_provider/db.py                          |  76 -------------
 login_provider/forms.py                       |  10 --
 login_provider/requirements.txt               |   7 --
 login_provider/templates/login.html           |  18 ---
 login_provider/templates/skip.html            |  14 ---
 logout_provider/Dockerfile                    |  22 ----
 logout_provider/app.py                        |  44 --------
 logout_provider/requirements.txt              |   2 -
 user-panel                                    |   1 -
 25 files changed, 4 insertions(+), 647 deletions(-)
 delete mode 100644 consent_provider/Dockerfile
 delete mode 100644 consent_provider/app.py
 delete mode 100644 consent_provider/db.py
 delete mode 100644 consent_provider/requirements.txt
 delete mode 100644 consent_provider/templates/base.html
 delete mode 100644 consent_provider/templates/consent.html
 rename docs/{local_dev_remote_kratos.md => development.md} (100%)
 delete mode 100644 docs/usage.md
 delete mode 100644 login_provider/.envrc.example
 delete mode 100644 login_provider/Dockerfile
 delete mode 100644 login_provider/README.md
 delete mode 100644 login_provider/app.py
 delete mode 100644 login_provider/db.py
 delete mode 100644 login_provider/forms.py
 delete mode 100644 login_provider/requirements.txt
 delete mode 100644 login_provider/templates/login.html
 delete mode 100644 login_provider/templates/skip.html
 delete mode 100644 logout_provider/Dockerfile
 delete mode 100644 logout_provider/app.py
 delete mode 100644 logout_provider/requirements.txt
 delete mode 160000 user-panel

diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index a4e8cbb..b43d4df 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -9,39 +9,6 @@ stages:
   - application-test
   - integration-test
 
-consent_provider:
-  stage: build
-  variables:
-    KANIKO_CONTEXT: "consent_provider"
-    KANIKO_BUILD_IMAGENAME: $CI_JOB_NAME
-  extends: .kaniko_build
-  only:
-    changes:
-      - consent_provider/**/*
-      - .gitlab-ci.yml
-
-logout_provider:
-  stage: build
-  variables:
-    KANIKO_CONTEXT: "logout_provider"
-    KANIKO_BUILD_IMAGENAME: $CI_JOB_NAME
-  extends: .kaniko_build
-  only:
-    changes:
-      - logout_provider/**/*
-      - .gitlab-ci.yml
-
-login_provider:
-  stage: build
-  variables:
-    KANIKO_CONTEXT: "login_provider"
-    KANIKO_BUILD_IMAGENAME: $CI_JOB_NAME
-  extends: .kaniko_build
-  only:
-    changes:
-      - login_provider/**/*
-      - .gitlab-ci.yml
-
 integration_test_app:
   stage: build-test-images
   variables:
diff --git a/.gitmodules b/.gitmodules
index 88b746c..e69de29 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -1,3 +0,0 @@
-[submodule "user-panel"]
-	path = user-panel
-	url = https://open.greenhost.net/stackspin/user-panel.git
diff --git a/consent_provider/Dockerfile b/consent_provider/Dockerfile
deleted file mode 100644
index 7d5437e..0000000
--- a/consent_provider/Dockerfile
+++ /dev/null
@@ -1,22 +0,0 @@
-FROM python:3.9-alpine
-
-RUN apk add gcc libc-dev libffi-dev
-
-WORKDIR /usr/src/app
-
-COPY requirements.txt ./
-RUN pip install --no-cache-dir -r requirements.txt
-
-COPY . .
-
-ARG FLASK_PORT=5001
-
-EXPOSE $FLASK_PORT
-
-ENV FLASK_ENV production
-ENV FLASK_RUN_PORT $FLASK_PORT
-ENV FLASK_RUN_HOST 0.0.0.0
-ENV HYDRA_ADMIN_URL http://localhost:4445
-
-
-CMD [ "flask", "run" ]
diff --git a/consent_provider/app.py b/consent_provider/app.py
deleted file mode 100644
index 95a49f7..0000000
--- a/consent_provider/app.py
+++ /dev/null
@@ -1,67 +0,0 @@
-from flask import abort, Flask, redirect, request
-from flask.views import View
-from os import urandom, environ
-from hydra_client import HydraAdmin
-import hydra_client
-from db import User, BackendConnectionError
-import logging
-
-HYDRA_ADMIN_URL = environ['HYDRA_ADMIN_URL']
-HYDRA = HydraAdmin(HYDRA_ADMIN_URL)
-
-app = Flask(__name__)
-app.logger.setLevel(logging.INFO)
-
-@app.route('/consent', methods=['GET'])
-def home():
-    """Checks user app permission
-
-    Checks user app permission by loading a consent object via the Hydra admin API and
-    validating that the user triggering the request has sufficient permissions by querying
-    the GraphQL API. If the user is allowed to use the app the request is accepted and openID
-    claims are sent to Hydra.
-
-    Args:
-        consent_challenge: Reference to a consent challenge object in form of an alphanumeric
-            String. Can be used to retrieve the consent challenge object via the Hydra Admin API (GET)
-
-    Returns:
-        Redirect to the url that is provided by the consent challenge object.
-    """
-    challenge = request.args.get("consent_challenge")
-    if not challenge:
-        abort(403)
-    try:
-        consent_request = HYDRA.consent_request(challenge)
-    except hydra_client.exceptions.NotFound:
-        app.logger.error("Not Found. Consent request not found. challenge={0}".format(challenge))
-        abort(404)
-    except hydra_client.exceptions.HTTPError:
-        app.logger.error("Conflict. Consent request has been used already. challenge={0}".format(challenge))
-        abort(503)
-    app_name = consent_request.client.client_name
-    username = consent_request.subject
-    try:
-        user = User(username)
-    except BackendConnectionError as error:
-        app.logger.error(
-            "Retrieving user object from GraphQL server failed {0}".format(error))
-        return redirect(consent_request.reject(
-            "Permission denied",
-            error_description="Login request was denied due to an internal server error"))
-    access_granted = user.has_app_permission(app_name)
-    if access_granted:
-        app.logger.info("{0} was granted access to {1}".format(username, app_name))
-        session = user.get_oauth_session()
-        return redirect(consent_request.accept(
-            grant_scope=consent_request.requested_scope,
-            grant_access_token_audience=consent_request.requested_access_token_audience,
-            session=session,
-            ))
-    app.logger.info("{0} was denied access to {1}".format(username, app_name))
-    return redirect(consent_request.reject(
-        "Permission denied",
-        error_description="Login request was denied due to missing application permission"))
-
-if __name__ == '__main__':
-    app.run()
diff --git a/consent_provider/db.py b/consent_provider/db.py
deleted file mode 100644
index fa994ef..0000000
--- a/consent_provider/db.py
+++ /dev/null
@@ -1,84 +0,0 @@
-from os import environ
-from hydra_client import HydraAdmin
-from graphqlclient import GraphQLClient
-import urllib
-import json
-
-GRAPHQL_URL = environ['GRAPHQL_URL']
-GRAPHQL_CLIENT = GraphQLClient(GRAPHQL_URL)
-
-
-class User():
-    def __init__(self, username):
-        self.username = username
-        try:
-            self._load_remote_user_info()
-        except urllib.error.HTTPError as error:
-            raise BackendConnectionError(
-                error.code,
-                error.headers,
-                ("Error during retrieval of userdata - " + error.reason))
-
-    def _load_remote_user_info(self):
-        querystring = '''{{
-        getUser(username: "{0}"){{
-            email,
-            applications{{
-                edges{{
-                    node{{
-                        name
-                    }}
-                }}
-            }},
-            roles{{
-                edges{{
-                    node{{
-                        name
-                    }}
-                }}
-            }}
-        }}}}'''.format(self.username)
-        result = json.loads(GRAPHQL_CLIENT.execute(querystring))
-        data = result["data"]["getUser"]
-        self.applications = list(map(lambda x: x["node"]["name"],
-                                     data["applications"]["edges"]))
-        self.roles = list(map(lambda x: x["node"]["name"],
-                                     data["roles"]["edges"]))
-        self.email = data["email"]
-
-    def has_app_permission(self, appname):
-        return appname in self.applications
-
-    def get_oauth_session(self):
-        """Create openID Connect token
-
-        Use the userdata stored in the user object to create an OpenID Connect token.
-        The token will be passed to Hydra, which will store it and serve it to all OpenID Connect
-        Clients, that successfully query the /userinfo endpoint. Every field in the "id_token"
-        dictionary can be accessed through standard scopes and claims.
-        See https://openid.net/specs/openid-connect-core-1_0.html#Claims
-
-        Returns:
-            OpenID Connect token of type dict
-        """
-        return {
-            "id_token": {
-                "name": self.username,
-                "preferred_username": self.username,
-                "email" : self.email,
-                "stackspin_roles": self.roles}
-        }
-
-
-class BackendConnectionError(Exception):
-    """Raised when requests to the backend server fail
-
-    Attributes:
-        code -- http response code
-        headers -- http response headers
-        reason -- reson for the error
-    """
-    def __init__(self, code, headers, reason):
-        self.code = code
-        self.headers = headers
-        self.reason = reason
diff --git a/consent_provider/requirements.txt b/consent_provider/requirements.txt
deleted file mode 100644
index 00c8039..0000000
--- a/consent_provider/requirements.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-Flask
-hydra-client
-graphqlclient
diff --git a/consent_provider/templates/base.html b/consent_provider/templates/base.html
deleted file mode 100644
index 26e9f45..0000000
--- a/consent_provider/templates/base.html
+++ /dev/null
@@ -1,11 +0,0 @@
-<!DOCTYPE html>
-<html lang="en">
-<head>
-  <title>{%block title %}python-login-consent{% endblock %}</title>
-</head>
-<body>
-  {% block content %}
-  <h1>Welcome to the Python login/consent app for Hydra</h1>
-  {% endblock %}
-</body>
-</html>
diff --git a/consent_provider/templates/consent.html b/consent_provider/templates/consent.html
deleted file mode 100644
index db91dd3..0000000
--- a/consent_provider/templates/consent.html
+++ /dev/null
@@ -1,15 +0,0 @@
-{% extends "base.html" %}
-{% block title %}Consent{% endblock %}
-
-{% block content %}
-<dl>
-  <dt>User</dt>
-  <dd>{{ user }}</dd>
-  <dt>Client</dt>
-  <dd>{{ client }}</dd>
-</dl>
-<form method="POST" action="/consent">
-    {{ form.hidden_tag() }}
-    {{ form.accept }}
-</form>
-{% endblock %}
diff --git a/docker-compose.yml b/docker-compose.yml
index 76747c6..2b72fd2 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -27,23 +27,6 @@ services:
       - LOG_LEVEL=debug
       - LOG_LEAK_SENSITIVE_VALUES=true
     restart: unless-stopped
-  consent:
-    build: consent_provider/
-    environment:
-      - HYDRA_ADMIN_URL=http://hydra:4445
-      - GRAPHQL_URL=http://backend:5000/graphql
-      - FLASK_ENV=development
-    ports:
-      - "5001:5001"
-    restart: unless-stopped
-  logout:
-    build: logout_provider/
-    environment:
-      - HYDRA_ADMIN_URL=http://hydra:4445
-      - FLASK_ENV=development
-    ports:
-      - "5002:5002"
-    restart: unless-stopped
   login:
     build: login_provider/
     environment:
@@ -53,18 +36,6 @@ services:
     ports:
       - "5000:5000"
     restart: unless-stopped
-  backend:
-    build: user-panel/backend/
-    environment:
-      - DEBUG=True
-      - HYDRA_ADMIN_URL=http://hydra:4445
-      - DATABASE_USER=postgres
-      - DATABASE_PASSWORD=secret
-      - DATABASE_NAME=postgres
-      - DATABASE_HOST=psql
-    ports:
-      - "5003:5000"
-    restart: unless-stopped
   psql:
     image: postgres:11
     environment:
diff --git a/docs/local_dev_remote_kratos.md b/docs/development.md
similarity index 100%
rename from docs/local_dev_remote_kratos.md
rename to docs/development.md
diff --git a/docs/index.rst b/docs/index.rst
index 8b46d87..c446f44 100644
--- a/docs/index.rst
+++ b/docs/index.rst
@@ -7,13 +7,13 @@ Welcome to single-sign-on's documentation!
 ==========================================
 
 This project provides a single sign on solution based on
-[hydra](https://github.com/ory/hydra) and in combination with a [user
-panel](https://open.greenhost.net/stackspin/user-panel).
+[hydra](https://github.com/ory/hydra), [kratos](https://github.com/ory/kratos) 
+and in combination with a [login panel](https://open.greenhost.net/stackspin/single-sign-on).
 
 .. toctree::
    :maxdepth: 2
    :caption: Contents:
 
-   usage
    helmchart
-   local_development
+   development
+
diff --git a/docs/usage.md b/docs/usage.md
deleted file mode 100644
index 2d7c5cb..0000000
--- a/docs/usage.md
+++ /dev/null
@@ -1,28 +0,0 @@
-# Usage
-
-## Installlation instructions
-
-Clone the repo  and make sure to also fetch the submodules.
-```
-git submodule update --init
-```
-
-Installation should be done via the helm using the helmchart contained in
-`./helmchart`.  Make sure to edit the values in
-`./helmchart/single-sign-on/values.yaml` according to your needs. To install the
-helm chart, make sure Helm is properly set up in your Kubernetes cluster, then:
-
-```
-cd helmchart        # Enter the helm chart directory
-helm dep update     # Download helm charts this chart relies on
-helm install .      # Run the installation command
-```
-
-For Details on how to configure the chart. Refer to [the Helm chart
-chapter](helmchart)
-
-### Managing users
-
-`single-sign-on` includese a simple `user-panel` to manage users. To read more
-about this, see the [user panel
-documentation](https://docs.stackspin.net/projects/user-panel/)
diff --git a/login_provider/.envrc.example b/login_provider/.envrc.example
deleted file mode 100644
index 54c318b..0000000
--- a/login_provider/.envrc.example
+++ /dev/null
@@ -1,6 +0,0 @@
-export FLASK_SECRET_KEY="CHANGEME"
-export FLASK_RUN_HOST="0.0.0.0"
-export FLASK_RUN_PORT="5000"
-export GRAPHQL_URL="http://localhost:5002/graphql"
-export HYDRA_ADMIN_URL="http://localhost:4445"
-export FLASK_ENV=development
diff --git a/login_provider/Dockerfile b/login_provider/Dockerfile
deleted file mode 100644
index 8c70d93..0000000
--- a/login_provider/Dockerfile
+++ /dev/null
@@ -1,20 +0,0 @@
-FROM python:3.9-alpine
-
-RUN apk add gcc libc-dev libffi-dev g++
-
-WORKDIR /usr/src/app
-
-COPY requirements.txt ./
-RUN pip install --no-cache-dir -r requirements.txt
-
-COPY . .
-
-EXPOSE 5000
-
-ENV FLASK_ENV production
-ENV FLASK_RUN_HOST 0.0.0.0
-ENV FLASK_RUN_PORT 5000
-ENV HYDRA_ADMIN_URL http://localhost:4445
-ENV GRAPHQL_URL http://localhost:5002/graphql
-
-CMD [ "flask", "run" ]
diff --git a/login_provider/README.md b/login_provider/README.md
deleted file mode 100644
index f04d92e..0000000
--- a/login_provider/README.md
+++ /dev/null
@@ -1,22 +0,0 @@
-# Configuration
-
-To enable the `debug` mode, set the environment variable `FLASK_ENV` to `development`.
-
-```
-export FLASK_ENV=development
-# or
-docker login-provider:latest build . && docker run -e FLASK_ENV=development login-provider
-```
-
-You can do the same with the following variables.
-
- * **FLASK_SECRET_KEY** A secret key that will be used for securely signing the session cookie.
- * **FLASK_RUN_HOST** IP Address that the server will open a socket on.
-   *Default*: 0.0.0.0
- * **FLASK_RUN_PORT** Port of the socket that the server will listen on.
-   *Default*: 5000
- * **GRAPHQL_URL** URL to the server that runs the graphql backend API
-   *Default*: http://localhost:5002/graphql
- * **HYDRA_ADMIN_URL** URl to the Hydra admin server
-   *Default*: http://localhost:4445
-   
diff --git a/login_provider/app.py b/login_provider/app.py
deleted file mode 100644
index 67ccce1..0000000
--- a/login_provider/app.py
+++ /dev/null
@@ -1,106 +0,0 @@
-from flask import abort, Flask, redirect, request, render_template
-from os import urandom, environ
-from hydra_client import HydraAdmin
-import hydra_client
-from db import User, BackendConnectionError
-from forms import LoginForm
-import logging
-
-HYDRA_ADMIN_URL = environ['HYDRA_ADMIN_URL']
-HYDRA = HydraAdmin(HYDRA_ADMIN_URL)
-
-app = Flask(__name__)
-app.config['SECRET_KEY'] = urandom(16)
-app.debug = True if "FLASK_ENV" in environ and environ["FLASK_ENV"] == "development" else False
-app.logger.setLevel(logging.INFO)
-
-@app.route('/login', methods=['GET', 'POST'])
-def login():
-    """Provides login form and handles login attempt
-
-    Args:
-        login_form: contains login data submitted by a user (POST)
-        challenge: id that identifies the request from oauth client. passed by hydra
-
-    Returns:
-        Error page if no challenge id is present
-        or Login Form if user hasn't authenticated
-        or redirect to callback url provided by hydra if login was successful
-    """
-    login_form = LoginForm()
-    redirect_to = None
-
-    # Retrieve the challenge id from the request. Depending on the method it is saved in the
-    # form (POST) or in a GET variable.
-    if request.method == 'GET':
-        challenge = request.args.get("login_challenge")
-        if not challenge:
-            return abort(400)
-    elif login_form.validate_on_submit():
-        challenge = login_form.challenge.data
-
-    # Now that we have the challenge id, we can request the challenge object from the hydra
-    # admin API
-    try:
-        login_request = HYDRA.login_request(challenge)
-    except hydra_client.exceptions.NotFound:
-        app.logger.error("Not Found. Login request not found. challenge={0}".format(challenge))
-        abort(404)
-    except hydra_client.exceptions.HTTPError:
-        app.logger.error("Conflict. Login request has been used already. challenge={0}".format(challenge))
-        abort(503)
-
-    # We need to decide here whether we want to accept or decline the login request.
-    # if a login form was submitted, we need to confirm that the userdata, the agent
-    # send us via POST is valid
-    if login_form.validate_on_submit():
-        try:
-            user = User(login_form.username.data)
-        except BackendConnectionError as error:
-            app.logger.error(
-                "Retrieving user object from GraphQL server failed {0}".format(error))
-            return redirect(login_request.reject(
-                "Login denied",
-                error_description="Login request was denied due to an internal server error"))
-        if user.authenticate(login_form.password.data):
-            redirect_to = login_request.accept(
-                user.username,
-                remember=login_form.remember.data,
-                # Remember session for 12h
-                remember_for=60*60*12)
-            app.logger.info("{0} logged in successfully".format(user.username))
-        else:
-            redirect_to = login_request.reject(
-                "Login denied",
-                error_description="Invalid username or password")
-            app.logger.info("{0} failed to login".format(user.username))
-        return redirect(redirect_to)
-
-    # Skip, if true, let's us know that Hydra has already successfully authenticated
-    # the user. we don't need to check anything and we can accept the request right away.
-    elif login_request.skip:
-        skip = request.args.get("skip")
-        logout = request.args.get("logout")
-        if skip:
-            app.logger.info("{0} is already logged in. Skip authentication".format(login_request.subject))
-            return redirect(login_request.accept(login_request.subject))
-        elif logout:
-            login_form.challenge.data = challenge
-            HYDRA.invalidate_login_sessions(login_request.subject);
-            return redirect(login_request.reject(
-                "Login cancelled",
-                error_description="Login was cancelled and user session was terminated"))
-        else:
-            return render_template('skip.html', challenge=challenge, logo=login_request.client.logo_uri, application_name=login_request.client.client_name, username=login_request.subject)
-
-
-
-    # If Skip is not true and the user has not submitted any data via a form, we need
-    # to display a login form for the user to type in their username and password.
-    # as a reference we save the challenge id in a hidden field of the form.
-    else:
-        login_form.challenge.data = challenge
-        return render_template('login.html', login_form=login_form, logo=login_request.client.logo_uri, application_name=login_request.client.client_name)
-
-if __name__ == '__main__':
-    app.run()
diff --git a/login_provider/db.py b/login_provider/db.py
deleted file mode 100644
index bf4de35..0000000
--- a/login_provider/db.py
+++ /dev/null
@@ -1,76 +0,0 @@
-from os import environ
-from hydra_client import HydraAdmin
-from flask_login import UserMixin
-from graphqlclient import GraphQLClient
-import urllib
-import json
-
-GRAPHQL_URL = environ['GRAPHQL_URL']
-graphql_client = GraphQLClient(GRAPHQL_URL)
-
-
-class User(UserMixin):
-    def __init__(self, username):
-        self.id = username
-        self.username = username
-        self.active = False
-        try:
-            self._load_remote_user_info()
-        except urllib.error.HTTPError as error:
-            raise BackendConnectionError(
-                error.code,
-                error.headers,
-                ("Error during retrieval of userdata - " + error.reason))
-
-    def _load_remote_user_info(self):
-        """Loads userdata from remote GraphQL API"""
-        querystring = '''{{
-        getUser(username: "{0}"){{
-            email,
-            active
-            }}}}'''.format(self.username)
-        result = json.loads(graphql_client.execute(querystring))
-        if "data" in result and result["data"]["getUser"] is not None:
-            self.active = result["data"]["getUser"]["active"]
-            self.email = result["data"]["getUser"]["email"]
-
-    def _verify_password(self, password):
-        """Verifies cleartext password
-
-        Sends the cleartext `password` to the GraphQL API
-        which verifies the password by hashing it and comparing it to a stored password
-        hash.
-
-        Args:
-            password: cleartext password
-
-        Returns:
-            Boolean result of password verification
-        """
-        password = password.replace('"', '\\"')
-        querystring = '''{{
-        verifyPassword(
-            username: "{0}",
-            password: "{1}")
-            }}'''.format(self.username, password)
-        result = json.loads(graphql_client.execute(querystring))
-        verified = False
-        if "data" in result:
-            verified = result["data"]["verifyPassword"]
-        return verified
-
-    def authenticate(self, password):
-        return self.active and self._verify_password(password)
-
-class BackendConnectionError(Exception):
-    """Raised when requests to the backend server fail
-
-    Attributes:
-        code -- http response code
-        headers -- http response headers
-        reason -- reson for the error
-    """
-    def __init__(self, code, headers, reason):
-        self.code = code
-        self.headers = headers
-        self.reason = reason
diff --git a/login_provider/forms.py b/login_provider/forms.py
deleted file mode 100644
index ed80ed0..0000000
--- a/login_provider/forms.py
+++ /dev/null
@@ -1,10 +0,0 @@
-from wtforms import SubmitField, StringField, PasswordField, BooleanField,  HiddenField, validators
-from flask_wtf import FlaskForm
-
-
-class LoginForm(FlaskForm):
-    username = StringField("Username", validators=[validators.input_required()],)
-    password = PasswordField("Password", validators=[validators.input_required()])
-    challenge = HiddenField("challenge")
-    remember = BooleanField("Remember me")
-    submit = SubmitField("Sign in")
diff --git a/login_provider/requirements.txt b/login_provider/requirements.txt
deleted file mode 100644
index 3c617cd..0000000
--- a/login_provider/requirements.txt
+++ /dev/null
@@ -1,7 +0,0 @@
-Flask
-flask-wtf
-flask-login
-hydra-client
-Flask-SQLAlchemy
-bcrypt
-graphqlclient
diff --git a/login_provider/templates/login.html b/login_provider/templates/login.html
deleted file mode 100644
index 912d0bf..0000000
--- a/login_provider/templates/login.html
+++ /dev/null
@@ -1,18 +0,0 @@
-<!doctype html>
-<title>Stackspin authentication service</title>
-<div style='margin: 0 auto ; width: 350px; padding:20px; border-style:solid; border-color:#6c757d; border-width: 1px; background-color: #f8f9fa; font-family: "Segoe UI", Roboto; font-family: "Helvetica Neue", Arial; font-family: "Noto Sans", sans-serif;'>
-  {% if logo %}
-  <div style="position:relative; width: 350px; height:100px">
-        <img style="overflow: auto; top: 0; left: 0; bottom: 0; right: 0; position: absolute; margin: auto;max-width: 300px; max-height: 100px" src="{{logo}}" alt="Logo of application"></img>
-  </div>
-  {% endif %}
-  <h1>Log in to {{ application_name }}</h1>
-  <form method="POST" action="/login">
-    {{ login_form.csrf_token }}
-    {{ login_form.challenge }}
-    {{ login_form.username(placeholder="Username", autofocus=true) }}<br>
-    <div style="margin-top:5px">{{ login_form.password(placeholder="Password") }}</div> <br>
-    {{ login_form.remember }}{{ login_form.remember.label }} <br>
-    <div style="margin-top:5px">{{ login_form.submit }}</div>
-  </form>
-</div>
diff --git a/login_provider/templates/skip.html b/login_provider/templates/skip.html
deleted file mode 100644
index 8effa54..0000000
--- a/login_provider/templates/skip.html
+++ /dev/null
@@ -1,14 +0,0 @@
-<!doctype html>
-<title>Stackspin authentication service</title>
-<div style='margin: 0 auto ; width: 350px; padding:20px; border-style:solid; border-color:#6c757d; border-width: 1px; background-color: #f8f9fa; font-family: "Segoe UI", Roboto; font-family: "Helvetica Neue", Arial; font-family: "Noto Sans", sans-serif;'>
-  {% if logo %}
-  <div style="position:relative; width: 350px; height:100px">
-        <img style="overflow: auto; top: 0; left: 0; bottom: 0; right: 0; position: absolute; margin: auto;max-width: 300px; max-height: 100px" src="{{logo}}" alt="Logo of application"></img>
-  </div>
-  {% endif %}
-  <h1>Log in to {{ application_name }}</h1>
-  <div style="width: 100%; margin-bottom: 5px; overflow: auto">
-      <div style="width:60%; float:left"><button id="continue" onclick="window.location.href = '/login?login_challenge={{ challenge }}&skip=true';">Continue with {{ username }}</button></div>
-      <div style="width:40%; float:left;"><button id="logout" onclick="window.location.href = '/login?login_challenge={{ challenge }}&logout=true';">Logout</button></div>
-  </div>
-</div>
diff --git a/logout_provider/Dockerfile b/logout_provider/Dockerfile
deleted file mode 100644
index 1312fc3..0000000
--- a/logout_provider/Dockerfile
+++ /dev/null
@@ -1,22 +0,0 @@
-FROM python:3.9-alpine
-
-RUN apk add gcc libc-dev libffi-dev
-
-WORKDIR /usr/src/app
-
-COPY requirements.txt ./
-RUN pip install --no-cache-dir -r requirements.txt
-
-COPY . .
-
-ARG FLASK_PORT=5002
-
-EXPOSE $FLASK_PORT
-
-ENV FLASK_ENV production
-ENV FLASK_RUN_PORT $FLASK_PORT
-ENV FLASK_RUN_HOST 0.0.0.0
-ENV HYDRA_ADMIN_URL http://localhost:4445
-
-
-CMD [ "flask", "run" ]
diff --git a/logout_provider/app.py b/logout_provider/app.py
deleted file mode 100644
index e17cebc..0000000
--- a/logout_provider/app.py
+++ /dev/null
@@ -1,44 +0,0 @@
-from flask import abort, Flask, redirect, request
-from flask.views import View
-from hydra_client import HydraAdmin
-import hydra_client
-import logging
-from os import environ
-
-HYDRA_ADMIN_URL = environ['HYDRA_ADMIN_URL']
-HYDRA = HydraAdmin(HYDRA_ADMIN_URL)
-
-app = Flask(__name__)
-app.logger.setLevel(logging.INFO)
-
-@app.route('/logout', methods=['GET'])
-def home():
-    """Handles the OpenID Connect Logout flow
-
-    Communicates with the hydra server to start the logout flow which uses backchannel and
-    frontchannel logout methods to log out the user from all applications they have
-    access to.
-
-    Args:
-        logout_challenge: Reference to a logout challenge object in form of an alphanumeric
-         String. Can be used to retrieve the LogoutRequest object via the Hydra Admin API (GET)
-
-    Returns:
-        Redirect to the url that is provided by the LogoutRequest object.
-    """
-    challenge = request.args.get("logout_challenge")
-    app.logger.info("Logout request: challenge={0}".format(challenge))
-    if not challenge:
-        abort(403)
-    try:
-        logout_request = HYDRA.logout_request(challenge)
-    except hydra_client.exceptions.NotFound:
-        app.logger.error("Not Found. Logout request not found. challenge={0}".format(challenge))
-        abort(404)
-    except hydra_client.exceptions.HTTPError:
-        app.logger.error("Conflict. Logout request has been used already. challenge={0}".format(challenge))
-        abort(503)
-    return redirect(logout_request.accept(subject=logout_request.subject))
-
-if __name__ == '__main__':
-    app.run()
diff --git a/logout_provider/requirements.txt b/logout_provider/requirements.txt
deleted file mode 100644
index 435993d..0000000
--- a/logout_provider/requirements.txt
+++ /dev/null
@@ -1,2 +0,0 @@
-Flask
-hydra-client
diff --git a/user-panel b/user-panel
deleted file mode 160000
index 9a16055..0000000
--- a/user-panel
+++ /dev/null
@@ -1 +0,0 @@
-Subproject commit 9a16055973a2b36acf361e853eb55b4cfbd0c6f4
-- 
GitLab