Skip to content

Commit

Permalink
Merge pull request #1 from eimis-ans/build/refactor-project
Browse files Browse the repository at this point in the history
Build: refactor project
  • Loading branch information
ad2ien authored Jun 15, 2023
2 parents 8eda4da + e3d829d commit 9cc00fb
Show file tree
Hide file tree
Showing 13 changed files with 199 additions and 111 deletions.
File renamed without changes.
83 changes: 63 additions & 20 deletions .github/workflows/docker-image.yml
Original file line number Diff line number Diff line change
@@ -1,33 +1,76 @@
name: Publish Docker image

on:
release:
types: [published]
push:
branches: [main]
tags: ["v*"]

concurrency:
group: docker-${{ github.ref }}
cancel-in-progress: true

jobs:
push_to_registry:
name: Push Docker image to Docker Hub
publish-docker-images:
runs-on: ubuntu-latest
steps:
- name: Check out the repo
- name: Check out repository
uses: actions/checkout@v3

- name: Log in to Docker Hub
uses: docker/login-action@f054a8b539a109f9f41c372932f1ae047eff08c9
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}


- name: Set up context
id: project_context
uses: FranzDiebold/github-env-vars-action@v2.7.0

- name: Extract metadata (tags, labels) for Docker
id: meta
uses: docker/metadata-action@98669ae865ea3cffbcbaa878cf57c20bbf1c6c38
id: docker_metadata
uses: docker/metadata-action@v4
with:
images: cameronwickes/ma1sd-extender

- name: Build and push Docker image
uses: docker/build-push-action@ad44023a93711e3deb337508980b4b5e9bcdc5dc
images: ${{ github.repository }}
tags: |
type=raw,enable=${{ !endsWith(github.ref, github.event.repository.default_branch) }},value=${{ env.CI_ACTION_REF_NAME_SLUG }}
type=raw,enable=${{ endsWith(github.ref, github.event.repository.default_branch) }},value=nightly
type=semver,pattern={{version}}
type=semver,pattern={{major}}.{{minor}}
type=semver,pattern={{major}}
labels: |
org.opencontainers.image.vendor=EIMIS
- name: Login to Docker Hub
uses: docker/login-action@v2
with:
username: ${{ secrets.DOCKER_HUB_USER }}
password: ${{ secrets.DOCKER_HUB_PASSWORD }}

- name: Build and publish image(s)
uses: docker/build-push-action@v3
with:
context: .
platforms: linux/amd64
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
tags: ${{ steps.docker_metadata.outputs.tags }}
labels: ${{ steps.docker_metadata.outputs.labels }}


dockerhub-description:
runs-on: ubuntu-latest
steps:
- name: Check out repository
uses: actions/checkout@v3
with:
fetch-depth: 2

- name: Find change in readme file
id: readme-change
uses: tj-actions/changed-files@v34
with:
files: |
README.md
- name: Docker Hub Description
if: steps.readme-change.outputs.any_changed == 'true'
uses: peter-evans/dockerhub-description@v3
with:
username: ${{ secrets.DOCKER_HUB_USER }}
short-description: Docker image for https://github.com/${{ github.repository }}
password: ${{ secrets.DOCKER_HUB_PASSWORD }}
repository: ${{ github.repository }}
readme-filepath: README.md
55 changes: 55 additions & 0 deletions .github/workflows/lint.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
name: Lint

on:
workflow_call:

push:
branches: [main]

pull_request:
branches: [main]

concurrency:
group: lint-${{ github.ref }}
cancel-in-progress: true

jobs:
lint-poetry:
runs-on: ubuntu-latest
steps:
- name: Check out repository
uses: actions/checkout@v3

- uses: actions/setup-python@v4
with:
python-version: "3.10"

- name: Install Python Poetry
uses: abatilo/actions-poetry@v2.2.0
with:
poetry-version: "1.5.1"

- name: Check poetry config is valid
run: |
poetry check
lint-dockerfile:
runs-on: ubuntu-latest
if: github.actor != 'dependabot[bot]'
steps:
- name: Check out repository
uses: actions/checkout@v3

- name: Lint dockerfile (hadolint)
uses: hadolint/hadolint-action@v3.0.0

lint-markdown:
runs-on: ubuntu-latest
steps:
- name: Check out repository
uses: actions/checkout@v3

- name: Lint markdown files
uses: avto-dev/markdown-lint@v1.5.0
with:
args: "**/*.md"
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
__pycache__/
4 changes: 4 additions & 0 deletions .markdownlint.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
line-length: false
no-hard-tabs: false
MD033:
allowed_elements: ["img", "p"]
82 changes: 36 additions & 46 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,62 +1,52 @@
# https://github.com/svx/poetry-fastapi-docker/blob/main/docker/Dockerfile
FROM python:3.10 as python-base

ENV PYTHONUNBUFFERED=1 \
# -----
FROM python:3.10-slim-buster AS builder

ENV \
# python:
PYTHONFAULTHANDLER=1 \
PYTHONUNBUFFERED=1 \
PYTHONHASHSEED=random \
PYTHONDONTWRITEBYTECODE=1 \
# pip:
PIP_NO_CACHE_DIR=off \
PIP_DISABLE_PIP_VERSION_CHECK=on \
PIP_DEFAULT_TIMEOUT=100 \
POETRY_HOME="/opt/poetry" \
POETRY_VIRTUALENVS_IN_PROJECT=true \
# poetry:
POETRY_VERSION=1.5.1 \
POETRY_NO_INTERACTION=1 \
PYSETUP_PATH="/opt/pysetup" \
VENV_PATH="/opt/pysetup/.venv"


ENV PATH="$POETRY_HOME/bin:$VENV_PATH/bin:$PATH"

FROM python-base as builder-base
RUN buildDeps="build-essential" \
&& apt-get update \
&& apt-get install --no-install-recommends -y \
curl \
vim \
netcat \
&& apt-get install -y --no-install-recommends $buildDeps \
&& rm -rf /var/lib/apt/lists/*
POETRY_VIRTUALENVS_CREATE=false \
POETRY_CACHE_DIR='/var/cache/pypoetry' \
PATH="$PATH:/root/.local/bin"

SHELL ["/bin/bash", "-o", "pipefail", "-c"]

ENV POETRY_VERSION=1.1.12
RUN curl -sSL https://raw.githubusercontent.com/python-poetry/poetry/master/get-poetry.py | python && \
chmod a+x /opt/poetry/bin/poetry
RUN apt-get update \
&& apt-get install --no-install-recommends -y \
build-essential=12.6 \
curl=7.64.0-4+deb10u6 \
&& curl -sSL https://install.python-poetry.org | python3 \
&& apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false \
&& apt-get clean -y \
&& rm -rf /var/lib/apt/lists/*

WORKDIR $PYSETUP_PATH
COPY ./api/poetry.lock ./api/pyproject.toml ./
ENV PATH="${PATH}:/root/.local/bin"

RUN poetry install --no-dev # respects
# RUN poetry add "uvicorn[standard]"
# RUN cat pyproject.toml
# RUN cat poetry.lock
WORKDIR /build

FROM python-base as development
ENV FASTAPI_ENV=development
COPY poetry.lock pyproject.toml ./
RUN poetry config virtualenvs.create false \
&& poetry install --no-root --only main

COPY ma1sd_extender ma1sd_extender

# Copying poetry and venv into image
COPY --from=builder-base $POETRY_HOME $POETRY_HOME
COPY --from=builder-base $PYSETUP_PATH $PYSETUP_PATH
RUN poetry build

# Copying in our entrypoint
COPY ./docker-entrypoint.sh /docker-entrypoint.sh
RUN chmod +x /docker-entrypoint.sh
# -----
FROM python:3.10-slim-buster

# venv already has runtime deps installed we get a quicker install
WORKDIR $PYSETUP_PATH
RUN poetry install
COPY --from=builder /build/dist/*.whl /tmp/whl/

WORKDIR /api
COPY ./api .
RUN python3 -m pip install --no-cache-dir /tmp/whl/*.whl \
&& rm -rf /tmp/whl

EXPOSE 8060
ENTRYPOINT /docker-entrypoint.sh $0 $@
CMD ["uvicorn", "--reload", "--host=0.0.0.0", "--port=8060", "ma1sd-extender.main:app"]
ENTRYPOINT ["ma1sd_extender"]
53 changes: 23 additions & 30 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,35 +1,29 @@
<h1 align="center">
<img alt="matrix logo" src="https://www.cameronwickes.co.uk/ma1sd-extender.png" width="250px"/><br/>
MA1SD-Extender
</h1>
# MA1SD-Extender

<p align="center">
<img alt="Supported Platforms" src="https://img.shields.io/badge/Platform-Linux-blueviolet?color=blue&style=for-the-badge">
<img alt="Language" src="https://img.shields.io/badge/Language-Python-blue?color=blueviolet&style=for-the-badge">
<img alt="License" src="https://img.shields.io/github/license/cameronwickes/ma1sd-extender?color=brightgreen&style=for-the-badge">
</p>
This project is a fork from <https://github.com/cameronwickes/ma1sd-extender> ❤️

<p align="center">
An API, built with <b>Docker</b> and <b>FastAPI</b>, that allows <b>Matrix</b> user directory searches to be recursively federated for corporate use.
<img alt="matrix logo" src="https://www.cameronwickes.co.uk/ma1sd-extender.png" width="250px"/>
</p>

</br>

<p>
<b>MA1SD-Extender performs the following sequence of actions in order to recursively federate directory lookups:</b>
<ul>
<li>Checks the validity of API supplied credentials</li>
<li>Checks the validity of a user specified authorisation token against all federation domains</li>
<li>Returns previously cached responses for faster lookups</li>
<li>Searches within local directory for users</li>
<li>Recursively searches other federation domains for users</li>
<li>Returns pooled responses masquerading as the local MA1SD server</li>
</ul>

</br>

MA1SD-Extender is available from this repository, and can also be found on the <a target="_blank" href="https://hub.docker.com/repository/docker/cameronwickes/ma1sd-extender">Docker Hub</a>.
</p>
![Supported Platforms](https://img.shields.io/badge/Platform-Linux-blueviolet?color=blue&style=for-the-badge)
![Language](https://img.shields.io/badge/Language-Python-blue?color=blueviolet&style=for-the-badge)
![License](https://img.shields.io/github/license/cameronwickes/ma1sd-extender?color=brightgreen&style=for-the-badge)

An API, built with **Docker** and **FastAPI**, that allows **Matrix** user directory searches to be recursively federated for corporate use.

---

MA1SD-Extender performs the following sequence of actions in order to recursively federate directory lookups:

- Checks the validity of API supplied credentials
- Checks the validity of a user specified authorization token against all federation domains
- Returns previously cached responses for faster lookups
- Searches within local directory for users
- Recursively searches other federation domains for users
- Returns pooled responses masquerading as the local MA1SD server

---

## ⚙️ Configuration Variables

Expand Down Expand Up @@ -60,20 +54,19 @@ uvicorn --reload --host='0.0.0.0' --port=8060 ma1sd-extender.main:app
MA1SD-Extender can also be run with Docker/Podman with the following commands:

```bash
docker pull cameronwickes/ma1sd-extender:latest
docker run --name ma1sd \
-e MA1SD_EXTENDER_USERNAME="X" \
-e MA1SD_EXTENDER_PASSWORD="X" \
-e MA1SD_EXTENDER_MATRIX_DOMAIN="X" \
-e MA1SD_EXTENDER_FEDERATED_DOMAINS="['X']" \
ma1sd-extender:latest
eimisans/ma1sd-extender:latest
```

## 💻 NGINX Proxy Setup

Once MA1SD-Extender is running, an NGINX proxy can be configured to pass requests to and from the API. The following section should be placed within the NGINX configuration file.

```
```nginx
location /_matrix/client/r0/user_directory {
proxy_pass http://0.0.0.0:8060/_matrix/client/r0/user_directory;
proxy_set_header Host $host;
Expand Down
File renamed without changes.
15 changes: 8 additions & 7 deletions api/ma1sd-extender/main.py → ma1sd_extender/main.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,10 @@
from json import loads
import uvicorn
from fastapi import FastAPI, Request, Body, Response, Depends
from fastapi.responses import JSONResponse
from starlette.middleware.cors import CORSMiddleware
from fastapi import Body, Depends, FastAPI, Request, Response
from fastapi_cache import caches, close_caches
from fastapi_cache.backends.memory import CACHE_KEY, InMemoryCacheBackend
from json import loads
import asyncio
import search
import models
from ma1sd_extender import models, search
from starlette.middleware.cors import CORSMiddleware

description="""
The `ma1sd_extender` API allows Matrix user directories to be federated for corporate use.
Expand Down Expand Up @@ -78,3 +75,7 @@ async def userDirectory(request: Request, cache: InMemoryCacheBackend = Depends(
"""
response = await search.findUsers(request, cache)
return response

def start():
"""Launched with `poetry run start` at root level"""
uvicorn.run("ma1sd_extender.main:app", host="0.0.0.0", port=8000, reload=False)
File renamed without changes.
10 changes: 5 additions & 5 deletions api/ma1sd-extender/search.py → ma1sd_extender/search.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
from fastapi import Request, Header, Depends
from itertools import chain
from json import loads
from os import getenv

from fastapi import Depends, Header, Request
from fastapi.responses import JSONResponse
from fastapi_cache.backends.memory import InMemoryCacheBackend
from os import getenv
from requests import get, post
from json import loads
from itertools import chain
import asyncio



Expand Down
File renamed without changes.
Loading

0 comments on commit 9cc00fb

Please sign in to comment.