Skip to content

Commit

Permalink
Merge branch 'master' into oidc-non-confidential
Browse files Browse the repository at this point in the history
  • Loading branch information
daniel-lerch committed Jan 13, 2025
2 parents 0fdadd3 + 21d6fb0 commit 34feaf6
Show file tree
Hide file tree
Showing 224 changed files with 7,259 additions and 12,900 deletions.
14 changes: 7 additions & 7 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,11 @@ on:
jobs:
server:
name: Backend build and integration tests
runs-on: ubuntu-22.04
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v4
- name: Setup .NET SDK
uses: actions/setup-dotnet@v3
uses: actions/setup-dotnet@v4
with:
dotnet-version: 8.0.x
- name: Restore NuGet packages
Expand All @@ -27,19 +27,19 @@ jobs:
# Launch and prepare MySQL server
sudo systemctl start mysql.service
dotnet run -c Release --no-build --project server/src/Korga.Server -- database create
dotnet run -c Release --no-build --project server/Korga -- database create
- name: Test
run: dotnet test -c Release --no-build --verbosity normal

webapp:
name: Frontend build
runs-on: ubuntu-22.04
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v4
- name: Setup NodeJS
uses: actions/setup-node@v4
with:
node-version: '20'
node-version: '22'
- name: Restore NPM packages
run: npm install
working-directory: webapp
Expand All @@ -49,7 +49,7 @@ jobs:

docker:
name: Docker build
runs-on: ubuntu-22.04
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v4
- name: Docker meta
Expand All @@ -69,7 +69,7 @@ jobs:
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Build and push
uses: docker/build-push-action@v5
uses: docker/build-push-action@v6
with:
context: .
push: ${{ github.event_name != 'pull_request' }}
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ on:
jobs:
docker:
name: Docker build
runs-on: ubuntu-22.04
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v4
- name: Docker meta
Expand All @@ -29,7 +29,7 @@ jobs:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Build and push
uses: docker/build-push-action@v5
uses: docker/build-push-action@v6
with:
context: .
push: true
Expand Down
29 changes: 23 additions & 6 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
FROM node:20 AS webapp
FROM node:22 AS webapp
WORKDIR /app

# Copy package definition and restore node modules as distinct layers
Expand All @@ -13,17 +13,34 @@ FROM mcr.microsoft.com/dotnet/sdk:8.0 AS server
WORKDIR /app

# Copy csproj and restore as distinct layers
COPY server/src/Korga.Server/Korga.Server.csproj ./Korga.Server/
RUN dotnet restore Korga.Server
COPY server/ChurchTools/ChurchTools.csproj ./ChurchTools/
COPY server/Korga/Korga.csproj ./Korga/
RUN dotnet restore Korga

# Copy everything else and build
COPY server/src ./
RUN dotnet publish -c Release -o /app/out Korga.Server
COPY server ./
RUN dotnet publish -c Release -o /app/out Korga

# Build runtime image
FROM mcr.microsoft.com/dotnet/aspnet:8.0
WORKDIR /app

# Install curl for healthcheck
RUN set -x \
&& apt-get update \
&& apt-get install -y --no-install-recommends \
curl \
&& rm -rf /var/lib/apt/lists/*

COPY --from=server /app/out .
COPY --from=webapp /app/dist wwwroot/
ENTRYPOINT ["dotnet", "Korga.Server.dll"]

HEALTHCHECK \
--interval=1m \
--timeout=10s \
--start-period=15s \
--start-interval=5s \
--retries=3 \
CMD curl --fail http://localhost:8080/healthz || exit 1

ENTRYPOINT ["dotnet", "Korga.dll"]
24 changes: 11 additions & 13 deletions Korga.sln
Original file line number Diff line number Diff line change
Expand Up @@ -3,28 +3,26 @@ Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.1.32210.238
MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Korga.Server", "server\src\Korga.Server\Korga.Server.csproj", "{E1C5CDEB-C3D5-4BE1-B823-5FD650AB1D08}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Korga", "server\Korga\Korga.csproj", "{E1C5CDEB-C3D5-4BE1-B823-5FD650AB1D08}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "server-src", "server-src", "{565B1C55-E3A4-4B7E-9F8E-EF14AA917618}"
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "server", "server", "{565B1C55-E3A4-4B7E-9F8E-EF14AA917618}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "_", "_", "{28945597-DB66-4C1C-A2DB-C5ACB5ED4DD4}"
ProjectSection(SolutionItems) = preProject
Dockerfile = Dockerfile
README.md = README.md
EndProjectSection
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "server-tests", "server-tests", "{86DB2784-54F6-43CC-8F86-94E059B7DE59}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Korga.Server.Tests", "server\tests\Korga.Server.Tests\Korga.Server.Tests.csproj", "{2A484A88-F6BD-4B36-92C8-0675ADDD8CDB}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "docs", "docs", "{2ED6D7FB-8B8A-4139-98C3-854E00A38490}"
ProjectSection(SolutionItems) = preProject
docs\docker-compose.yml = docs\docker-compose.yml
docs\compose.yaml = docs\compose.yaml
docs\email-processing-pipeline.md = docs\email-processing-pipeline.md
docs\frontend.md = docs\frontend.md
EndProjectSection
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Korga.Core", "server\src\Korga.Core\Korga.Core.csproj", "{D1CEB029-9AFB-4464-BF93-DBA6216B4128}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ChurchTools", "server\ChurchTools\ChurchTools.csproj", "{D1CEB029-9AFB-4464-BF93-DBA6216B4128}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Korga.Tests", "server\Korga.Tests\Korga.Tests.csproj", "{EFA087E1-C034-44A2-B1C1-DEDCF996FEB1}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Expand All @@ -36,22 +34,22 @@ Global
{E1C5CDEB-C3D5-4BE1-B823-5FD650AB1D08}.Debug|Any CPU.Build.0 = Debug|Any CPU
{E1C5CDEB-C3D5-4BE1-B823-5FD650AB1D08}.Release|Any CPU.ActiveCfg = Release|Any CPU
{E1C5CDEB-C3D5-4BE1-B823-5FD650AB1D08}.Release|Any CPU.Build.0 = Release|Any CPU
{2A484A88-F6BD-4B36-92C8-0675ADDD8CDB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{2A484A88-F6BD-4B36-92C8-0675ADDD8CDB}.Debug|Any CPU.Build.0 = Debug|Any CPU
{2A484A88-F6BD-4B36-92C8-0675ADDD8CDB}.Release|Any CPU.ActiveCfg = Release|Any CPU
{2A484A88-F6BD-4B36-92C8-0675ADDD8CDB}.Release|Any CPU.Build.0 = Release|Any CPU
{D1CEB029-9AFB-4464-BF93-DBA6216B4128}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{D1CEB029-9AFB-4464-BF93-DBA6216B4128}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D1CEB029-9AFB-4464-BF93-DBA6216B4128}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D1CEB029-9AFB-4464-BF93-DBA6216B4128}.Release|Any CPU.Build.0 = Release|Any CPU
{EFA087E1-C034-44A2-B1C1-DEDCF996FEB1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{EFA087E1-C034-44A2-B1C1-DEDCF996FEB1}.Debug|Any CPU.Build.0 = Debug|Any CPU
{EFA087E1-C034-44A2-B1C1-DEDCF996FEB1}.Release|Any CPU.ActiveCfg = Release|Any CPU
{EFA087E1-C034-44A2-B1C1-DEDCF996FEB1}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{E1C5CDEB-C3D5-4BE1-B823-5FD650AB1D08} = {565B1C55-E3A4-4B7E-9F8E-EF14AA917618}
{2A484A88-F6BD-4B36-92C8-0675ADDD8CDB} = {86DB2784-54F6-43CC-8F86-94E059B7DE59}
{D1CEB029-9AFB-4464-BF93-DBA6216B4128} = {565B1C55-E3A4-4B7E-9F8E-EF14AA917618}
{EFA087E1-C034-44A2-B1C1-DEDCF996FEB1} = {565B1C55-E3A4-4B7E-9F8E-EF14AA917618}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {638049AA-35BE-4FFE-8370-373448555D24}
Expand Down
19 changes: 12 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,16 @@ Once configured, Korga automatically synchronizes people and groups from ChurchT
There is no Web UI available yet to manage distribution lists so you must stick to the CLI inside the Docker container:

```
./Korga.Server distribution-list create --group 137 kids
./Korga dist create kids
./Korga dist add-recipient kids -g 137
```

This command creates a distribution list _[email protected]_ which forwards emails to every member of group #137.

## Installation

The only officially supported distribution are Docker containers. An official image is available at [daniellerch/korga](https://hub.docker.com/r/daniellerch/korga).
If you are using Docker Compose, take a look our [example compose file](docs/docker-compose.yml) in the `docs` folder.
If you are using Docker Compose, take a look our [example compose file](docs/compose.yaml) in the `docs` folder.

Korga has multiple modules that must be enabled via configuration to use them:
- ChurchTools sync
Expand All @@ -32,7 +33,7 @@ Korga has multiple modules that must be enabled via configuration to use them:

Configuration can set as enviroment variables or by creating a custom config file.
I recommend to use environment variables and will explain them in the following sections.
However, if you prefer a config file, copy the default [appsettings.json](server/src/Korga.Server/appsettings.json), edit it as required, and mount it at `/app/appsettings.json`.
However, if you prefer a config file, copy the default [appsettings.json](server/Korga/appsettings.json), edit it as required, and mount it at `/app/appsettings.json`.

### OpenID Connect authentication

Expand Down Expand Up @@ -87,6 +88,7 @@ Grant the following permissions to Korga's user:
- Personen & Gruppen > Sicherheitslevel Personendaten (Stufe 1-3) `churchdb:security level person(1,2,3)`
- Personen & Gruppen > Alle Personen des jeweiligen Bereiches sichtbar machen (Alle) `churchdb:view alldata(-1)`
- Personen & Gruppen > Einzelne Gruppen inkl. der enthaltenen Personen sehen (gilt auch für versteckte Gruppen) (Alle) `churchdb:view group(-1)`
- Personen & Gruppen > Gruppenmitgliedschaften aller sichtbaren Personen bearbeiten `churchdb:edit group memberships`
- Events > "Events" sehen `churchservice:view`
- Events > Dienste einzelner Dienstgruppen einsehen (Alle) `churchservice:view servicegroup(-1)`
- Events > Events von einzelnen Kalendern sehen (Alle) `churchservice:view events(-1)`
Expand Down Expand Up @@ -156,18 +158,21 @@ The following instructions are written for Windows but generally also apply to L

### Backend
- Visual Studio 2022
- .NET SDK 7.0
- .NET SDK 8.0
- EF Core CLI Tools _(e.g. `dotnet tool install -g dotnet-ef`)_
- MySQL or MariaDB _(e.g. from [PSModules](https://github.com/daniel-lerch/psmodules))_

### Frontend
- Visual Studio Code
- Vue Language Features (Volar) Extension
- NodeJS 18 LTS
- NodeJS 22 LTS

During development the frontend running on the Vue CLI development server will use _http://localhost:50805_ as API endpoint.
During development the frontend running on the Vue CLI development server will use _http://localhost:10501_ as API endpoint.
That means the backend can be running in Visual Studio with Debugger attached.

If you just want to work on the frontend you can also use a public test server by creating a file `webapp/.env.development.local`
to override the defaults with `VUE_APP_API_URL=https://lerchen.net/korga`.
```env
VITE_API_ORIGIN=https://lerchen.net
VITE_API_BASE_PATH=/korga/
```
Then you don't have to setup a database server and the ASP.NET Core backend.
17 changes: 15 additions & 2 deletions docs/docker-compose.yml → docs/compose.yaml
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
version: '2.1'

services:
app:
image: daniellerch/korga:latest
restart: unless-stopped
mem_limit: 512m
environment:
# Change this according to your database settings
- Database__ConnectionString=Server=db;Port=3306;Database=korga;User=korga;Password=korga;
Expand Down Expand Up @@ -38,13 +37,27 @@ services:
#- EmailRelay__ImapHost=imap.example.org
#- [email protected]
#- EmailRelay__ImapPassword=RKXMaQWm8k7QKFnmijma
depends_on:
db:
condition: service_healthy
db:
image: mariadb:latest
restart: unless-stopped
mem_limit: 512m
environment:
- MYSQL_ROOT_PASSWORD=root
- MYSQL_DATABASE=korga
- MYSQL_USER=korga
- MYSQL_PASSWORD=korga
volumes:
- ./data/mysql:/var/lib/mysql

# This healthcheck will only work for newly initialized databases with a healthcheck user
# To configure it manually, refer to https://stackoverflow.com/a/76089040/7075733
healthcheck:
test: [ "CMD", "healthcheck.sh", "--su-mysql", "--connect", "--innodb_initialized" ]
interval: 1m30s
timeout: 10s
retries: 3
start_period: 30s
start_interval: 1s
9 changes: 9 additions & 0 deletions server/ChurchTools/ChurchTools.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<Nullable>enable</Nullable>
<RootNamespace>ChurchTools</RootNamespace>
</PropertyGroup>

</Project>
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using Korga.ChurchTools.Api;
using ChurchTools.Model;
using System;
using System.Collections.Generic;
using System.IO;
Expand All @@ -10,7 +10,7 @@
using System.Threading;
using System.Threading.Tasks;

namespace Korga.ChurchTools;
namespace ChurchTools;

public class ChurchToolsApi : IChurchToolsApi, IDisposable
{
Expand Down Expand Up @@ -92,9 +92,14 @@ public ValueTask<List<Group>> GetGroups(IEnumerable<int> groupStatuses, Cancella
return InternalGetAllPages<Group>("/api/groups", query.ToString(), cancellationToken);
}

public ValueTask<List<GroupMember>> GetGroupMembers(CancellationToken cancellationToken = default)
public ValueTask<List<GroupsMember>> GetGroupMembers(CancellationToken cancellationToken = default)
{
return InternalGetNonPaged<List<GroupMember>>("/api/groups/members", cancellationToken);
return InternalGetNonPaged<List<GroupsMember>>("/api/groups/members", cancellationToken);
}

public ValueTask<List<GroupMember>> GetGroupMembers(int groupId, CancellationToken cancellationToken = default)
{
return InternalGetAllPages<GroupMember>($"/api/groups/{groupId}/members", null, cancellationToken);
}

public ValueTask<List<Person>> GetPeople(CancellationToken cancellationToken = default)
Expand Down Expand Up @@ -164,7 +169,7 @@ private async ValueTask<T> InternalGetNonPaged<T>(string path, CancellationToken

private async ValueTask<List<T>> InternalGetAllPages<T>(string path, string? query, CancellationToken cancellationToken)
{
List<T> items = new();
List<T> items = [];
PaginatedResponse<T[]>? response;
int page = 0;

Expand Down
Original file line number Diff line number Diff line change
@@ -1,17 +1,18 @@
using Korga.ChurchTools.Api;
using ChurchTools.Model;
using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;

namespace Korga.ChurchTools;
namespace ChurchTools;

public interface IChurchToolsApi : IDisposable
{
Login? User { get; }
ValueTask<List<Group>> GetGroups(CancellationToken cancellationToken = default);
ValueTask<List<Group>> GetGroups(IEnumerable<int> groupStatuses, CancellationToken cancellationToken = default);
ValueTask<List<GroupMember>> GetGroupMembers(CancellationToken cancellationToken = default);
ValueTask<List<GroupsMember>> GetGroupMembers(CancellationToken cancellationToken = default);
ValueTask<List<GroupMember>> GetGroupMembers(int groupId, CancellationToken cancellationToken = default);
ValueTask<List<Person>> GetPeople(CancellationToken cancellationToken = default);
ValueTask<Person> GetPerson(CancellationToken cancellationToken = default);
ValueTask<Person> GetPerson(int personId, CancellationToken cancellationToken = default);
Expand Down
10 changes: 10 additions & 0 deletions server/ChurchTools/Model/DomainObject.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
using System.Collections.Generic;
using System.Text.Json.Nodes;

namespace ChurchTools.Model;

public record DomainObject(
string Title,
string DomainType,
string DomainIdentifier,
Dictionary<string, JsonValue> DomainAttributes);
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
using System;
using System.Collections.Generic;

namespace Korga.ChurchTools.Api;
namespace ChurchTools.Model;

public class Event
{
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
using System.Collections.Generic;
using System.Text.Json.Serialization;

namespace Korga.ChurchTools.Api;
namespace ChurchTools.Model;

public class GlobalPermissions
{
Expand Down
Loading

0 comments on commit 34feaf6

Please sign in to comment.