forked from Hostea/dashboard
feat: integration testing
SUMMARY integration/__main__.py is a CLI-based HTTP client that can interact with Hostea Dashboard and Gitea. Integration tests are run via integration/tests.sh, which is a driver for the HTTP client at integration/__main__.py. The script is capable of spinning up a test environment consisting of services defined in docker-compose-dev-deps.yml and the Hostea Dashboard and tearing it down after a successful run. The credentials used to create various accounts and other parameters are all defined in integration/tests.sh script it self. So it is self contained. CLIENT FUNCTIONALITY: HOSTEA DASHBOARD: - register user with email verification - login - create OIDC app - visit support page GITEA: - Install Gitea(DB configuration, etc. The first form that's presented to the visitor after a new instance is deployed) - Register User - Login User - Create repository - Configure OIDC SSO - Login via SSOwip-site
parent
3fb756bd12
commit
798a2f03d9
3
Makefile
3
Makefile
|
@ -32,6 +32,9 @@ freeze: ## Freeze python dependencies
|
|||
help: ## Prints help for targets with comments
|
||||
@cat $(MAKEFILE_LIST) | grep -E '^[a-zA-Z_-]+:.*?## .*$$' | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}'
|
||||
|
||||
integration-test: ## run integration tests
|
||||
. ./venv/bin/activate && integration/tests.sh
|
||||
|
||||
lint: ## Run linter
|
||||
@./venv/bin/black ./dashboard/
|
||||
@./venv/bin/black ./accounts/
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
import argparse
|
||||
|
||||
from .cli import Cli
|
||||
|
||||
|
||||
def admin(args):
|
||||
print(args)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
cli = Cli()
|
||||
opts = cli.parse()
|
||||
opts.func(opts, c=cli.c)
|
|
@ -0,0 +1,284 @@
|
|||
import argparse
|
||||
|
||||
from requests import Session
|
||||
|
||||
|
||||
def gitea_from_args(args, c: Session):
|
||||
from .gitea import Gitea
|
||||
|
||||
return Gitea(
|
||||
host=args.host,
|
||||
username=args.username,
|
||||
password=args.password,
|
||||
email=args.email,
|
||||
c=c,
|
||||
)
|
||||
|
||||
|
||||
class Gitea:
|
||||
def __init__(self, parser, c: Session):
|
||||
self.c = c
|
||||
self.parser = parser
|
||||
self.subparser = self.parser.add_subparsers()
|
||||
self.install()
|
||||
self.register()
|
||||
self.login()
|
||||
self.create_repository()
|
||||
self.install_sso()
|
||||
|
||||
def __add_credentials_parser(self, parser):
|
||||
group = parser.add_argument_group("credentials", "User credentials")
|
||||
group.add_argument("username", type=str, help="Gitea user's username")
|
||||
group.add_argument("password", type=str, help="Gitea user's password")
|
||||
group.add_argument("email", type=str, help="Gitea user's email")
|
||||
group.add_argument("host", type=str, help="URI at which Gitea is running")
|
||||
|
||||
def install(self):
|
||||
def run(args, c: Session):
|
||||
gitea = gitea_from_args(args, c=c)
|
||||
gitea.install()
|
||||
|
||||
self.install_parser = self.subparser.add_parser(
|
||||
name="install", description="Install Gitea", help="Install Gitea"
|
||||
)
|
||||
self.__add_credentials_parser(self.install_parser)
|
||||
self.install_parser.set_defaults(func=run)
|
||||
|
||||
def register(self):
|
||||
def run(args, c: Session):
|
||||
gitea = gitea_from_args(args, c=c)
|
||||
gitea.register()
|
||||
|
||||
self.register_parser = self.subparser.add_parser(
|
||||
name="register",
|
||||
description="Gitea user registration",
|
||||
help="Register a user on Gitea",
|
||||
)
|
||||
self.__add_credentials_parser(self.register_parser)
|
||||
self.register_parser.set_defaults(func=run)
|
||||
|
||||
def login(self):
|
||||
def run(args, c: Session):
|
||||
gitea = gitea_from_args(args, c=c)
|
||||
gitea.login()
|
||||
|
||||
self.login_parser = self.subparser.add_parser(
|
||||
name="login", description="Gitea user login", help="Login on Gitea"
|
||||
)
|
||||
self.__add_credentials_parser(self.login_parser)
|
||||
self.login_parser.set_defaults(func=run)
|
||||
|
||||
def create_repository(self):
|
||||
def run(args, c: Session):
|
||||
gitea = gitea_from_args(args, c=c)
|
||||
gitea.login()
|
||||
gitea.create_repository(name=args.repo_name)
|
||||
|
||||
self.create_repository_parser = self.subparser.add_parser(
|
||||
name="create_repo",
|
||||
description="Create repository on Gitea",
|
||||
help="Create repository on Gitea",
|
||||
)
|
||||
self.__add_credentials_parser(self.create_repository_parser)
|
||||
self.create_repository_parser.set_defaults(func=run)
|
||||
self.create_repository_parser.add_argument(
|
||||
"repo_name", type=str, help="Name of the repository to be created"
|
||||
)
|
||||
|
||||
def install_sso(self):
|
||||
def run(args, c: Session):
|
||||
gitea = gitea_from_args(args, c=c)
|
||||
gitea.login()
|
||||
print(f"CLIENT ID: {args.client_id}")
|
||||
gitea.install_sso(
|
||||
sso_name=args.sso_name,
|
||||
client_id=args.client_id,
|
||||
client_secret=args.client_secret,
|
||||
sso_auto_discovery_url=args.sso_auto_discovery_url,
|
||||
)
|
||||
|
||||
self.install_sso_parser = self.subparser.add_parser(
|
||||
name="install_sso",
|
||||
description="Install SSO on Gitea",
|
||||
help="Install SSO on Gitea",
|
||||
)
|
||||
self.__add_credentials_parser(self.install_sso_parser)
|
||||
self.install_sso_parser.add_argument(
|
||||
"sso_name", type=str, help="(Human readable)Name of the SSO"
|
||||
)
|
||||
self.install_sso_parser.add_argument(
|
||||
"client_id", type=str, help="Client ID generated by the SSO"
|
||||
)
|
||||
self.install_sso_parser.add_argument(
|
||||
"client_secret", type=str, help="Client secret generated by the SSO"
|
||||
)
|
||||
self.install_sso_parser.add_argument(
|
||||
"sso_auto_discovery_url",
|
||||
type=str,
|
||||
help="OIDC Auto Discovery URL of the SSO",
|
||||
)
|
||||
|
||||
self.install_sso_parser.set_defaults(func=run)
|
||||
|
||||
|
||||
def dash_from_args(args, c: Session):
|
||||
from .hostea import Hostea
|
||||
|
||||
return Hostea(
|
||||
username=args.username,
|
||||
email=args.email,
|
||||
password=args.password,
|
||||
host=args.host,
|
||||
c=c,
|
||||
)
|
||||
|
||||
|
||||
class Hostea:
|
||||
def __init__(self, parser, c: Session):
|
||||
self.c = c
|
||||
self.parser = parser
|
||||
self.subparser = self.parser.add_subparsers()
|
||||
self.register()
|
||||
self.login()
|
||||
self.support()
|
||||
|
||||
def __add_credentials_parser(self, parser):
|
||||
group = parser.add_argument_group("credentials", "User credentials")
|
||||
group.add_argument("username", type=str, help="Hostea user's username")
|
||||
group.add_argument("password", type=str, help="Hostea user's password")
|
||||
group.add_argument("email", type=str, help="Hostea user's email")
|
||||
group.add_argument("host", type=str, help="URI at which Hostea is running")
|
||||
|
||||
def register(self):
|
||||
def run(args, c: Session):
|
||||
dash = dash_from_args(args, c=c)
|
||||
dash.register(maildev_host=args.maildev_host)
|
||||
|
||||
self.register_parser = self.subparser.add_parser(
|
||||
name="register",
|
||||
description="register new user ",
|
||||
help="Register new user on Hostea Dashboard",
|
||||
)
|
||||
self.__add_credentials_parser(self.register_parser)
|
||||
self.register_parser.add_argument(
|
||||
"maildev_host", type=str, help="URI at which maildev is running"
|
||||
)
|
||||
self.register_parser.set_defaults(func=run)
|
||||
|
||||
def login(self):
|
||||
def run(args, c: Session):
|
||||
dash = dash_from_args(args, c=c)
|
||||
dash.login()
|
||||
|
||||
self.login_parser = self.subparser.add_parser(
|
||||
name="login",
|
||||
description="login",
|
||||
help="Login user on Hostea Dashboard",
|
||||
)
|
||||
self.__add_credentials_parser(self.login_parser)
|
||||
self.login_parser.set_defaults(func=run)
|
||||
|
||||
def support(self):
|
||||
def run(args, c: Session):
|
||||
from .gitea import GiteaSSO
|
||||
|
||||
dash = dash_from_args(args, c=c)
|
||||
dash.login()
|
||||
|
||||
gitea = GiteaSSO(
|
||||
username=dash.username,
|
||||
email=dash.email,
|
||||
gitea_host=args.gitea_host,
|
||||
hostea_org=args.gitea_hostea_org,
|
||||
support_repo=args.support_repo,
|
||||
c=c,
|
||||
)
|
||||
dash.new_ticket(gitea.new_issues_uri)
|
||||
gitea.new_issue()
|
||||
|
||||
self.support_parser = self.subparser.add_parser(
|
||||
name="support",
|
||||
description="Hostea support",
|
||||
help="Support functionality on Hostea Dashboard",
|
||||
)
|
||||
self.__add_credentials_parser(self.support_parser)
|
||||
self.support_parser.add_argument(
|
||||
"gitea_host", type=str, help="URI at which Gitea is running"
|
||||
)
|
||||
self.support_parser.add_argument(
|
||||
"gitea_hostea_org",
|
||||
type=str,
|
||||
help="Hostea namespace(username/org) on Gitea, where support repository is hosted",
|
||||
)
|
||||
self.support_parser.add_argument(
|
||||
"support_repo", type=str, help="support repository name"
|
||||
)
|
||||
|
||||
self.support_parser.set_defaults(func=run)
|
||||
|
||||
|
||||
class Cli:
|
||||
def __init__(self):
|
||||
c = Session()
|
||||
self.c = c
|
||||
self.parser = argparse.ArgumentParser(
|
||||
description="Install and Bootstrap Gitea and Hostea Dashboard"
|
||||
)
|
||||
self.subparser = self.parser.add_subparsers()
|
||||
self.check_env()
|
||||
self.gitea()
|
||||
self.hostea()
|
||||
|
||||
def __add_credentials_parser(self, parser):
|
||||
group = parser.add_argument_group("credentials", "User credentials")
|
||||
group.add_argument("username", type=str, help="Gitea user's username")
|
||||
group.add_argument("password", type=str, help="Gitea user's password")
|
||||
group.add_argument("email", type=str, help="Gitea user's email")
|
||||
|
||||
def check_env(self):
|
||||
def run(args, c: Session):
|
||||
from .gitea import Gitea
|
||||
from .hostea import Hostea
|
||||
|
||||
Hostea.check_online(
|
||||
dashboard_host=args.hostea_host, maildev_host=args.maildev_host
|
||||
)
|
||||
Gitea.check_online(host=args.gitea_host)
|
||||
|
||||
self.check_env_parser = self.subparser.add_parser(
|
||||
name="check_env",
|
||||
description="Check and block until environment is ready",
|
||||
help="Check and block until environment is ready",
|
||||
)
|
||||
|
||||
self.check_env_parser.add_argument(
|
||||
"gitea_host", type=str, help="URI at which Gitea is running"
|
||||
)
|
||||
|
||||
self.check_env_parser.add_argument(
|
||||
"hostea_host", type=str, help="URI at which Hostea is running"
|
||||
)
|
||||
|
||||
self.check_env_parser.add_argument(
|
||||
"maildev_host", type=str, help="URI at which maildev is running"
|
||||
)
|
||||
self.check_env_parser.set_defaults(func=run)
|
||||
|
||||
def hostea(self):
|
||||
self.hostea = self.subparser.add_parser(
|
||||
name="hostea",
|
||||
description="Hostea Dashboard",
|
||||
help="Hostea Dashboard-related functionality",
|
||||
)
|
||||
Hostea(parser=self.hostea, c=self.c)
|
||||
|
||||
def gitea(self):
|
||||
self.gitea = self.subparser.add_parser(
|
||||
name="gitea",
|
||||
description="Gitea",
|
||||
help="Gitea-related functionality",
|
||||
)
|
||||
Gitea(parser=self.gitea, c=self.c)
|
||||
|
||||
def parse(self):
|
||||
return self.parser.parse_args()
|
|
@ -0,0 +1,38 @@
|
|||
from html.parser import HTMLParser
|
||||
|
||||
|
||||
class ParseCSRF(HTMLParser):
|
||||
token: str = None
|
||||
|
||||
def __init__(self, name):
|
||||
HTMLParser.__init__(self)
|
||||
self.name = name
|
||||
|
||||
# @classmethod
|
||||
# def dashboard_parser(cls) -> "ParseCSRF":
|
||||
# return cls(name="csrfmiddlewaretoken")
|
||||
#
|
||||
# @classmethod
|
||||
# def gitea_parser(cls) -> "ParseCSRF":
|
||||
# return cls(name="_csrf")
|
||||
#
|
||||
def handle_starttag(self, tag: str, attrs: (str, str)):
|
||||
if self.token:
|
||||
return
|
||||
|
||||
if tag != "input":
|
||||
return
|
||||
|
||||
token = None
|
||||
for (index, (k, v)) in enumerate(attrs):
|
||||
if k == "value":
|
||||
token = v
|
||||
|
||||
if all([k == "name", v == self.name]):
|
||||
if token:
|
||||
self.token = token
|
||||
return
|
||||
for (inner_index, (nk, nv)) in enumerate(attrs, start=index):
|
||||
if nk == "value":
|
||||
self.token = nv
|
||||
return
|
|
@ -0,0 +1,449 @@
|
|||
from urllib.parse import urlunparse, urlparse
|
||||
from html.parser import HTMLParser
|
||||
from time import sleep
|
||||
import random
|
||||
import argparse
|
||||
|
||||
from requests import Session
|
||||
from requests.auth import HTTPBasicAuth
|
||||
import requests
|
||||
|
||||
from .csrf import ParseCSRF
|
||||
|
||||
# GITEA_USER = "root"
|
||||
# GITEA_EMAIL = "root@example.com"
|
||||
# GITEA_PASSWORD = "foobarpassword"
|
||||
# HOST = "http://localhost:8080"
|
||||
#
|
||||
# REPOS = []
|
||||
|
||||
|
||||
class Gitea:
|
||||
def __init__(self, host: str, username: str, password: str, email: str, c: Session):
|
||||
self.host = host
|
||||
self.username = username
|
||||
self.password = password
|
||||
self.email = email
|
||||
self.c = c
|
||||
self.__csrf_key = "_csrf"
|
||||
self.__logged_in = False
|
||||
|
||||
def get_uri(self, path: str):
|
||||
parsed = urlparse(self.host)
|
||||
return urlunparse((parsed.scheme, parsed.netloc, path, "", "", ""))
|
||||
|
||||
def get_api_uri(self, path: str):
|
||||
parsed = urlparse(self.host)
|
||||
return urlunparse(
|
||||
(
|
||||
parsed.scheme,
|
||||
f"{self.username}:{self.password}@{parsed.netloc}",
|
||||
path,
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
)
|
||||
)
|
||||
|
||||
@staticmethod
|
||||
def check_online(host: str):
|
||||
"""
|
||||
Check if Gitea instance is online
|
||||
"""
|
||||
count = 0
|
||||
parsed = urlparse(host)
|
||||
url = urlunparse((parsed.scheme, parsed.netloc, "api/v1/nodeinfo", "", "", ""))
|
||||
|
||||
while True:
|
||||
try:
|
||||
res = requests.get(url, allow_redirects=False)
|
||||
if any([res.status_code == 302, res.status_code == 200]):
|
||||
break
|
||||
except:
|
||||
sleep(2)
|
||||
print(f"Retrying {count} time")
|
||||
count += 1
|
||||
continue
|
||||
|
||||
def install(self):
|
||||
"""
|
||||
Install Gitea, first form that a user sees when a new instance is
|
||||
deployed
|
||||
"""
|
||||
payload = {
|
||||
"db_type": "sqlite3",
|
||||
"db_host": "localhost:3306",
|
||||
"db_user": "root",
|
||||
"db_passwd": "",
|
||||
"db_name": "gitea",
|
||||
"ssl_mode": "disable",
|
||||
"db_schema": "",
|
||||
"charset": "utf8",
|
||||
"db_path": "/data/gitea/gitea.db",
|
||||
"app_name": "Gitea:+Git+with+a+cup+of+tea",
|
||||
"repo_root_path": "/data/git/repositories",
|
||||
"lfs_root_path": "/data/git/lfs",
|
||||
"run_user": "git",
|
||||
"domain": "localhost",
|
||||
"ssh_port": "2221",
|
||||
"http_port": "3000",
|
||||
"app_url": self.get_uri(""),
|
||||
"log_root_path": "/data/gitea/log",
|
||||
"smtp_host": "",
|
||||
"smtp_from": "",
|
||||
"smtp_user": "",
|
||||
"smtp_passwd": "",
|
||||
"enable_federated_avatar": "on",
|
||||
"enable_open_id_sign_in": "on",
|
||||
"enable_open_id_sign_up": "on",
|
||||
"default_allow_create_organization": "on",
|
||||
"default_enable_timetracking": "on",
|
||||
"no_reply_address": "noreply.localhost",
|
||||
"password_algorithm": "pbkdf2",
|
||||
"admin_name": "",
|
||||
"admin_passwd": "",
|
||||
"admin_confirm_passwd": "",
|
||||
"admin_email": "",
|
||||
}
|
||||
self.c.post(self.get_uri(""), data=payload)
|
||||
sleep(10)
|
||||
|
||||
def get_csrf_token(self, url: str) -> str:
|
||||
"""
|
||||
Get CSRF token at a URI
|
||||
"""
|
||||
resp = self.c.get(url, allow_redirects=False)
|
||||
if resp.status_code != 200 and resp.status_code != 302:
|
||||
print(resp.status_code, resp.text)
|
||||
raise Exception(f"Can't get csrf token: {resp.status_code}")
|
||||
parser = ParseCSRF(name=self.__csrf_key)
|
||||
parser.feed(resp.text)
|
||||
csrf = parser.token
|
||||
return csrf
|
||||
|
||||
def register(self):
|
||||
"""
|
||||
Register User
|
||||
"""
|
||||
url = self.get_uri("/user/sign_up")
|
||||
csrf = self.get_csrf_token(url)
|
||||
payload = {
|
||||
"_csrf": csrf,
|
||||
"user_name": self.username,
|
||||
"password": self.password,
|
||||
"retype": self.password,
|
||||
"email": self.email,
|
||||
}
|
||||
self.c.post(url, data=payload, allow_redirects=False)
|
||||
|
||||
def login(self):
|
||||
"""
|
||||
Login, must be called at least once before performing authenticated
|
||||
operations
|
||||
"""
|
||||
if self.__logged_in:
|
||||
return
|
||||
url = self.get_uri("/user/login")
|
||||
csrf = self.get_csrf_token(url)
|
||||
payload = {
|
||||
"_csrf": csrf,
|
||||
"user_name": self.username,
|
||||
"password": self.password,
|
||||
"remember": "on",
|
||||
}
|
||||
resp = self.c.post(url, data=payload, allow_redirects=False)
|
||||
if any(
|
||||
[resp.status_code == 302, resp.status_code == 200, resp.status_code == 303]
|
||||
):
|
||||
print("User logged in")
|
||||
self.__logged_in = True
|
||||
return
|
||||
|
||||
raise Exception(
|
||||
f"[ERROR] Authentication failed. status code {resp.status_code}"
|
||||
)
|
||||
|
||||
def create_repository(self, name: str):
|
||||
"""
|
||||
Create repository
|
||||
"""
|
||||
self.login()
|
||||
|
||||
def get_repository_payload(csrf: str, name: str, user_id: str):
|
||||
data = {
|
||||
"_csrf": csrf,
|
||||
"uid": user_id,
|
||||
"repo_name": name,
|
||||
"description": f"this repository is named {name}",
|
||||
"repo_template": "",
|
||||
"issue_labels": "",
|
||||
"gitignores": "",
|
||||
"license": "",
|
||||
"readme": "Default",
|
||||
"default_branch": "master",
|
||||
"trust_model": "default",
|
||||
}
|
||||
return data
|
||||
|
||||
url = self.get_uri("/repo/create")
|
||||
user_id = self.c.get(self.get_api_uri("/api/v1/user")).json()["id"]
|
||||
print(type(user_id))
|
||||
print(user_id)
|
||||
|
||||
csrf = self.get_csrf_token(url)
|
||||
data = get_repository_payload(csrf, name, user_id=user_id)
|
||||
print(data)
|
||||
print(type(data))
|
||||
|
||||
resp = self.c.post(url, data=data, allow_redirects=False)
|
||||
print(f"Created repository {name}")
|
||||
if resp.status_code != 302 and resp.status_code != 200:
|
||||
raise Exception(
|
||||
f"Error while creating repository: {name} {resp.status_code}"
|
||||
)
|
||||
|
||||
def install_sso(
|
||||
self,
|
||||
sso_name: str,
|
||||
client_id: str,
|
||||
client_secret: str,
|
||||
sso_auto_discovery_url: str,
|
||||
):
|
||||
self.login()
|
||||
"""
|
||||
Install SSO.
|
||||
|
||||
- sso_name: human readable SSO name. Doesn't have any functionality
|
||||
except assisting admins ID an SSO by a name
|
||||
|
||||
- client_id: OAuth stuff, will be generated by the SSO that should be integrated
|
||||
|
||||
- client_secret: OAuth stuff, will be generated by the SSO that should be integrated
|
||||
|
||||
- sso_auto_discovery_url: Again OAuth stuff. Should be available in the SSO documentation.
|
||||
In Hostea SSO's case, it is available at
|
||||
https://hostea-dash.example.org/o/.well-known/openid-configuration/
|
||||
"""
|
||||
csrf = self.get_csrf_token(self.get_uri("/admin/auths/new"))
|
||||
payload = {
|
||||
"_autofill_dummy_username": "",
|
||||
"_autofill_dummy_password": "",
|
||||
"_csrf": csrf,
|
||||
"type": "6",
|
||||
"name": sso_name,
|
||||
"security_protocol": "",
|
||||
"host": "",
|
||||
"port": "",
|
||||
"bind_dn": "",
|
||||
"bind_password": "",
|
||||
"user_base": "",
|
||||
"user_dn": "",
|
||||
"filter": "",
|
||||
"admin_filter": ["", ""],
|
||||
"attribute_username": "",
|
||||
"attribute_name": "",
|
||||
"attribute_surname": "",
|
||||
"attribute_mail": "",
|
||||
"attribute_ssh_public_key": "",
|
||||
"attribute_avatar": "",
|
||||
"group_dn": "",
|
||||
"group_member_uid": "",
|
||||
"user_uid": "",
|
||||
"group_filter": "",
|
||||
"group_team_map": "",
|
||||
"search_page_size": "",
|
||||
"smtp_auth": "PLAIN",
|
||||
"smtp_host": "",
|
||||
"smtp_port": "",
|
||||
"helo_hostname": "",
|
||||
"allowed_domains": "",
|
||||
"pam_service_name": "",
|
||||
"pam_email_domain": "",
|
||||
"oauth2_provider": "openidConnect",
|
||||
"oauth2_key": client_id,
|
||||
"oauth2_secret": client_secret,
|
||||
"oauth2_icon_url": "",
|
||||
"open_id_connect_auto_discovery_url": sso_auto_discovery_url,
|
||||
"oauth2_auth_url": "",
|
||||
"oauth2_token_url": "",
|
||||
"oauth2_profile_url": "",
|
||||
"oauth2_email_url": "",
|
||||
"oauth2_tenant": "",
|
||||
"oauth2_scopes": "openid",
|
||||
"oauth2_required_claim_name": "",
|
||||
"oauth2_required_claim_value": "",
|
||||
"oauth2_group_claim_name": "",
|
||||
"oauth2_admin_group": "",
|
||||
"oauth2_restricted_group": "",
|
||||
"sspi_auto_create_users": "on",
|
||||
"sspi_auto_activate_users": "on",
|
||||
"sspi_strip_domain_names": "on",
|
||||
"sspi_separator_replacement": "_",
|
||||
"sspi_default_language": "",
|
||||
"is_sync_enabled": "on",
|
||||
"is_active": "on",
|
||||
}
|
||||
|
||||
resp = self.c.post(self.get_uri("/admin/auths/new"), data=payload)
|
||||
|
||||
|
||||
def cli():
|
||||
parser = argparse.ArguementParser(description="Install and Bootstrap Gitea")
|
||||
parser.add_arguement("username", type=str, help="Gitea user's username")
|
||||
parser.add_arguement("password", type=str, help="Gitea user's password")
|
||||
parser.add_arguement("email", type=str, help="Gitea user's email")
|
||||
args = parser.parse_args()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
print("hello")
|
||||
|
||||
# args = cli()
|
||||
|
||||
|
||||
# gitea = Gitea(
|
||||
# host=HOST,
|
||||
# username=GITEA_USER,
|
||||
# password=GITEA_PASSWORD,
|
||||
# email=GITEA_EMAIL,
|
||||
# c=Session(),
|
||||
# )
|
||||
# gitea.check_online()
|
||||
# print("Instace online")
|
||||
# gitea.install()
|
||||
# gitea.register()
|
||||
# gitea.login()
|
||||
# gitea.create_repository(name="support")
|
||||
# client_id = ""
|
||||
# client_secret = ""
|
||||
# sso_auto_discovery_url = ""
|
||||
# gitea.install_sso(
|
||||
# sso_name="Hostea OIDC",
|
||||
# client_id=client_id,
|
||||
# client_secret=client_secret,
|
||||
# sso_auto_discovery_url=sso_auto_discovery_url,
|
||||
# )
|
||||
|
||||
|
||||
class ParseSSOLogin(HTMLParser):
|
||||
url: str = None
|
||||
|
||||
def handle_starttag(self, tag: str, attrs: (str, str)):
|
||||
if self.url:
|
||||
return
|
||||
|
||||
if tag != "a":
|
||||
return
|
||||
|
||||
token = None
|
||||
for (index, (k, v)) in enumerate(attrs):
|
||||
if k == "href":
|
||||
if "/user/oauth2/" in v:
|
||||
self.url = v
|
||||
return
|
||||
|
||||
|
||||
class GiteaSSO:
|
||||
def __init__(
|
||||
self,
|
||||
username: str,
|
||||
email: str,
|
||||
gitea_host: str,
|
||||
hostea_org: str,
|
||||
support_repo: str,
|
||||
c: Session,
|
||||
):
|
||||
self.c = c
|
||||
self.username = username
|
||||
self.gitea_host = gitea_host
|
||||
self.hostea_org = hostea_org
|
||||
self.support_repo = support_repo
|
||||
self.email = email
|
||||
|
||||
self.__csrf_key = "_csrf"
|
||||
|
||||
url = urlparse(self.gitea_host)
|
||||
repo = f"{self.hostea_org}/{self.support_repo}"
|
||||
issues = f"{repo}/issues"
|
||||
new_issues = f"{issues}/new"
|
||||
|
||||
self.__partial_call_back_url = urlunparse(
|
||||
(url.scheme, url.netloc, "/user/oauth2/", "", "", "")
|
||||
)
|
||||
self.__login = urlunparse((url.scheme, url.netloc, "/user/login/", "", "", ""))
|
||||
self.__link_acount = urlunparse(
|
||||
(url.scheme, url.netloc, "/user/link_account/", "", "", "")
|
||||
)
|
||||
self.__link_acount_signup = urlunparse(
|
||||
(url.scheme, url.netloc, "/user/link_account_signup/", "", "", "")
|
||||
)
|
||||
|
||||
self.__me = urlunparse(
|
||||
(url.scheme, url.netloc, f"/{self.username}", "", "", "")
|
||||
)
|
||||
|
||||
self.issues_uri = urlunparse((url.scheme, url.netloc, issues, "", "", ""))
|
||||
self.new_issues_uri = urlunparse(
|
||||
(url.scheme, url.netloc, new_issues, "", "", "")
|
||||
)
|
||||
|
||||
def get_csrf(self, url: str) -> str:
|
||||
resp = self.c.get(url)
|
||||
parser = ParseCSRF(name=self.__csrf_key)
|
||||
parser.feed(resp.text)
|
||||
return parser.token
|
||||
|
||||
def _sso_login(self):
|
||||
resp = self.c.get(self.__login)
|
||||
parser = ParseSSOLogin()
|
||||
parser.feed(resp.text)
|
||||
|
||||
url = urlparse(self.gitea_host)
|
||||
## SSO URL in Gitea login page
|
||||
sso = urlunparse((url.scheme, url.netloc, parser.url, "", "", ""))
|
||||
|
||||
# redirects are enabled to for a cleaner implementation. Commented out
|
||||
# code below does the same in a step-by-step manner
|
||||
resp = self.c.get(sso)
|
||||
|
||||
# resp = c.get(sso, allow_redirects=False)
|
||||
# ## Visiting SSO URL redirects the user with HTTP 307 to the SSO for authorization
|
||||
# assert resp.status_code == 307
|
||||
|
||||
# resp = c.get(resp.headers["Location"], allow_redirects=False)
|
||||
|
||||
# assert self.__partial_call_back_url in resp.headers["Location"]
|
||||
# resp = c.get(resp.headers["Location"], allow_redirects=False)
|
||||
# assert resp.status_code == 303
|
||||
# assert resp.headers["Location"] in self.__link_acount
|
||||
|
||||
# to register account, the user has to visit form at self.__link_acount
|
||||
csrf = self.get_csrf(self.__link_acount)
|
||||
# which makes a POST request to self.__link_acount_signup
|
||||
# weird, but have to go to above URL to collect CSRF toekn
|
||||
payload = {
|
||||
"user_name": self.username,
|
||||
"email": self.email,
|
||||
self.__csrf_key: csrf,
|
||||
}
|
||||
|
||||
resp = self.c.post(self.__link_acount_signup, payload, allow_redirects=True)
|
||||
assert resp.status_code == 200
|
||||
# redirect mechanisms seems to change for every version
|
||||
# print(resp.status_code)
|
||||
# print(resp.headers["Location"])
|
||||
# assert resp.status_code == 303
|
||||
# assert resp.headers["Location"] == self.new_issues_uri
|
||||
|
||||
resp = self.c.get(self.__me)
|
||||
assert resp.status_code == 200
|
||||
assert self.username in resp.text
|
||||
|
||||
def new_issue(self):
|
||||
resp = self.c.get(self.new_issues_uri, allow_redirects=False)
|
||||
resp.status_code = 303
|
||||
assert "/user/login" in resp.headers["Location"]
|
||||
|
||||
self._sso_login()
|
||||
resp = self.c.get(self.new_issues_uri, allow_redirects=False)
|
||||
assert resp.status_code == 200
|
|
@ -0,0 +1,129 @@
|
|||
import logging
|
||||
from urllib.parse import urlparse, urlunparse
|
||||
from html.parser import HTMLParser
|
||||
from time import sleep
|
||||
|
||||
from requests import Session
|
||||
import requests
|
||||
|
||||
from .csrf import ParseCSRF
|
||||
|
||||
|
||||
class Hostea:
|
||||
def __init__(self, username: str, email: str, password: str, host: str, c: Session):
|
||||
self.username = username
|
||||
self.email = email
|
||||
self.password = password
|
||||
self.csrf_key = "csrfmiddlewaretoken"
|
||||
self.host = host
|
||||
self.c = c
|
||||
|
||||
@staticmethod
|
||||
def check_online(dashboard_host: str, maildev_host: str):
|
||||
"""
|
||||
Check if Hostea Dashboard is online
|
||||
"""
|
||||
count = 0
|
||||
dash_parsed = urlparse(dashboard_host)
|
||||
maildev_parsed = urlparse(maildev_host)
|
||||
urls = [
|
||||
urlunparse((dash_parsed.scheme, dash_parsed.netloc, "/login/", "", "", "")),
|
||||
urlunparse((maildev_parsed.scheme, maildev_parsed.netloc, "", "", "", "")),
|
||||
]
|
||||
|
||||
for url in urls:
|
||||
while True:
|
||||
try:
|
||||
res = requests.get(url, allow_redirects=False)
|
||||
if any([res.status_code == 302, res.status_code == 200]):
|
||||
break
|
||||
except Exception as e:
|
||||
sleep(2)
|
||||
print(e)
|
||||
print(f"[Hostea] Retrying {count} time for {url}")
|
||||
count += 1
|
||||
continue
|
||||
|
||||
def get_uri(self, path: str):
|
||||
parsed = urlparse(self.host)
|
||||
return urlunparse((parsed.scheme, parsed.netloc, path, "", "", ""))
|
||||
|
||||
def get_csrf(self, url: str) -> str:
|
||||
resp = self.c.get(url=url)
|
||||
assert resp.status_code == 200
|
||||
parser = ParseCSRF(name=self.csrf_key)
|
||||
parser.feed(resp.text)
|
||||
csrf = parser.token
|
||||
return csrf
|
||||
|
||||
def __get_verification_link(self, maildev_host: str):
|
||||
def maildev_uri(maildev_host: str, path: str):
|
||||
parsed = urlparse(maildev_host)
|
||||
return urlunparse((parsed.scheme, parsed.netloc, path, "", "", ""))
|
||||
|
||||
resp = self.c.get(maildev_uri(maildev_host=maildev_host, path="/email/"))
|
||||
# resp = self.c.get("http://localhost:1080/email/")
|
||||
emails = resp.json()
|
||||
for email in emails:
|
||||
if email["to"][0]["address"] == self.email:
|
||||
logging.info("[Dashboard] Found verification link")
|
||||
resp = self.c.delete(
|
||||
maildev_uri(maildev_host=maildev_host, path=f"/email/{email['id']}")
|
||||
)
|
||||
return str.strip(email["text"].split("\n")[1])
|
||||
logging.critical("[Dashboard] Verification link not found")
|
||||
|
||||
def register(self, maildev_host: str):
|
||||
url = self.get_uri("/register/")
|
||||
csrf = self.get_csrf(url)
|
||||
payload = {
|
||||
"username": self.username,
|
||||
"password": self.password,
|
||||
"email": self.email,
|
||||
"confirm_password": self.password,
|
||||
self.csrf_key: csrf,
|
||||
}
|
||||
|
||||
logging.info("Registering user")
|
||||
resp = self.c.post(url, payload, allow_redirects=False)
|
||||
assert resp.status_code == 302
|
||||
assert "pending" in resp.headers["Location"]
|
||||
|
||||
email_verification_link = self.__get_verification_link(
|
||||
maildev_host=maildev_host
|
||||
)
|
||||
csrf = self.get_csrf(email_verification_link)
|
||||
payload = {
|
||||
self.csrf_key: csrf,
|
||||
}
|
||||
resp = self.c.post(email_verification_link, payload, allow_redirects=False)
|
||||
assert resp.status_code == 302
|
||||
assert resp.headers["Location"] == "/login/"
|
||||
logging.info("[Dashboard] Email verified user")
|
||||
|
||||
def login(self):
|
||||
url = self.get_uri("/login/")
|
||||
|
||||
csrf = self.get_csrf(url)
|
||||
payload = {
|
||||
"login": self.username,
|
||||
"password": self.password,
|
||||
self.csrf_key: csrf,
|
||||
}
|
||||
|
||||
logging.info("Logging In user")
|
||||
resp = self.c.post(url, payload, allow_redirects=False)
|
||||
|
||||
assert resp.status_code == 302
|
||||
assert resp.headers["Location"] == "/"
|
||||
|
||||
resp = self.c.get(self.get_uri("/support/new/"))
|
||||
assert resp.status_code == 200
|
||||
|
||||
def new_ticket(self, support_repository_new_issue: str):
|
||||
resp = self.c.get(self.get_uri("/support/new/"))
|
||||
|
||||
|
||||
# print(resp.text)
|
||||
# print(support_repository_new_issue)
|
||||
# assert support_repository_new_issue in resp.text
|
|
@ -1,276 +0,0 @@
|
|||
import logging
|
||||
from urllib.parse import urlparse, urlunparse
|
||||
from html.parser import HTMLParser
|
||||
|
||||
from requests import Session
|
||||
|
||||
logging.basicConfig(level=logging.INFO)
|
||||
|
||||
|
||||
c = Session()
|
||||
|
||||
|
||||
class ParseCSRF(HTMLParser):
|
||||
token: str = None
|
||||
|
||||
def __init__(self, name):
|
||||
HTMLParser.__init__(self)
|
||||
self.name = name
|
||||
|
||||
@classmethod
|
||||
def dashboard_parser(cls) -> "ParseCSRF":
|
||||
return cls(name="csrfmiddlewaretoken")
|
||||
|
||||
@classmethod
|
||||
def gitea_parser(cls) -> "ParseCSRF":
|
||||
return cls(name="_csrf")
|
||||
|
||||
def handle_starttag(self, tag: str, attrs: (str, str)):
|
||||
if self.token:
|
||||
return
|
||||
|
||||
if tag != "input":
|
||||
return
|
||||
|
||||
token = None
|
||||
for (index, (k, v)) in enumerate(attrs):
|
||||
if k == "value":
|
||||
token = v
|
||||
|
||||
if all([k == "name", v == self.name]):
|
||||
if token:
|
||||
self.token = token
|
||||
return
|
||||
for (inner_index, (nk, nv)) in enumerate(attrs, start=index):
|
||||
if nk == "value":
|
||||
self.token = nv
|
||||
return
|
||||
|
||||
|
||||
class ParseSSOLogin(HTMLParser):
|
||||
url: str = None
|
||||
|
||||
def handle_starttag(self, tag: str, attrs: (str, str)):
|
||||
if self.url:
|
||||
return
|
||||
|
||||
if tag != "a":
|
||||
return
|
||||
|
||||
token = None
|
||||
for (index, (k, v)) in enumerate(attrs):
|
||||
if k == "href":
|
||||
if "/user/oauth2/" in v:
|
||||
self.url = v
|
||||
return
|
||||
|
||||
|
||||
class Hostea:
|
||||
def __init__(self, username: str, email: str, password: str, url: str):
|
||||
self.username = username
|
||||
self.email = email
|
||||
self.password = password
|
||||
self.url = urlparse(url)
|
||||
self.csrf_key = "csrfmiddlewaretoken"
|
||||
|
||||
def get_csrf(self, url: str) -> str:
|
||||
resp = c.get(url)
|
||||
assert resp.status_code == 200
|
||||
parser = ParseCSRF(name=self.csrf_key)
|
||||
parser.feed(resp.text)
|
||||
csrf = parser.token
|
||||
return csrf
|
||||
|
||||
def __get_verification_link(self):
|
||||
resp = c.get("http://localhost:1080/email/")
|
||||
emails = resp.json()
|
||||
for email in emails:
|
||||
if email["to"][0]["address"] == self.email:
|
||||
logging.info("[Dashboard] Found verification link")
|
||||
resp = c.delete(f"http://localhost:1080/email/{email['id']}")
|
||||
return str.strip(email["text"].split("\n")[1])
|
||||
logging.critical("[Dashboard] Verification link not found")
|
||||
|
||||
def register(self):
|
||||
url = urlunparse((self.url.scheme, self.url.netloc, "/register/", "", "", ""))
|
||||
csrf = self.get_csrf(url)
|
||||
payload = {
|
||||
"username": self.username,
|
||||
"password": self.password,
|
||||
"email": self.email,
|
||||
"confirm_password": self.password,
|
||||
self.csrf_key: csrf,
|
||||
}
|
||||
|
||||
logging.info("Registering user")
|
||||
resp = c.post(url, payload, allow_redirects=False)
|
||||
assert resp.status_code == 302
|
||||
assert "pending" in resp.headers["Location"]
|
||||
|
||||
email_verification_link = self.__get_verification_link()
|
||||
csrf = self.get_csrf(email_verification_link)
|
||||
payload = {
|
||||
self.csrf_key: csrf,
|
||||
}
|
||||
resp = c.post(email_verification_link, payload, allow_redirects=False)
|
||||
assert resp.status_code == 302
|
||||
assert resp.headers["Location"] == "/login/"
|
||||
logging.info("[Dashboard] Email verified user")
|
||||
|
||||
def login(self):
|
||||
url = urlunparse((self.url.scheme, self.url.netloc, "/login/", "", "", ""))
|
||||
|
||||
csrf = self.get_csrf(url)
|
||||
payload = {
|
||||
"login": self.username,
|
||||
"password": self.password,
|
||||
self.csrf_key: csrf,
|
||||
}
|
||||
|
||||
logging.info("Logging In user")
|
||||
resp = c.post(url, payload, allow_redirects=False)
|
||||
|
||||
assert resp.status_code == 302
|
||||
assert resp.headers["Location"] == "/"
|
||||
|
||||
url = urlunparse(
|
||||
(self.url.scheme, self.url.netloc, "/support/new/", "", "", "")
|
||||
)
|
||||
|
||||
resp = c.get(url)
|
||||
assert resp.status_code == 200
|
||||
|
||||
def new_ticket(self, support_repository_new_issue: str):
|
||||
url = urlunparse(
|
||||
(self.url.scheme, self.url.netloc, "/support/new/", "", "", "")
|
||||
)
|
||||
resp = c.get(url)
|
||||
assert support_repository_new_issue in resp.text
|
||||
|
||||
|
||||
class Gitea:
|
||||
def __init__(
|
||||
self,
|
||||
username: str,
|
||||
email: str,
|
||||
gitea_host: str,
|
||||
hostea_org: str,
|
||||
support_repo: str,
|
||||
):
|
||||
self.username = username
|
||||
self.gitea_host = gitea_host
|
||||
self.hostea_org = hostea_org
|
||||
self.support_repo = support_repo
|
||||
self.email = email
|
||||
|
||||
self.__csrf_key = "_csrf"
|
||||
|
||||
url = urlparse(self.gitea_host)
|
||||
repo = f"{self.hostea_org}/{self.support_repo}"
|
||||
issues = f"{repo}/issues"
|
||||
new_issues = f"{issues}/new"
|
||||
|
||||
self.__partial_call_back_url = urlunparse(
|
||||
(url.scheme, url.netloc, "/user/oauth2/", "", "", "")
|
||||
)
|
||||
self.__login = urlunparse((url.scheme, url.netloc, "/user/login/", "", "", ""))
|
||||
self.__link_acount = urlunparse(
|
||||
(url.scheme, url.netloc, "/user/link_account/", "", "", "")
|
||||
)
|
||||
self.__link_acount_signup = urlunparse(
|
||||
(url.scheme, url.netloc, "/user/link_account_signup/", "", "", "")
|
||||
)
|
||||
|
||||
self.__me = urlunparse(
|
||||
(url.scheme, url.netloc, f"/{self.username}", "", "", "")
|
||||
)
|
||||
|
||||
self.issues_uri = urlunparse((url.scheme, url.netloc, issues, "", "", ""))
|
||||
self.new_issues_uri = urlunparse(
|
||||
(url.scheme, url.netloc, new_issues, "", "", "")
|
||||
)
|
||||
|
||||
def get_csrf(self, url: str) -> str:
|
||||
resp = c.get(url)
|
||||
parser = ParseCSRF.gitea_parser()
|
||||
parser.feed(resp.text)
|
||||
return parser.token
|
||||
|
||||
def _sso_login(self):
|
||||
resp = c.get(self.__login)
|
||||
parser = ParseSSOLogin()
|
||||
parser.feed(resp.text)
|
||||
|
||||
url = urlparse(self.gitea_host)
|
||||
## SSO URL in Gitea login page
|
||||
sso = urlunparse((url.scheme, url.netloc, parser.url, "", "", ""))
|
||||
|
||||
# redirects are enabled to for a cleaner implementation. Commented out
|
||||
# code below does the same in a step-by-step manner
|
||||
resp = c.get(sso)
|
||||
|
||||
# resp = c.get(sso, allow_redirects=False)
|
||||
# ## Visiting SSO URL redirects the user with HTTP 307 to the SSO for authorization
|
||||
# assert resp.status_code == 307
|
||||
|
||||
# resp = c.get(resp.headers["Location"], allow_redirects=False)
|
||||
|
||||
# assert self.__partial_call_back_url in resp.headers["Location"]
|
||||
# resp = c.get(resp.headers["Location"], allow_redirects=False)
|
||||
# assert resp.status_code == 303
|
||||
# assert resp.headers["Location"] in self.__link_acount
|
||||
|
||||
# to register account, the user has to visit form at self.__link_acount
|
||||
csrf = self.get_csrf(self.__link_acount)
|
||||
# which makes a POST request to self.__link_acount_signup
|
||||
# weird, but have to go to above URL to collect CSRF toekn
|
||||
payload = {
|
||||
"user_name": self.username,
|
||||
"email": self.email,
|
||||
self.__csrf_key: csrf,
|
||||
}
|
||||
|
||||
resp = c.post(self.__link_acount_signup, payload, allow_redirects=False)
|
||||
assert resp.status_code == 303
|
||||
assert resp.headers["Location"] == "/Hostea/support/issues/new"
|
||||
|
||||
resp = c.get(self.__me)
|
||||
assert resp.status_code == 200
|
||||
assert self.username in resp.text
|
||||
|
||||
def new_issue(self):
|
||||
resp = c.get(self.new_issues_uri, allow_redirects=False)
|
||||
resp.status_code = 303
|
||||
assert "/user/login" in resp.headers["Location"]
|
||||
|
||||
self._sso_login()
|
||||
resp = c.get(self.new_issues_uri, allow_redirects=False)
|
||||
assert resp.status_code == 200
|
||||
|
||||
|
||||
def main():
|
||||
|
||||
dash = Hostea(
|
||||
username="enough",
|
||||
email="enough@example.org",
|
||||
password="asdfas234234vaa",
|
||||
url="http://localhost:8000",
|
||||
)
|
||||
gitea = Gitea(
|
||||
gitea_host="http://localhost:8080",
|
||||
username=dash.username,
|
||||
email=dash.email,
|
||||
hostea_org="Hostea",
|
||||
support_repo="support",
|
||||
)
|
||||
dash.register()
|
||||
dash.login()
|
||||
dash.new_ticket(gitea.new_issues_uri)
|
||||
|
||||
gitea.new_issue()
|
||||
|
||||
logging.info("All tests passed")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
|
@ -0,0 +1,149 @@
|
|||
#!/bin/bash
|
||||
|
||||
set -Exeuo pipefail
|
||||
|
||||
readonly DASHBOARD_URL="http://localhost:8000"
|
||||
readonly GITEA_URL="http://localhost:3000"
|
||||
readonly MAILDEV_URL="http://localhost:1080"
|
||||
readonly DASHBOARD_OIDC_DISCOVERY_URL="$DASHBOARD_URL/o/.well-known/openid-configuration/"
|
||||
|
||||
readonly DASHBOARD_ADMIN_USERNAME=root
|
||||
readonly DASHBOARD_ADMIN_PASSWORD=supercomplicatedpassword
|
||||
readonly DASHBOARD_ADMIN_EMAIL="$DASHBOARD_ADMIN_USERNAME@dash.example.org"
|
||||
readonly DASHBOARD_OIDC_APP_NAME=hostea-gitea
|
||||
|
||||
readonly GITEA_ROOT_USERNAME=root
|
||||
readonly GITEA_ROOT_EMAIL="$GITEA_ROOT_USERNAME@example.org"
|
||||
readonly GITEA_ROOT_PASSOWRD=supercomplicatedpassword
|
||||
readonly GITEA_HOSTEA_SSO_NAME=hostea-sso
|
||||
readonly GITEA_OIDC_CALLBACK="$GITEA_URL/user/oauth2/$GITEA_HOSTEA_SSO_NAME/callback"
|
||||
|
||||
readonly GITEA_HOSTEA_USERNAME=hostea
|
||||
readonly GITEA_HOSTEA_PASSWORD=supercomplicatedpassword
|
||||
readonly GITEA_HOSTEA_EMAIL="$GITEA_HOSTEA_USERNAME@example.org"
|
||||
readonly GITEA_HOSTEA_SUPPORT_REPO="support"
|
||||
|
||||
readonly HOSTEA_CUSTOMER_USERNAME=batman
|
||||
readonly HOSTEA_CUSTOMER_PASSWORD=supercomplicatedpassword
|
||||
readonly HOSTEA_CUSTOMER_EMAIL="$HOSTEA_CUSTOMER_USERNAME@example.org"
|
||||
|
||||
OIDC_CLIENT_ID=""
|
||||
OIDC_CLIENT_SECRET=""
|
||||
|
||||
wait_for_env() {
|
||||
python -m integration \
|
||||
check_env $GITEA_URL $DASHBOARD_URL $MAILDEV_URL
|
||||
}
|
||||
|
||||
# create OIDC app on Hostea Dashboard
|
||||
oidc_dashboard_init() {
|
||||
python -m integration \
|
||||
hostea register \
|
||||
$DASHBOARD_ADMIN_USERNAME $DASHBOARD_ADMIN_PASSWORD \
|
||||
$DASHBOARD_ADMIN_EMAIL \
|
||||
$DASHBOARD_URL \
|
||||
$MAILDEV_URL
|
||||
|
||||
resp=$(python manage.py create_oidc \
|
||||
$DASHBOARD_OIDC_APP_NAME $DASHBOARD_ADMIN_USERNAME \
|
||||
$GITEA_OIDC_CALLBACK)
|
||||
OIDC_CLIENT_ID=$(echo $resp | cut -d ":" -f 2 | cut -d " " -f 2)
|
||||
OIDC_CLIENT_SECRET=$(echo $resp | cut -d ":" -f 3 | cut -d " " -f 2)
|
||||
}
|
||||
|
||||
# register root user on Gitea to simulate Hoste admin and integrate SSO
|
||||
gitea_root(){
|
||||
python -m integration \
|
||||
gitea install \
|
||||
$GITEA_ROOT_USERNAME $GITEA_ROOT_PASSOWRD \
|
||||
$GITEA_ROOT_EMAIL \
|
||||
$GITEA_URL
|
||||
python -m integration \
|
||||
gitea register \
|
||||
$GITEA_ROOT_USERNAME $GITEA_ROOT_PASSOWRD \
|
||||
$GITEA_ROOT_EMAIL \
|
||||
$GITEA_URL
|
||||
python -m integration \
|
||||
gitea login \
|
||||
$GITEA_ROOT_USERNAME $GITEA_ROOT_PASSOWRD \
|
||||
$GITEA_ROOT_EMAIL \
|
||||
$GITEA_URL
|
||||
python -m integration \
|
||||
gitea install_sso \
|
||||
$GITEA_ROOT_USERNAME $GITEA_ROOT_PASSOWRD \
|
||||
$GITEA_ROOT_EMAIL \
|
||||
$GITEA_URL \
|
||||
$GITEA_HOSTEA_SSO_NAME \
|
||||
$OIDC_CLIENT_ID $OIDC_CLIENT_SECRET \
|
||||
$DASHBOARD_OIDC_DISCOVERY_URL
|
||||
}
|
||||
|
||||
|
||||
# register user "Hostea" on Gitea and create support repository
|
||||
support_repo_init() {
|
||||
python -m integration \
|
||||
gitea register \
|
||||
$GITEA_HOSTEA_USERNAME $GITEA_HOSTEA_PASSWORD \
|
||||
$GITEA_HOSTEA_EMAIL \
|
||||
$GITEA_URL
|
||||
python -m integration \
|
||||
gitea login \
|
||||
$GITEA_HOSTEA_USERNAME $GITEA_HOSTEA_PASSWORD \
|
||||
$GITEA_HOSTEA_EMAIL \
|
||||
$GITEA_URL
|
||||
python -m integration \
|
||||
gitea create_repo \
|
||||
$GITEA_HOSTEA_USERNAME $GITEA_HOSTEA_PASSWORD \
|
||||
$GITEA_HOSTEA_EMAIL \
|
||||
$GITEA_URL \
|
||||
$GITEA_HOSTEA_SUPPORT_REPO
|
||||
}
|
||||
|
||||
# Create user on Hostea to simulate a Hostea customer
|
||||
hostea_customer_simulation() {
|
||||
python -m integration \
|
||||
hostea register \
|
||||
$HOSTEA_CUSTOMER_USERNAME $HOSTEA_CUSTOMER_PASSWORD \
|
||||
$HOSTEA_CUSTOMER_EMAIL \
|
||||
$DASHBOARD_URL \
|
||||
$MAILDEV_URL
|
||||
python -m integration \
|
||||
hostea login \
|
||||
$HOSTEA_CUSTOMER_USERNAME $HOSTEA_CUSTOMER_PASSWORD \
|
||||
$HOSTEA_CUSTOMER_EMAIL $DASHBOARD_URL
|
||||
python -m integration \
|
||||
hostea support \
|
||||
$HOSTEA_CUSTOMER_USERNAME $HOSTEA_CUSTOMER_PASSWORD \
|
||||
$HOSTEA_CUSTOMER_EMAIL \
|
||||
$DASHBOARD_URL \
|
||||
$GITEA_URL \
|
||||
$GITEA_HOSTEA_USERNAME $GITEA_HOSTEA_SUPPORT_REPO
|
||||
}
|
||||
|
||||
SERVER_PID=""
|
||||
|
||||
setup_env() {
|
||||
nohup python manage.py runserver > /dev/null 2>&1 &
|
||||
SERVER_PID=$!
|
||||
docker-compose -f docker-compose-dev-deps.yml up --detach
|
||||
}
|
||||
|
||||
teardown_env() {
|
||||
docker-compose -f docker-compose-dev-deps.yml down --remove-orphans
|
||||
kill $SERVER_PID
|
||||
}
|
||||
|
||||
main() {
|
||||
teardown_env || true
|
||||
setup_env
|
||||
wait_for_env
|
||||
oidc_dashboard_init
|
||||
echo "OIDC APP initialized. CLIENT_ID: $OIDC_CLIENT_ID CLIENT SECRET: $OIDC_CLIENT_SECRET"
|
||||
gitea_root
|
||||
support_repo_init
|
||||
hostea_customer_simulation
|
||||
teardown_env
|
||||
echo "All Good! :)"
|
||||
}
|
||||
|
||||
main
|
Loading…
Reference in New Issue