latest
This commit is contained in:
parent
8b2d298488
commit
635f2650e9
25
.drone.yml
Normal file
25
.drone.yml
Normal file
@ -0,0 +1,25 @@
|
||||
kind: pipeline
|
||||
name: test-docker-build
|
||||
|
||||
steps:
|
||||
- name: golangci-lint
|
||||
image: git.eeqj.de/sneak/drone-golangci-lint:2024-06-01
|
||||
- name: test-docker-build
|
||||
image: plugins/docker
|
||||
network_mode: bridge
|
||||
settings:
|
||||
repo: sneak/directory
|
||||
dry_run: true
|
||||
tags:
|
||||
- ${DRONE_COMMIT_SHA}
|
||||
- ${DRONE_BRANCH}
|
||||
- name: notify
|
||||
image: plugins/slack
|
||||
secrets: [SLACK_WEBHOOK]
|
||||
settings:
|
||||
webhook: $SLACK_WEBHOOK
|
||||
link_names: true
|
||||
when:
|
||||
status:
|
||||
- success
|
||||
- failure
|
1
Makefile
1
Makefile
@ -13,7 +13,6 @@ commit: fmt lint
|
||||
git commit -a
|
||||
|
||||
fmt:
|
||||
gofumpt -l -w .
|
||||
golangci-lint run --fix
|
||||
|
||||
lint:
|
||||
|
45
assets/embed.go
Normal file
45
assets/embed.go
Normal file
@ -0,0 +1,45 @@
|
||||
package assets
|
||||
|
||||
import (
|
||||
"embed"
|
||||
"net/http"
|
||||
|
||||
"github.com/CloudyKit/jet/v6"
|
||||
)
|
||||
|
||||
//go:embed templates/*.jet
|
||||
var templatesFS embed.FS
|
||||
|
||||
//go:embed static/*
|
||||
var staticFS embed.FS
|
||||
|
||||
var Views *jet.Set
|
||||
|
||||
func init() {
|
||||
loader := jet.NewInMemLoader()
|
||||
|
||||
// Load templates from embed.FS
|
||||
templateFiles, err := templatesFS.ReadDir("templates")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
for _, tmpl := range templateFiles {
|
||||
if tmpl.IsDir() {
|
||||
continue
|
||||
}
|
||||
tmplPath := "templates/" + tmpl.Name()
|
||||
tmplContent, err := templatesFS.ReadFile(tmplPath)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
name := tmpl.Name()
|
||||
loader.Set(name, string(tmplContent))
|
||||
}
|
||||
|
||||
Views = jet.NewSet(loader)
|
||||
}
|
||||
|
||||
func StaticHandler() http.Handler {
|
||||
return http.FileServer(http.FS(staticFS))
|
||||
}
|
1
assets/static/tailwind.v2.2.19.min.css
vendored
Normal file
1
assets/static/tailwind.v2.2.19.min.css
vendored
Normal file
File diff suppressed because one or more lines are too long
12
assets/templates/flashes.jet
Normal file
12
assets/templates/flashes.jet
Normal file
@ -0,0 +1,12 @@
|
||||
{{ block flashes() }}
|
||||
{{ if len(Flashes) > 0 }}
|
||||
<div class="space-y-4 my-8 mx-auto max-w-2xl">
|
||||
{{ range Flashes }}
|
||||
<div class="bg-red-100 border border-red-400 text-red-700 px-4 py-3 rounded shadow-lg relative" role="alert">
|
||||
<span class="block sm:inline">{{ . }}</span>
|
||||
</div>
|
||||
{{ end }}
|
||||
</div>
|
||||
{{ end }}
|
||||
{{ end }}
|
||||
|
8
assets/templates/footer.jet
Normal file
8
assets/templates/footer.jet
Normal file
@ -0,0 +1,8 @@
|
||||
{{ block footer() }}
|
||||
<footer>
|
||||
<p>Directory <a
|
||||
href="https://git.eeqj.de/sneak/directory/commit/{{version}}"><code>{{
|
||||
version }}</code></a></p>
|
||||
</footer>
|
||||
{{ end }}
|
||||
|
12
assets/templates/html.jet
Normal file
12
assets/templates/html.jet
Normal file
@ -0,0 +1,12 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>{{ block title() }}Default Title{{ end }}</title>
|
||||
<link rel="stylesheet" href="/static/tailwind.v2.2.19.min.css">
|
||||
</head>
|
||||
<body>
|
||||
{{ block body() . }}{{ end }}
|
||||
</body>
|
||||
</html>
|
13
assets/templates/index.jet
Normal file
13
assets/templates/index.jet
Normal file
@ -0,0 +1,13 @@
|
||||
{{ extends "pagelayout.jet" }}
|
||||
|
||||
{{ block title() }}The Directory{{ end }}
|
||||
|
||||
{{ block pageContent() }}
|
||||
<h2>Directory</h2>
|
||||
|
||||
<h3>Tags</h3>
|
||||
<ul>
|
||||
<li><a href="/tags/tag1">Tag1</a></li>
|
||||
</ul>
|
||||
|
||||
{{ end }}
|
29
assets/templates/login.jet
Normal file
29
assets/templates/login.jet
Normal file
@ -0,0 +1,29 @@
|
||||
{{ extends "pagelayout.jet" }}
|
||||
|
||||
{{ block pageContent() }}
|
||||
<div class="flex items-center justify-center min-h-screen bg-gray-100">
|
||||
<div class="bg-white p-8 rounded-lg shadow-lg w-full max-w-md mx-4">
|
||||
<h2 class="text-2xl font-bold mb-6 text-center">Login</h2>
|
||||
<form action="/login" method="post">
|
||||
<div class="mb-4">
|
||||
<label for="username" class="block text-gray-700">Username:</label>
|
||||
<input type="text" id="username" name="username" required class="mt-1 w-full p-2 border border-gray-300 rounded">
|
||||
</div>
|
||||
<div class="mb-4">
|
||||
<label for="password" class="block text-gray-700">Password:</label>
|
||||
<input type="password" id="password" name="password" required class="mt-1 w-full p-2 border border-gray-300 rounded">
|
||||
</div>
|
||||
<div class="flex items-center justify-center">
|
||||
<input type="submit" value="Login" class="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded cursor-pointer">
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.min-h-screen {
|
||||
min-height: calc(100vh - 4rem); /* Adjust based on navbar height */
|
||||
}
|
||||
</style>
|
||||
{{ end }}
|
||||
|
39
assets/templates/navbar.jet
Normal file
39
assets/templates/navbar.jet
Normal file
@ -0,0 +1,39 @@
|
||||
{{ block navbar() }}
|
||||
<nav class="bg-gray-100 border-b border-gray-300 fixed top-0 left-0 right-0 w-full z-50">
|
||||
<div class="container mx-auto px-4 flex justify-between items-center h-16">
|
||||
<ul class="flex space-x-4">
|
||||
<li><a href="/" class="text-black hover:text-blue-500">Home</a></li>
|
||||
<li><a href="/status" class="text-black hover:text-blue-500">Status</a></li>
|
||||
</ul>
|
||||
<div class="relative">
|
||||
<input type="checkbox" id="dropdown-toggle" class="hidden">
|
||||
<label for="dropdown-toggle" class="cursor-pointer p-2 border border-gray-300 rounded bg-white">☰</label>
|
||||
<ul class="absolute right-0 mt-2 w-48 bg-white border border-gray-300 rounded shadow-lg hidden">
|
||||
{{ if isset("LoggedInUser") && LoggedInUser != nil }}
|
||||
<li><a href="/users/{{LoggedInUser.ID}}" class="block px-4 py-2 text-black hover:bg-gray-100">Profile</a></li>
|
||||
<li><a href="/logout" class="block px-4 py-2 text-black hover:bg-gray-100">Logout</a></li>
|
||||
{{ if LoggedInUser.IsSuperAdmin() }}
|
||||
<li><a href="/users/new" class="block px-4 py-2 text-black hover:bg-gray-100">Create User</a></li>
|
||||
{{ end }}
|
||||
<li class="block px-4 py-2 bg-gray-100 border-t border-gray-300">Welcome,
|
||||
<a href="/users/{{LoggedInUser.ID}}"><code>{{ LoggedInUser.Username }}</code></a>
|
||||
</li>
|
||||
{{ else }}
|
||||
<li><a href="/login" class="block px-4 py-2 text-black hover:bg-gray-100">Login</a></li>
|
||||
{{ end }}
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<style>
|
||||
body, html {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
#dropdown-toggle:checked + label + ul {
|
||||
display: block;
|
||||
}
|
||||
</style>
|
||||
{{ end }}
|
||||
|
25
assets/templates/pagelayout.jet
Normal file
25
assets/templates/pagelayout.jet
Normal file
@ -0,0 +1,25 @@
|
||||
{{ extends "html.jet" }}
|
||||
|
||||
{{ block body() . }}
|
||||
<!-- pagelayout.jet -->
|
||||
{{ include "navbar.jet" . }}
|
||||
<div class="content">
|
||||
{{ include "flashes.jet" . }}
|
||||
{{ block pageContent() . }}default page content{{ end }}
|
||||
</div>
|
||||
{{ include "footer.jet" . }}
|
||||
<style>
|
||||
body, html {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
.content {
|
||||
margin-top: 4rem; /* Adjust this value based on your navbar height */
|
||||
padding: 1em 0; /* Only top and bottom padding */
|
||||
background-color: #f8f9fa; /* Ensure background color spans full width */
|
||||
width: 100%; /* Ensure the content spans full width */
|
||||
box-sizing: border-box; /* Include padding in the element's total width and height */
|
||||
}
|
||||
</style>
|
||||
{{ end }}
|
||||
|
8
go.mod
8
go.mod
@ -19,12 +19,17 @@ require (
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/CloudyKit/fastprinter v0.0.0-20200109182630-33d98a066a53 // indirect
|
||||
github.com/CloudyKit/jet/v6 v6.2.0 // indirect
|
||||
github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 // indirect
|
||||
github.com/beorn7/perks v1.0.1 // indirect
|
||||
github.com/cespare/xxhash/v2 v2.3.0 // indirect
|
||||
github.com/fsnotify/fsnotify v1.7.0 // indirect
|
||||
github.com/hako/durafmt v0.0.0-20210608085754-5c1018a4e16b // indirect
|
||||
github.com/hashicorp/hcl v1.0.0 // indirect
|
||||
github.com/jackc/pgpassfile v1.0.0 // indirect
|
||||
github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a // indirect
|
||||
github.com/jackc/pgx/v5 v5.4.3 // indirect
|
||||
github.com/jinzhu/inflection v1.0.0 // indirect
|
||||
github.com/jinzhu/now v1.1.5 // indirect
|
||||
github.com/magiconair/properties v1.8.7 // indirect
|
||||
@ -32,6 +37,7 @@ require (
|
||||
github.com/mattn/go-isatty v0.0.20 // indirect
|
||||
github.com/mattn/go-sqlite3 v1.14.17 // indirect
|
||||
github.com/mitchellh/mapstructure v1.5.0 // indirect
|
||||
github.com/oklog/ulid/v2 v2.1.0 // indirect
|
||||
github.com/pelletier/go-toml/v2 v2.2.1 // indirect
|
||||
github.com/prometheus/client_model v0.6.1 // indirect
|
||||
github.com/prometheus/common v0.53.0 // indirect
|
||||
@ -46,10 +52,12 @@ require (
|
||||
go.uber.org/dig v1.17.1 // indirect
|
||||
go.uber.org/multierr v1.10.0 // indirect
|
||||
go.uber.org/zap v1.26.0 // indirect
|
||||
golang.org/x/crypto v0.22.0 // indirect
|
||||
golang.org/x/exp v0.0.0-20240416160154-fe59bbe5cc7f // indirect
|
||||
golang.org/x/sys v0.19.0 // indirect
|
||||
golang.org/x/text v0.14.0 // indirect
|
||||
google.golang.org/protobuf v1.33.0 // indirect
|
||||
gopkg.in/ini.v1 v1.67.0 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
gorm.io/driver/postgres v1.5.7 // indirect
|
||||
)
|
||||
|
19
go.sum
19
go.sum
@ -1,5 +1,9 @@
|
||||
github.com/99designs/basicauth-go v0.0.0-20230316000542-bf6f9cbbf0f8 h1:nMpu1t4amK3vJWBibQ5X/Nv0aXL+b69TQf2uK5PH7Go=
|
||||
github.com/99designs/basicauth-go v0.0.0-20230316000542-bf6f9cbbf0f8/go.mod h1:3cARGAK9CfW3HoxCy1a0G4TKrdiKke8ftOMEOHyySYs=
|
||||
github.com/CloudyKit/fastprinter v0.0.0-20200109182630-33d98a066a53 h1:sR+/8Yb4slttB4vD+b9btVEnWgL3Q00OBTzVT8B9C0c=
|
||||
github.com/CloudyKit/fastprinter v0.0.0-20200109182630-33d98a066a53/go.mod h1:+3IMCy2vIlbG1XG/0ggNQv0SvxCAIpPM5b1nCz56Xno=
|
||||
github.com/CloudyKit/jet/v6 v6.2.0 h1:EpcZ6SR9n28BUGtNJSvlBqf90IpjeFr36Tizxhn/oME=
|
||||
github.com/CloudyKit/jet/v6 v6.2.0/go.mod h1:d3ypHeIRNo2+XyqnGA8s+aphtcVpjP5hPwP/Lzo7Ro4=
|
||||
github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 h1:DklsrG3dyBCFEj5IhUbnKptjxatkF07cF2ak3yi77so=
|
||||
github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw=
|
||||
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
|
||||
@ -32,6 +36,12 @@ github.com/hako/durafmt v0.0.0-20210608085754-5c1018a4e16b h1:wDUNC2eKiL35DbLvsD
|
||||
github.com/hako/durafmt v0.0.0-20210608085754-5c1018a4e16b/go.mod h1:VzxiSdG6j1pi7rwGm/xYI5RbtpBgM8sARDXlvEvxlu0=
|
||||
github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4=
|
||||
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
|
||||
github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM=
|
||||
github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg=
|
||||
github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a h1:bbPeKD0xmW/Y25WS6cokEszi5g+S0QxI/d45PkRi7Nk=
|
||||
github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM=
|
||||
github.com/jackc/pgx/v5 v5.4.3 h1:cxFyXhxlvAifxnkKKdlxv8XqUf59tDlYjnV5YYfsJJY=
|
||||
github.com/jackc/pgx/v5 v5.4.3/go.mod h1:Ig06C2Vu0t5qXC60W8sqIthScaEnFvojjj9dSljmHRA=
|
||||
github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E=
|
||||
github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc=
|
||||
github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ=
|
||||
@ -54,6 +64,9 @@ github.com/mattn/go-sqlite3 v1.14.17 h1:mCRHCLDUBXgpKAqIKsaAaAsrAlbkeomtRFKXh2L6
|
||||
github.com/mattn/go-sqlite3 v1.14.17/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg=
|
||||
github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY=
|
||||
github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
|
||||
github.com/oklog/ulid/v2 v2.1.0 h1:+9lhoxAP56we25tyYETBBY1YLA2SaoLvUFgrP2miPJU=
|
||||
github.com/oklog/ulid/v2 v2.1.0/go.mod h1:rcEKHmBBKfef9DhnvX7y1HZBYxjXb0cP5ExxNsTT1QQ=
|
||||
github.com/pborman/getopt v0.0.0-20170112200414-7148bc3a4c30/go.mod h1:85jBQOZwpVEaDAr341tbn15RS4fCAsIst0qp7i8ex1o=
|
||||
github.com/pelletier/go-toml/v2 v2.2.1 h1:9TA9+T8+8CUCO2+WYnDLCgrYi9+omqKXyjDtosvtEhg=
|
||||
github.com/pelletier/go-toml/v2 v2.2.1/go.mod h1:1t835xjRzz80PqgE6HHgN2JOsmgYu/h4qDAS4n929Rs=
|
||||
github.com/pingcap/errors v0.11.4 h1:lFuQV/oaUMGcD2tqt+01ROSmJs75VG1ToEOkZIZ4nE4=
|
||||
@ -97,6 +110,8 @@ github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSS
|
||||
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
|
||||
github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY=
|
||||
github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA=
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
||||
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
|
||||
@ -114,6 +129,8 @@ go.uber.org/multierr v1.10.0 h1:S0h4aNzvfcFsC3dRF1jLoaov7oRaKqRGC/pUEJ2yvPQ=
|
||||
go.uber.org/multierr v1.10.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
|
||||
go.uber.org/zap v1.26.0 h1:sI7k6L95XOKS281NhVKOFCUNIvv9e0w4BF8N3u+tCRo=
|
||||
go.uber.org/zap v1.26.0/go.mod h1:dtElttAiwGvoJ/vj4IwHBS/gXsEu/pZ50mUIRWuG0so=
|
||||
golang.org/x/crypto v0.22.0 h1:g1v0xeRhjcugydODzvb3mEM9SQ0HGp9s/nh3COQ/C30=
|
||||
golang.org/x/crypto v0.22.0/go.mod h1:vr6Su+7cTlO45qkww3VDJlzDn0ctJvRgYbC2NvXHt+M=
|
||||
golang.org/x/exp v0.0.0-20240416160154-fe59bbe5cc7f h1:99ci1mjWVBWwJiEKYY6jWa4d2nTQVIEhZIptnrVb1XY=
|
||||
golang.org/x/exp v0.0.0-20240416160154-fe59bbe5cc7f/go.mod h1:/lliqkxwWAhPjf5oSOIJup2XcqJaw8RGS6k3TGEc7GI=
|
||||
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
@ -133,6 +150,8 @@ gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gorm.io/driver/postgres v1.5.7 h1:8ptbNJTDbEmhdr62uReG5BGkdQyeasu/FZHxI0IMGnM=
|
||||
gorm.io/driver/postgres v1.5.7/go.mod h1:3e019WlBaYI5o5LIdNV+LyxCMNtLOQETBXL2h4chKpA=
|
||||
gorm.io/driver/sqlite v1.5.5 h1:7MDMtUZhV065SilG62E0MquljeArQZNfJnjd9i9gx3E=
|
||||
gorm.io/driver/sqlite v1.5.5/go.mod h1:6NgQ7sQWAIFsPrJJl1lSNSu2TABh0ZZ/zm5fosATavE=
|
||||
gorm.io/gorm v1.25.10 h1:dQpO+33KalOA+aFYGlK+EfxcI5MbO7EP2yYygwh9h+s=
|
||||
|
@ -26,7 +26,7 @@ type ConfigParams struct {
|
||||
}
|
||||
|
||||
type Config struct {
|
||||
DBURL string
|
||||
DBDSN string
|
||||
Debug bool
|
||||
MaintenanceMode bool
|
||||
DevelopmentMode bool
|
||||
@ -59,7 +59,7 @@ func New(lc fx.Lifecycle, params ConfigParams) (*Config, error) {
|
||||
viper.SetDefault("DEV_ADMIN_USERNAME", "")
|
||||
viper.SetDefault("DEV_ADMIN_PASSWORD", "")
|
||||
viper.SetDefault("PORT", "8080")
|
||||
viper.SetDefault("DBURL", "")
|
||||
viper.SetDefault("DB_DSN", "")
|
||||
viper.SetDefault("SENTRY_DSN", "")
|
||||
viper.SetDefault("METRICS_USERNAME", "")
|
||||
viper.SetDefault("METRICS_PASSWORD", "")
|
||||
@ -76,7 +76,7 @@ func New(lc fx.Lifecycle, params ConfigParams) (*Config, error) {
|
||||
}
|
||||
|
||||
s := &Config{
|
||||
DBURL: viper.GetString("DBURL"),
|
||||
DBDSN: viper.GetString("DB_DSN"),
|
||||
Debug: viper.GetBool("debug"),
|
||||
Port: viper.GetInt("PORT"),
|
||||
SentryDSN: viper.GetString("SENTRY_DSN"),
|
||||
|
@ -2,27 +2,17 @@ package database
|
||||
|
||||
import (
|
||||
"context"
|
||||
"os"
|
||||
|
||||
"database/sql"
|
||||
"errors"
|
||||
|
||||
"github.com/rs/zerolog"
|
||||
"github.com/rs/zerolog/log"
|
||||
"go.uber.org/fx"
|
||||
"gorm.io/driver/sqlite"
|
||||
"gorm.io/driver/postgres"
|
||||
"gorm.io/gorm"
|
||||
"sneak.berlin/go/directory/internal/config"
|
||||
"sneak.berlin/go/directory/internal/globals"
|
||||
"sneak.berlin/go/directory/internal/logger"
|
||||
"sneak.berlin/go/util"
|
||||
|
||||
// spooky action at a distance!
|
||||
// this populates the environment
|
||||
// from a ./.env file automatically
|
||||
// for development configuration.
|
||||
// .env contents should be things like
|
||||
// `DBURL=postgres://user:pass@.../`
|
||||
// (without the backticks, of course)
|
||||
_ "github.com/joho/godotenv/autoload"
|
||||
)
|
||||
|
||||
@ -39,8 +29,6 @@ type Database struct {
|
||||
params *DatabaseParams
|
||||
DB *gorm.DB
|
||||
SQLDB *sql.DB
|
||||
dbdir string
|
||||
dbfn string
|
||||
}
|
||||
|
||||
func New(lc fx.Lifecycle, params DatabaseParams) (*Database, error) {
|
||||
@ -53,11 +41,21 @@ func New(lc fx.Lifecycle, params DatabaseParams) (*Database, error) {
|
||||
lc.Append(fx.Hook{
|
||||
OnStart: func(ctx context.Context) error {
|
||||
s.log.Info().Msg("Database OnStart Hook")
|
||||
// FIXME connect to db
|
||||
err := s.Connect()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
},
|
||||
OnStop: func(ctx context.Context) error {
|
||||
// FIXME disconnect from db
|
||||
if s.SQLDB != nil {
|
||||
err := s.SQLDB.Close()
|
||||
if err != nil {
|
||||
s.log.Error().Err(err).Msg("failed to close database connection")
|
||||
return err
|
||||
}
|
||||
}
|
||||
s.log.Info().Msg("Database connection closed")
|
||||
return nil
|
||||
},
|
||||
})
|
||||
@ -80,36 +78,49 @@ func (d *Database) Get() (*gorm.DB, error) {
|
||||
}
|
||||
|
||||
func (d *Database) Connect() error {
|
||||
// FIXME make this get the data dir path from config
|
||||
d.dbdir = os.Getenv("HOME")
|
||||
err := util.Mkdirp(d.dbdir)
|
||||
if err != nil {
|
||||
d.log.Error().
|
||||
Err(err).
|
||||
Str("dbdir", d.dbdir).
|
||||
Msg("unable to create directory")
|
||||
dsn := d.params.Config.DatabaseDSN
|
||||
if dsn == "" {
|
||||
err := errors.New("database DSN is empty")
|
||||
d.log.Error().Err(err).Msg("failed to get database DSN from config")
|
||||
return err
|
||||
}
|
||||
d.dbfn = d.dbdir + "/" + d.params.Globals.Appname + ".db"
|
||||
d.log.Info().
|
||||
Str("file", d.dbfn).
|
||||
Msg("opening store db")
|
||||
|
||||
// Open the database using the pure Go SQLite driver
|
||||
sqlDB, err := sql.Open("sqlite", d.dbfn+"?_pragma=foreign_keys(1)&_pragma=journal_mode(WAL)")
|
||||
d.log.Info().
|
||||
Str("dsn", dsn).
|
||||
Msg("connecting to database")
|
||||
|
||||
sqlDB, err := sql.Open("postgres", dsn)
|
||||
if err != nil {
|
||||
d.log.Error().Err(err).Msg("failed to open database")
|
||||
return err
|
||||
}
|
||||
d.SQLDB = sqlDB
|
||||
|
||||
// Use the generic Gorm SQL driver to integrate it
|
||||
db, err := gorm.Open(sqlite.Dialector{Conn: d.SQLDB}, &gorm.Config{})
|
||||
// Ping the database to ensure the connection is valid
|
||||
err = d.Ping()
|
||||
if err != nil {
|
||||
log.Error().Err(err).Msg("failed to connect database")
|
||||
d.log.Error().Err(err).Msg("failed to ping database")
|
||||
return err
|
||||
}
|
||||
|
||||
db, err := gorm.Open(postgres.New(postgres.Config{
|
||||
Conn: d.SQLDB,
|
||||
}), &gorm.Config{})
|
||||
if err != nil {
|
||||
d.log.Error().Err(err).Msg("failed to connect database")
|
||||
return err
|
||||
}
|
||||
d.DB = db
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (d *Database) Ping() error {
|
||||
err := d.SQLDB.Ping()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
d.log.Info().Msg("successfully pinged the database")
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -23,8 +23,6 @@ type StoreParams struct {
|
||||
}
|
||||
|
||||
type Store struct {
|
||||
dbdir string
|
||||
dbfn string
|
||||
db *gorm.DB
|
||||
logger *logger.Logger
|
||||
log *zerolog.Logger
|
||||
|
@ -110,7 +110,6 @@ func (s *Store) LogSuccessfulAuth(UserID string, r *http.Request) {
|
||||
}
|
||||
s.db.Model(u).Update("LastSeen", now)
|
||||
//s.db.Model(u).Update("LastSeenIP", FIXME)
|
||||
|
||||
}
|
||||
|
||||
func (s *Store) AuthenticateUser(username, password, rootPasswordHash string, r *http.Request) (bool, *User, error) {
|
||||
|
Loading…
Reference in New Issue
Block a user