mirror of
https://github.com/steveiliop56/tinyauth.git
synced 2026-07-03 08:40:14 +00:00
Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 1fcac1b2f7 |
+17
-17
@@ -220,23 +220,6 @@ TINYAUTH_LDAP_AUTHCERT=
|
||||
TINYAUTH_LDAP_AUTHKEY=
|
||||
# Cache duration for LDAP group membership in seconds.
|
||||
TINYAUTH_LDAP_GROUPCACHETTL=900
|
||||
|
||||
# experimental config
|
||||
|
||||
# Enable Tailscale integration.
|
||||
TINYAUTH_EXPERIMENTAL_TAILSCALE_ENABLED=false
|
||||
# Tailscale state directory.
|
||||
TINYAUTH_EXPERIMENTAL_TAILSCALE_DIR="./tailscale_state"
|
||||
# Tailscale hostname.
|
||||
TINYAUTH_EXPERIMENTAL_TAILSCALE_HOSTNAME=
|
||||
# Tailscale auth key.
|
||||
TINYAUTH_EXPERIMENTAL_TAILSCALE_AUTHKEY=
|
||||
# Use ephemeral Tailscale node.
|
||||
TINYAUTH_EXPERIMENTAL_TAILSCALE_EPHEMERAL=false
|
||||
# Enable Tailscale Funnel.
|
||||
TINYAUTH_EXPERIMENTAL_TAILSCALE_FUNNEL=false
|
||||
# Listen on the Tailscale address instead of standard address.
|
||||
TINYAUTH_EXPERIMENTAL_TAILSCALE_LISTEN=false
|
||||
# Label provider to use for ACLs (auto, docker, kubernetes or none to disable). auto detects the environment.
|
||||
TINYAUTH_LABELPROVIDER="auto"
|
||||
|
||||
@@ -258,3 +241,20 @@ TINYAUTH_LOG_STREAMS_APP_LEVEL=
|
||||
TINYAUTH_LOG_STREAMS_AUDIT_ENABLED=false
|
||||
# Log level for this stream. Use global if empty.
|
||||
TINYAUTH_LOG_STREAMS_AUDIT_LEVEL=
|
||||
|
||||
# tailscale config
|
||||
|
||||
# Enable Tailscale integration.
|
||||
TINYAUTH_TAILSCALE_ENABLED=false
|
||||
# Tailscale state directory.
|
||||
TINYAUTH_TAILSCALE_DIR="./tailscale_state"
|
||||
# Tailscale hostname.
|
||||
TINYAUTH_TAILSCALE_HOSTNAME=
|
||||
# Tailscale auth key.
|
||||
TINYAUTH_TAILSCALE_AUTHKEY=
|
||||
# Use ephemeral Tailscale node.
|
||||
TINYAUTH_TAILSCALE_EPHEMERAL=false
|
||||
# Enable Tailscale Funnel.
|
||||
TINYAUTH_TAILSCALE_FUNNEL=false
|
||||
# Listen on the Tailscale address instead of standard address.
|
||||
TINYAUTH_TAILSCALE_LISTEN=false
|
||||
|
||||
@@ -38,7 +38,7 @@ jobs:
|
||||
sqlc generate
|
||||
go generate ./...
|
||||
git diff --exit-code
|
||||
git status --porcelain | grep -q . && echo "untracked files code gen files" && exit 1 || true
|
||||
git status --porcelain | grep -q . && echo "untracked files in git diff" && exit 1 || true
|
||||
|
||||
- name: Install frontend dependencies
|
||||
working-directory: ./frontend
|
||||
|
||||
@@ -163,7 +163,7 @@ jobs:
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@bb05f3f5519dd87d3ba754cc423b652a5edd6d2c # v4
|
||||
uses: docker/setup-buildx-action@d7f5e7f509e45cec5c76c4d5afdd7de93d0b3df5 # v4
|
||||
|
||||
- name: Build and push
|
||||
uses: docker/build-push-action@f9f3042f7e2789586610d6e8b85c8f03e5195baf # v7
|
||||
@@ -221,7 +221,7 @@ jobs:
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@bb05f3f5519dd87d3ba754cc423b652a5edd6d2c # v4
|
||||
uses: docker/setup-buildx-action@d7f5e7f509e45cec5c76c4d5afdd7de93d0b3df5 # v4
|
||||
|
||||
- name: Build and push
|
||||
uses: docker/build-push-action@f9f3042f7e2789586610d6e8b85c8f03e5195baf # v7
|
||||
@@ -279,7 +279,7 @@ jobs:
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@bb05f3f5519dd87d3ba754cc423b652a5edd6d2c # v4
|
||||
uses: docker/setup-buildx-action@d7f5e7f509e45cec5c76c4d5afdd7de93d0b3df5 # v4
|
||||
|
||||
- name: Build and push
|
||||
uses: docker/build-push-action@f9f3042f7e2789586610d6e8b85c8f03e5195baf # v7
|
||||
@@ -337,7 +337,7 @@ jobs:
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@bb05f3f5519dd87d3ba754cc423b652a5edd6d2c # v4
|
||||
uses: docker/setup-buildx-action@d7f5e7f509e45cec5c76c4d5afdd7de93d0b3df5 # v4
|
||||
|
||||
- name: Build and push
|
||||
uses: docker/build-push-action@f9f3042f7e2789586610d6e8b85c8f03e5195baf # v7
|
||||
@@ -391,7 +391,7 @@ jobs:
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@bb05f3f5519dd87d3ba754cc423b652a5edd6d2c # v4
|
||||
uses: docker/setup-buildx-action@d7f5e7f509e45cec5c76c4d5afdd7de93d0b3df5 # v4
|
||||
|
||||
- name: Docker meta
|
||||
id: meta
|
||||
@@ -430,7 +430,7 @@ jobs:
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@bb05f3f5519dd87d3ba754cc423b652a5edd6d2c # v4
|
||||
uses: docker/setup-buildx-action@d7f5e7f509e45cec5c76c4d5afdd7de93d0b3df5 # v4
|
||||
|
||||
- name: Docker meta
|
||||
id: meta
|
||||
|
||||
@@ -133,7 +133,7 @@ jobs:
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@bb05f3f5519dd87d3ba754cc423b652a5edd6d2c # v4
|
||||
uses: docker/setup-buildx-action@d7f5e7f509e45cec5c76c4d5afdd7de93d0b3df5 # v4
|
||||
|
||||
- name: Build and push
|
||||
uses: docker/build-push-action@f9f3042f7e2789586610d6e8b85c8f03e5195baf # v7
|
||||
@@ -189,7 +189,7 @@ jobs:
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@bb05f3f5519dd87d3ba754cc423b652a5edd6d2c # v4
|
||||
uses: docker/setup-buildx-action@d7f5e7f509e45cec5c76c4d5afdd7de93d0b3df5 # v4
|
||||
|
||||
- name: Build and push
|
||||
uses: docker/build-push-action@f9f3042f7e2789586610d6e8b85c8f03e5195baf # v7
|
||||
@@ -245,7 +245,7 @@ jobs:
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@bb05f3f5519dd87d3ba754cc423b652a5edd6d2c # v4
|
||||
uses: docker/setup-buildx-action@d7f5e7f509e45cec5c76c4d5afdd7de93d0b3df5 # v4
|
||||
|
||||
- name: Build and push
|
||||
uses: docker/build-push-action@f9f3042f7e2789586610d6e8b85c8f03e5195baf # v7
|
||||
@@ -301,7 +301,7 @@ jobs:
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@bb05f3f5519dd87d3ba754cc423b652a5edd6d2c # v4
|
||||
uses: docker/setup-buildx-action@d7f5e7f509e45cec5c76c4d5afdd7de93d0b3df5 # v4
|
||||
|
||||
- name: Build and push
|
||||
uses: docker/build-push-action@f9f3042f7e2789586610d6e8b85c8f03e5195baf # v7
|
||||
@@ -356,7 +356,7 @@ jobs:
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@bb05f3f5519dd87d3ba754cc423b652a5edd6d2c # v4
|
||||
uses: docker/setup-buildx-action@d7f5e7f509e45cec5c76c4d5afdd7de93d0b3df5 # v4
|
||||
|
||||
- name: Docker meta
|
||||
id: meta
|
||||
@@ -397,7 +397,7 @@ jobs:
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@bb05f3f5519dd87d3ba754cc423b652a5edd6d2c # v4
|
||||
uses: docker/setup-buildx-action@d7f5e7f509e45cec5c76c4d5afdd7de93d0b3df5 # v4
|
||||
|
||||
- name: Docker meta
|
||||
id: meta
|
||||
|
||||
@@ -51,6 +51,3 @@ config.certify.yml
|
||||
|
||||
# deepsec
|
||||
/.deepsec
|
||||
|
||||
# jetbrains
|
||||
/.idea/
|
||||
+5
-7
@@ -52,17 +52,15 @@ WORKDIR /tinyauth
|
||||
|
||||
COPY --from=builder /tinyauth/tinyauth ./
|
||||
|
||||
EXPOSE 3000
|
||||
RUN mkdir -p /data
|
||||
|
||||
# Make the data directory with a non-root user
|
||||
RUN addgroup tinyauth && adduser -DH tinyauth -G tinyauth
|
||||
RUN mkdir -p /data/resources /data/oidc /data/tailscale
|
||||
RUN chown -R tinyauth:tinyauth /data
|
||||
EXPOSE 3000
|
||||
|
||||
VOLUME ["/data"]
|
||||
|
||||
# Tell tinyauth that it's running in a container and where to find the data directory
|
||||
ENV RUNTIME_ENV=docker
|
||||
ENV TINYAUTH_DATABASE_PATH=/data/tinyauth.db
|
||||
|
||||
ENV TINYAUTH_RESOURCES_PATH=/data/resources
|
||||
|
||||
ENV PATH=$PATH:/tinyauth
|
||||
|
||||
|
||||
@@ -40,16 +40,13 @@ COPY ./cmd ./cmd
|
||||
COPY ./internal ./internal
|
||||
COPY --from=frontend-builder /frontend/dist ./internal/assets/dist
|
||||
|
||||
RUN mkdir -p data
|
||||
|
||||
RUN CGO_ENABLED=0 go build -ldflags "${LDFLAGS} \
|
||||
-X github.com/tinyauthapp/tinyauth/internal/model.Version=${VERSION} \
|
||||
-X github.com/tinyauthapp/tinyauth/internal/model.CommitHash=${COMMIT_HASH} \
|
||||
-X github.com/tinyauthapp/tinyauth/internal/model.BuildTimestamp=${BUILD_TIMESTAMP}" ./cmd/tinyauth
|
||||
|
||||
# Make the data directory with a non-root user
|
||||
RUN addgroup tinyauth && adduser -DH tinyauth -G tinyauth
|
||||
RUN mkdir -p /data/resources /data/oidc /data/tailscale
|
||||
RUN chown -R tinyauth:tinyauth /data
|
||||
|
||||
# Runner
|
||||
FROM gcr.io/distroless/static-debian12:latest AS runner
|
||||
|
||||
@@ -58,14 +55,15 @@ WORKDIR /tinyauth
|
||||
COPY --from=builder /tinyauth/tinyauth ./
|
||||
|
||||
# Since it's distroless, we need to copy the data directory from the builder stage
|
||||
COPY --from=builder /data /data
|
||||
COPY --from=builder /tinyauth/data /data
|
||||
|
||||
EXPOSE 3000
|
||||
|
||||
VOLUME ["/data"]
|
||||
|
||||
# Tell tinyauth that it's running in a container and where to find the data directory
|
||||
ENV RUNTIME_ENV=docker
|
||||
ENV TINYAUTH_DATABASE_PATH=/data/tinyauth.db
|
||||
|
||||
ENV TINYAUTH_RESOURCES_PATH=/data/resources
|
||||
|
||||
ENV PATH=$PATH:/tinyauth
|
||||
|
||||
|
||||
@@ -16,8 +16,6 @@ PROD_COMPOSE := $(shell test -f "docker-compose.test.prod.yml" && echo "docker-c
|
||||
|
||||
.DEFAULT_GOAL := binary
|
||||
|
||||
.PHONY: deps clean-data clean-webui webui binary binary-linux-amd64 binary-linux-arm64 test vet test-race dev dev-infisical prod prod-infisical sql generate docker docker-distroless
|
||||
|
||||
# Deps
|
||||
deps:
|
||||
cd frontend && pnpm ci
|
||||
@@ -60,10 +58,12 @@ binary-linux-arm64:
|
||||
$(MAKE) binary
|
||||
|
||||
# Go test
|
||||
.PHONY: test
|
||||
test:
|
||||
go test -v ./...
|
||||
|
||||
# Go vet
|
||||
.PHONY: vet
|
||||
vet:
|
||||
go vet ./...
|
||||
|
||||
@@ -88,17 +88,10 @@ prod-infisical:
|
||||
infisical run --env=dev -- docker compose -f $(PROD_COMPOSE) up --force-recreate --pull=always --remove-orphans
|
||||
|
||||
# SQL
|
||||
.PHONY: sql
|
||||
sql:
|
||||
sqlc generate
|
||||
|
||||
# Go gen
|
||||
generate:
|
||||
go generate ./...
|
||||
|
||||
# Docker image
|
||||
docker:
|
||||
docker buildx build -t tinyauthapp/tinyauth:dev --build-arg=VERSION=$(TAG_NAME) --build-arg=COMMIT_HASH=$(COMMIT_HASH) --build-arg=BUILD_TIMESTAMP=$(BUILD_TIMESTAMP) -f Dockerfile .
|
||||
|
||||
# Docker image distroless
|
||||
docker-distroless:
|
||||
docker buildx build -t tinyauthapp/tinyauth:dev-distroless --build-arg=VERSION=$(TAG_NAME) --build-arg=COMMIT_HASH=$(COMMIT_HASH) --build-arg=BUILD_TIMESTAMP=$(BUILD_TIMESTAMP) -f Dockerfile.distroless .
|
||||
|
||||
@@ -1,26 +0,0 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
|
||||
"github.com/tinyauthapp/paerser/cli"
|
||||
"github.com/tinyauthapp/tinyauth/internal/model"
|
||||
)
|
||||
|
||||
func configCmd(tconfig *model.Config, loaders []cli.ResourceLoader) *cli.Command {
|
||||
return &cli.Command{
|
||||
Name: "config",
|
||||
Description: "Print the configuration of Tinyauth",
|
||||
Configuration: tconfig,
|
||||
Resources: loaders,
|
||||
Run: func(_ []string) error {
|
||||
jsonBytes, err := json.MarshalIndent(tconfig, "", " ")
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to marshal configuration: %w", err)
|
||||
}
|
||||
fmt.Println(string(jsonBytes))
|
||||
return nil
|
||||
},
|
||||
}
|
||||
}
|
||||
@@ -13,8 +13,7 @@ import (
|
||||
)
|
||||
|
||||
func main() {
|
||||
env := model.DetectRuntimeEnv()
|
||||
tConfig := model.NewDefaultConfiguration(env)
|
||||
tConfig := model.NewDefaultConfiguration()
|
||||
|
||||
loaders := []cli.ResourceLoader{
|
||||
&loaders.FileLoader{},
|
||||
@@ -53,12 +52,6 @@ func main() {
|
||||
log.Fatal().Err(err).Msg("Failed to add version command")
|
||||
}
|
||||
|
||||
err = cmdTinyauth.AddCommand(configCmd(tConfig, loaders))
|
||||
|
||||
if err != nil {
|
||||
log.Fatal().Err(err).Msg("Failed to add config command")
|
||||
}
|
||||
|
||||
err = cmdUser.AddCommand(verifyUserCmd())
|
||||
|
||||
if err != nil {
|
||||
|
||||
@@ -51,6 +51,7 @@
|
||||
"eslint-plugin-react-hooks": "^7.0.1",
|
||||
"eslint-plugin-react-refresh": "^0.5.2",
|
||||
"globals": "^17.5.0",
|
||||
"prettier": "3.8.2",
|
||||
"rollup-plugin-visualizer": "^7.0.1",
|
||||
"tw-animate-css": "^1.4.0",
|
||||
"typescript": "~6.0.2",
|
||||
|
||||
Generated
+10
@@ -120,6 +120,9 @@ importers:
|
||||
globals:
|
||||
specifier: ^17.5.0
|
||||
version: 17.6.0
|
||||
prettier:
|
||||
specifier: 3.8.2
|
||||
version: 3.8.2
|
||||
rollup-plugin-visualizer:
|
||||
specifier: ^7.0.1
|
||||
version: 7.0.1(rolldown@1.0.1)
|
||||
@@ -2145,6 +2148,11 @@ packages:
|
||||
resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==}
|
||||
engines: {node: '>= 0.8.0'}
|
||||
|
||||
prettier@3.8.2:
|
||||
resolution: {integrity: sha512-8c3mgTe0ASwWAJK+78dpviD+A8EqhndQPUBpNUIPt6+xWlIigCwfN01lWr9MAede4uqXGTEKeQWTvzb3vjia0Q==}
|
||||
engines: {node: '>=14'}
|
||||
hasBin: true
|
||||
|
||||
property-information@7.1.0:
|
||||
resolution: {integrity: sha512-TwEZ+X+yCJmYfL7TPUOcvBZ4QfoT5YenQiJuX//0th53DE6w0xxLEtfK3iyryQFddXuvkIk51EEgrJQ0WJkOmQ==}
|
||||
|
||||
@@ -4650,6 +4658,8 @@ snapshots:
|
||||
|
||||
prelude-ls@1.2.1: {}
|
||||
|
||||
prettier@3.8.2: {}
|
||||
|
||||
property-information@7.1.0: {}
|
||||
|
||||
proxy-from-env@2.1.0: {}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
dangerouslyAllowAllBuilds: false
|
||||
blockExoticSubdeps: true
|
||||
minimumReleaseAge: 1440 # 1 day
|
||||
minimumReleaseAge: 1440 # 1 day
|
||||
trustPolicy: no-downgrade
|
||||
|
||||
@@ -0,0 +1,131 @@
|
||||
// gen/context_paths generates the ignore paths for the user context since
|
||||
// gin will not less apply the middleware to only specific paths.
|
||||
//
|
||||
// The generator reads every controller and looks for the //context:ignore comment.
|
||||
// The format for the context ignore comment is:
|
||||
//
|
||||
// //contxt:ignore /api/mypath GET,POST
|
||||
package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"go/format"
|
||||
"os"
|
||||
"strings"
|
||||
"text/template"
|
||||
|
||||
_ "embed"
|
||||
|
||||
"golang.org/x/tools/go/packages"
|
||||
)
|
||||
|
||||
//go:embed paths.tmpl
|
||||
var pathsTmplSrc string
|
||||
|
||||
var pathsTmpl = template.Must(template.New("paths").Parse(pathsTmplSrc))
|
||||
|
||||
func main() {
|
||||
if err := run(); err != nil {
|
||||
fmt.Printf("Failed to generate: %s", err.Error())
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
|
||||
func run() error {
|
||||
// load pkg
|
||||
pkgConfig := &packages.Config{
|
||||
Mode: packages.NeedFiles,
|
||||
}
|
||||
|
||||
pkgs, err := packages.Load(pkgConfig, "github.com/tinyauthapp/tinyauth/internal/controller")
|
||||
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to load pkg: %w", err)
|
||||
}
|
||||
|
||||
if len(pkgs) == 0 {
|
||||
return fmt.Errorf("failed to get controllers package")
|
||||
}
|
||||
|
||||
pkg := pkgs[0]
|
||||
|
||||
// for each file we check the comments and either add or remove the context
|
||||
var contextIgnorePaths []string
|
||||
|
||||
for _, gofile := range pkg.GoFiles {
|
||||
// read the file
|
||||
file, err := os.ReadFile(gofile)
|
||||
|
||||
if err != nil {
|
||||
fmt.Printf("Failed to read %s, ignoring", gofile)
|
||||
continue
|
||||
}
|
||||
|
||||
// get the comment lines
|
||||
lines := strings.SplitSeq(string(file), "\n")
|
||||
|
||||
for line := range lines {
|
||||
if !strings.HasPrefix(strings.TrimSpace(line), "//context:ignore") {
|
||||
continue
|
||||
}
|
||||
|
||||
path, methods, ok := parseContextIgnoreLine(line)
|
||||
|
||||
if !ok {
|
||||
fmt.Printf("Failed to parse %s rule, ignore", line)
|
||||
continue
|
||||
}
|
||||
|
||||
for _, m := range methods {
|
||||
contextIgnorePaths = append(contextIgnorePaths, m+" "+path)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// generate out
|
||||
type tmplData struct {
|
||||
IgnorePaths []string
|
||||
}
|
||||
|
||||
var buf bytes.Buffer
|
||||
|
||||
if err := pathsTmpl.Execute(&buf, tmplData{
|
||||
IgnorePaths: contextIgnorePaths,
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
formatted, err := format.Source(buf.Bytes())
|
||||
|
||||
if err != nil {
|
||||
return fmt.Errorf("gofmt failed: %w", err)
|
||||
}
|
||||
|
||||
// write out
|
||||
err = os.WriteFile("context_paths.go", formatted, 0666)
|
||||
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to write out: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func parseContextIgnoreLine(line string) (string, []string, bool) {
|
||||
line = strings.TrimPrefix(line, "//context:ignore ")
|
||||
path, methodStr, ok := strings.Cut(line, " ")
|
||||
if !ok {
|
||||
return "", []string{}, false
|
||||
}
|
||||
var methodsParsed []string
|
||||
methodParts := strings.SplitSeq(methodStr, ",")
|
||||
for m := range methodParts {
|
||||
if strings.TrimSpace(m) == "" {
|
||||
continue
|
||||
}
|
||||
m = strings.ToUpper(m)
|
||||
methodsParsed = append(methodsParsed, m)
|
||||
}
|
||||
return path, methodsParsed, true
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
// Code generated by gen/context_paths. DO NOT EDIT.
|
||||
package middleware
|
||||
|
||||
var contextSkipPathsPrefix = []string{
|
||||
{{range .IgnorePaths}}"{{.}}",
|
||||
{{end}}}
|
||||
@@ -1,3 +1,9 @@
|
||||
// gen/docs generates the .env.example and config.gen.md
|
||||
// files for the configuration of Tinyauth. Run via:
|
||||
//
|
||||
// The generator reads the Tinyauth configuration package and using reflection it generates the
|
||||
// example files. The .env.example is used in this repo while the config.gen.md is used in the
|
||||
// documentaton alongside some warnings that are added later.
|
||||
package main
|
||||
|
||||
import (
|
||||
+1
-1
@@ -20,7 +20,7 @@ type EnvEntry struct {
|
||||
}
|
||||
|
||||
func generateExampleEnv() {
|
||||
cfg := model.NewDefaultConfiguration(model.RuntimeEnvUnknown)
|
||||
cfg := model.NewDefaultConfiguration()
|
||||
entries := make([]EnvEntry, 0)
|
||||
|
||||
root := reflect.TypeOf(cfg).Elem()
|
||||
|
||||
+1
-1
@@ -21,7 +21,7 @@ type MarkdownEntry struct {
|
||||
}
|
||||
|
||||
func generateMarkdown() {
|
||||
cfg := model.NewDefaultConfiguration(model.RuntimeEnvUnknown)
|
||||
cfg := model.NewDefaultConfiguration()
|
||||
entries := make([]MarkdownEntry, 0)
|
||||
|
||||
root := reflect.TypeOf(cfg).Elem()
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
// gen/sqlc_wrapper generates store.go wrapper files for each sqlc driver package under
|
||||
// internal/repository/<driver>/. Run via:
|
||||
//
|
||||
// go generate ./internal/repository/...
|
||||
// internal/repository/<driver>/.
|
||||
//
|
||||
// The generator introspects *Queries methods and the model/params types in the
|
||||
// driver package, then emits a store.go that wraps *Queries so it satisfies
|
||||
@@ -32,7 +30,7 @@ import (
|
||||
var storeSrc string
|
||||
|
||||
func main() {
|
||||
fmt.Println("sqlc_wrapper: generating store.go files for sqlc driver packages...")
|
||||
fmt.Println("sqlc-wrapper: generating store.go files for sqlc driver packages...")
|
||||
if err := run(); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Code generated by cmd/gen/sqlc-wrapper. DO NOT EDIT.
|
||||
// Code generated by cmd/gen/sqlc_wrapper. DO NOT EDIT.
|
||||
package {{.PkgName}}
|
||||
|
||||
import (
|
||||
|
||||
+1
-1
@@ -1,3 +1,3 @@
|
||||
package tinyauth
|
||||
package docs
|
||||
|
||||
//go:generate go run github.com/tinyauthapp/tinyauth/gen/docs
|
||||
|
||||
@@ -279,7 +279,7 @@ func (app *BootstrapApp) Setup() error {
|
||||
app.runtime.ConfiguredProviders = configuredProviders
|
||||
|
||||
// if tailscale is enabled and listening, replace the app url with the tailscale hostname
|
||||
if app.services.tailscaleService != nil && app.config.Experimental.Tailscale.Listen {
|
||||
if app.services.tailscaleService != nil && app.config.Tailscale.Listen {
|
||||
tailscaleUrl := "https://" + app.services.tailscaleService.GetHostname()
|
||||
|
||||
// if the tailscale url is different from the app url, replace it
|
||||
|
||||
@@ -130,9 +130,9 @@ func (app *BootstrapApp) setupRouter() error {
|
||||
// 2. Unix socket (if server.socketPath)
|
||||
// 3. HTTP - default
|
||||
func (app *BootstrapApp) getListenerFunc() (func(ctx context.Context) error, error) {
|
||||
if app.config.Experimental.Tailscale.Listen {
|
||||
if app.config.Tailscale.Listen {
|
||||
if app.services.tailscaleService == nil {
|
||||
return nil, fmt.Errorf("experimental.tailscale.listen is enabled but tailscale service is not initialized")
|
||||
return nil, fmt.Errorf("tailscale.listen is enabled but tailscale service is not initialized")
|
||||
}
|
||||
return app.serveTailscale, nil
|
||||
}
|
||||
@@ -227,6 +227,7 @@ func (app *BootstrapApp) serve(listener net.Listener, server *http.Server, ctx c
|
||||
err := server.Serve(listener)
|
||||
|
||||
if err != nil && !errors.Is(err, http.ErrServerClosed) {
|
||||
shutdown()
|
||||
return fmt.Errorf("failed to start %s listener: %w", name, err)
|
||||
}
|
||||
|
||||
|
||||
@@ -147,6 +147,7 @@ func (controller *ContextController) userContextHandler(c *gin.Context) {
|
||||
c.JSON(200, userContext)
|
||||
}
|
||||
|
||||
//context:ignore /api/context/app GET
|
||||
func (controller *ContextController) appContextHandler(c *gin.Context) {
|
||||
c.JSON(200, AppContextResponse{
|
||||
Status: 200,
|
||||
|
||||
@@ -23,6 +23,7 @@ func NewHealthController(i HealthControllerInput) *HealthController {
|
||||
return controller
|
||||
}
|
||||
|
||||
//context:ignore /api/healthz GET,HEAD
|
||||
func (controller *HealthController) healthHandler(c *gin.Context) {
|
||||
c.JSON(200, gin.H{
|
||||
"status": 200,
|
||||
|
||||
@@ -54,6 +54,7 @@ func NewOAuthController(i OAuthControllerInput) *OAuthController {
|
||||
return controller
|
||||
}
|
||||
|
||||
//context:ignore /api/oauth/url GET
|
||||
func (controller *OAuthController) oauthURLHandler(c *gin.Context) {
|
||||
var req OAuthRequest
|
||||
|
||||
@@ -118,6 +119,7 @@ func (controller *OAuthController) oauthURLHandler(c *gin.Context) {
|
||||
})
|
||||
}
|
||||
|
||||
//context:ignore /api/oauth/callback GET
|
||||
func (controller *OAuthController) oauthCallbackHandler(c *gin.Context) {
|
||||
var req OAuthRequest
|
||||
|
||||
|
||||
@@ -367,6 +367,7 @@ func (controller *OIDCController) authorizeComplete(c *gin.Context) {
|
||||
})
|
||||
}
|
||||
|
||||
//context:ignore /api/oidc/token POST
|
||||
func (controller *OIDCController) Token(c *gin.Context) {
|
||||
if controller.oidc == nil {
|
||||
controller.log.App.Warn().Msg("Received OIDC request but OIDC server is not configured")
|
||||
@@ -538,6 +539,7 @@ func (controller *OIDCController) Token(c *gin.Context) {
|
||||
c.JSON(200, tokenResponse)
|
||||
}
|
||||
|
||||
//context:ignore /api/oidc/userinfo GET,POST
|
||||
func (controller *OIDCController) Userinfo(c *gin.Context) {
|
||||
if controller.oidc == nil {
|
||||
controller.log.App.Warn().Msg("Received OIDC userinfo request but OIDC server is not configured")
|
||||
|
||||
@@ -33,6 +33,7 @@ func NewResourcesController(i ResourcesControllerInput) *ResourcesController {
|
||||
return controller
|
||||
}
|
||||
|
||||
//context:ignore /resources GET
|
||||
func (controller *ResourcesController) resourcesHandler(c *gin.Context) {
|
||||
if controller.config.Resources.Path == "" {
|
||||
c.JSON(404, gin.H{
|
||||
|
||||
@@ -57,6 +57,7 @@ func NewUserController(i UserControllerInput) *UserController {
|
||||
return controller
|
||||
}
|
||||
|
||||
//context:ignore /api/user/login POST
|
||||
func (controller *UserController) loginHandler(c *gin.Context) {
|
||||
var req LoginRequest
|
||||
|
||||
|
||||
@@ -65,6 +65,7 @@ func NewWellKnownController(i WellKnownControllerInput) *WellKnownController {
|
||||
return controller
|
||||
}
|
||||
|
||||
//context:ignore /.well-known/openid-configuration GET
|
||||
func (controller *WellKnownController) OpenIDConnectConfiguration(c *gin.Context) {
|
||||
if controller.oidc == nil {
|
||||
c.JSON(500, gin.H{
|
||||
@@ -94,6 +95,7 @@ func (controller *WellKnownController) OpenIDConnectConfiguration(c *gin.Context
|
||||
})
|
||||
}
|
||||
|
||||
//context:ignore /.well-known/jwks.json GET
|
||||
func (controller *WellKnownController) JWKS(c *gin.Context) {
|
||||
if controller.oidc == nil {
|
||||
c.JSON(500, gin.H{
|
||||
@@ -122,6 +124,7 @@ func (controller *WellKnownController) JWKS(c *gin.Context) {
|
||||
c.Status(http.StatusOK)
|
||||
}
|
||||
|
||||
//context:ignore /.well-known/webfinger GET
|
||||
func (controller *WellKnownController) WebFinger(c *gin.Context) {
|
||||
c.Header("Content-Type", "application/jrd+json")
|
||||
c.Header("Access-Control-Allow-Origin", "*")
|
||||
|
||||
@@ -16,26 +16,6 @@ import (
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
// Gin won't let us set a middleware on a specific route (at least it doesn't work,
|
||||
// see https://github.com/gin-gonic/gin/issues/531) so we have to do some hackery
|
||||
var (
|
||||
contextSkipPathsPrefix = []string{
|
||||
"GET /api/context/app",
|
||||
"GET /api/healthz",
|
||||
"HEAD /api/healthz",
|
||||
"GET /api/oauth/url",
|
||||
"GET /api/oauth/callback",
|
||||
"GET /api/oidc/clients",
|
||||
"POST /api/oidc/token",
|
||||
"GET /api/oidc/userinfo",
|
||||
"POST /api/oidc/userinfo",
|
||||
"GET /resources",
|
||||
"POST /api/user/login",
|
||||
"GET /.well-known/openid-configuration",
|
||||
"GET /.well-known/jwks.json",
|
||||
}
|
||||
)
|
||||
|
||||
type ContextMiddleware struct {
|
||||
log *logger.Logger
|
||||
runtime *model.RuntimeConfig
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
// Code generated by gen/context_paths. DO NOT EDIT.
|
||||
package middleware
|
||||
|
||||
var contextSkipPathsPrefix = []string{
|
||||
"GET /api/context/app",
|
||||
"GET /api/healthz",
|
||||
"HEAD /api/healthz",
|
||||
"GET /api/oauth/url",
|
||||
"GET /api/oauth/callback",
|
||||
"POST /api/oidc/token",
|
||||
"GET /api/oidc/userinfo",
|
||||
"POST /api/oidc/userinfo",
|
||||
"GET /resources",
|
||||
"POST /api/user/login",
|
||||
"GET /.well-known/openid-configuration",
|
||||
"GET /.well-known/jwks.json",
|
||||
"GET /.well-known/webfinger",
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
package middleware
|
||||
|
||||
//go:generate go run github.com/tinyauthapp/tinyauth/gen/context_paths
|
||||
@@ -1,27 +1,8 @@
|
||||
package model
|
||||
|
||||
import "os"
|
||||
|
||||
type RuntimeEnv int
|
||||
|
||||
const (
|
||||
RuntimeEnvUnknown RuntimeEnv = iota
|
||||
RuntimeEnvDocker
|
||||
)
|
||||
|
||||
func DetectRuntimeEnv() RuntimeEnv {
|
||||
env := os.Getenv("RUNTIME_ENV")
|
||||
switch env {
|
||||
case "docker":
|
||||
return RuntimeEnvDocker
|
||||
default:
|
||||
return RuntimeEnvUnknown
|
||||
}
|
||||
}
|
||||
|
||||
// Default configuration
|
||||
func NewDefaultConfiguration(runtimeEnv RuntimeEnv) *Config {
|
||||
cfg := &Config{
|
||||
func NewDefaultConfiguration() *Config {
|
||||
return &Config{
|
||||
Database: DatabaseConfig{
|
||||
Driver: "sqlite",
|
||||
Path: "./tinyauth.db",
|
||||
@@ -81,24 +62,11 @@ func NewDefaultConfiguration(runtimeEnv RuntimeEnv) *Config {
|
||||
PrivateKeyPath: "./tinyauth_oidc_key",
|
||||
PublicKeyPath: "./tinyauth_oidc_key.pub",
|
||||
},
|
||||
Experimental: ExperimentalConfig{
|
||||
Tailscale: TailscaleConfig{
|
||||
Dir: "./tailscale_state",
|
||||
},
|
||||
Tailscale: TailscaleConfig{
|
||||
Dir: "./tailscale_state",
|
||||
},
|
||||
LabelProvider: "auto",
|
||||
}
|
||||
|
||||
// apply path overrides for docker runtime
|
||||
if runtimeEnv == RuntimeEnvDocker {
|
||||
cfg.Database.Path = "/data/tinyauth.db"
|
||||
cfg.Resources.Path = "/data/resources"
|
||||
cfg.OIDC.PrivateKeyPath = "/data/oidc/key.pem"
|
||||
cfg.OIDC.PublicKeyPath = "/data/oidc/key.pub"
|
||||
cfg.Experimental.Tailscale.Dir = "/data/tailscale"
|
||||
}
|
||||
|
||||
return cfg
|
||||
}
|
||||
|
||||
type Config struct {
|
||||
@@ -116,6 +84,7 @@ type Config struct {
|
||||
Experimental ExperimentalConfig `description:"Experimental features, use with caution." yaml:"experimental"`
|
||||
LabelProvider string `description:"Label provider to use for ACLs (auto, docker, kubernetes or none to disable). auto detects the environment." yaml:"labelProvider"`
|
||||
Log LogConfig `description:"Logging configuration." yaml:"log"`
|
||||
Tailscale TailscaleConfig `description:"Tailscale configuration." yaml:"tailscale"`
|
||||
ConfigFile string `description:"Path to config file." yaml:"-"`
|
||||
}
|
||||
|
||||
@@ -238,9 +207,8 @@ type LogStreamConfig struct {
|
||||
Level string `description:"Log level for this stream. Use global if empty." yaml:"level"`
|
||||
}
|
||||
|
||||
type ExperimentalConfig struct {
|
||||
Tailscale TailscaleConfig `description:"Tailscale configuration." yaml:"tailscale"`
|
||||
}
|
||||
// no experimental features
|
||||
type ExperimentalConfig struct{}
|
||||
|
||||
type TailscaleConfig struct {
|
||||
Enabled bool `description:"Enable Tailscale integration." yaml:"enabled"`
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Code generated by cmd/gen/sqlc-wrapper. DO NOT EDIT.
|
||||
// Code generated by cmd/gen/sqlc_wrapper. DO NOT EDIT.
|
||||
package postgres
|
||||
|
||||
import (
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Code generated by cmd/gen/sqlc-wrapper. DO NOT EDIT.
|
||||
// Code generated by cmd/gen/sqlc_wrapper. DO NOT EDIT.
|
||||
package sqlite
|
||||
|
||||
import (
|
||||
|
||||
@@ -45,17 +45,17 @@ type TailscaleServiceInput struct {
|
||||
}
|
||||
|
||||
func NewTailscaleService(i TailscaleServiceInput) (*TailscaleService, error) {
|
||||
if !i.Config.Experimental.Tailscale.Enabled {
|
||||
if !i.Config.Tailscale.Enabled {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
srv := new(tsnet.Server)
|
||||
|
||||
// node options
|
||||
srv.Dir = i.Config.Experimental.Tailscale.Dir
|
||||
srv.Hostname = i.Config.Experimental.Tailscale.Hostname
|
||||
srv.AuthKey = i.Config.Experimental.Tailscale.AuthKey
|
||||
srv.Ephemeral = i.Config.Experimental.Tailscale.Ephemeral
|
||||
srv.Dir = i.Config.Tailscale.Dir
|
||||
srv.Hostname = i.Config.Tailscale.Hostname
|
||||
srv.AuthKey = i.Config.Tailscale.AuthKey
|
||||
srv.Ephemeral = i.Config.Tailscale.Ephemeral
|
||||
|
||||
// redirect logs to zerolog
|
||||
srv.Logf = i.Log.App.Printf
|
||||
@@ -94,7 +94,7 @@ func NewTailscaleService(i TailscaleServiceInput) (*TailscaleService, error) {
|
||||
|
||||
i.Ding.Go(service.watchAndClose, ding.RingMajor)
|
||||
|
||||
if i.Config.Experimental.Tailscale.Funnel && !i.Config.Experimental.Tailscale.Listen {
|
||||
if i.Config.Tailscale.Funnel && !i.Config.Tailscale.Listen {
|
||||
service.log.App.Warn().Msg("Tailscale Funnel is enabled but listen is disabled. Funnel will not work without listen enabled.")
|
||||
}
|
||||
|
||||
@@ -153,7 +153,7 @@ func (ts *TailscaleService) CreateListener() (net.Listener, error) {
|
||||
return *ts.ln, nil
|
||||
}
|
||||
|
||||
if ts.config.Experimental.Tailscale.Funnel {
|
||||
if ts.config.Tailscale.Funnel {
|
||||
ln, err := ts.srv.ListenFunnel("tcp", ":443")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
||||
Reference in New Issue
Block a user