Compare commits
5 Commits
db507259c7
...
3be2a47c56
| Author | SHA1 | Date | |
|---|---|---|---|
| 3be2a47c56 | |||
| f6e77bda66 | |||
| 5fb6254c04 | |||
| f2a5e9874d | |||
| 32a4f5277a |
@@ -1,12 +1,21 @@
|
||||
FROM golang:alpine
|
||||
# syntax=docker/dockerfile:1
|
||||
FROM --platform=$BUILDPLATFORM golang:alpine AS build
|
||||
ARG TARGETOS
|
||||
ARG TARGETARCH
|
||||
ENV CGO_ENABLED=0 \
|
||||
GOOS=$TARGETOS \
|
||||
GOARCH=$TARGETARCH
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
COPY go.mod go.sum /app/
|
||||
|
||||
RUN go mod download && go mod verify
|
||||
|
||||
COPY . .
|
||||
RUN go build -o /usr/local/bin/app
|
||||
RUN go build -o server .
|
||||
|
||||
CMD ["app"]
|
||||
FROM alpine
|
||||
WORKDIR /app
|
||||
COPY --from=build /app/server /app/server
|
||||
|
||||
COPY /static /app/static
|
||||
ENTRYPOINT ["./server"]
|
||||
|
||||
@@ -43,14 +43,19 @@ func parseTimestamp(r *http.Request , get_key string, fallback string) (time.Tim
|
||||
|
||||
// Returns bookings from DB with similar card uid -> checks for card uid in http query params
|
||||
func getBookings(w http.ResponseWriter, r *http.Request) {
|
||||
// if(!Session.Exists(r.Context(), "user")){
|
||||
// log.Println("No user in session storage!")
|
||||
// http.Error(w, "Not logged in!", http.StatusForbidden)
|
||||
// return
|
||||
// }
|
||||
var user models.User
|
||||
var err error
|
||||
if(helper.GetEnv("GO_ENV", "production") == "debug"){
|
||||
user, err = (*models.User).GetByPersonalNummer(nil, 123)
|
||||
}else{
|
||||
if(!Session.Exists(r.Context(), "user")){
|
||||
log.Println("No user in session storage!")
|
||||
http.Error(w, "Not logged in!", http.StatusForbidden)
|
||||
return
|
||||
}
|
||||
|
||||
// user, err := (*models.User).GetByPersonalNummer(nil, Session.GetInt(r.Context(), "user"))
|
||||
user, err := (*models.User).GetByPersonalNummer(nil, 123)
|
||||
user, err = (*models.User).GetByPersonalNummer(nil, Session.GetInt(r.Context(), "user"))
|
||||
}
|
||||
if(err != nil){
|
||||
log.Println("No user found with the given personal number!")
|
||||
http.Error(w, "No user found", http.StatusNotFound)
|
||||
|
||||
@@ -5,6 +5,7 @@ import (
|
||||
"arbeitszeitmessung/templates"
|
||||
"log"
|
||||
"net/http"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"github.com/alexedwards/scs/v2"
|
||||
@@ -20,18 +21,18 @@ func CreateSessionManager(lifetime time.Duration) *scs.SessionManager {
|
||||
|
||||
func LoginHandler(w http.ResponseWriter, r *http.Request){
|
||||
switch r.Method{
|
||||
case http.MethodGet: showForm(w, r)
|
||||
case http.MethodGet: showForm(w, r, false)
|
||||
break
|
||||
case http.MethodPost: loginUser(w, r)
|
||||
break
|
||||
default:
|
||||
showForm(w, r)
|
||||
showForm(w, r, false)
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
func showForm(w http.ResponseWriter, r *http.Request){
|
||||
templates.LoginForm().Render(r.Context(), w)
|
||||
func showForm(w http.ResponseWriter, r *http.Request, failed bool){
|
||||
templates.LoginForm(failed).Render(r.Context(), w)
|
||||
}
|
||||
|
||||
func loginUser(w http.ResponseWriter, r *http.Request){
|
||||
@@ -39,15 +40,24 @@ func loginUser(w http.ResponseWriter, r *http.Request){
|
||||
if err != nil {
|
||||
log.Println("Error parsing form!", err)
|
||||
http.Error(w, "Internal error", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
card_uid := r.FormValue("card_uid")
|
||||
if(card_uid == ""){
|
||||
log.Println("No card_uid provided!")
|
||||
http.Error(w, "No card_uid provided", http.StatusBadRequest)
|
||||
_personal_nummer := r.FormValue("personal_nummer")
|
||||
if(_personal_nummer == ""){
|
||||
log.Println("No personal_nummer provided!")
|
||||
http.Error(w, "No personal_nummer provided", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
user, err := (*models.User).GetByCardUID(nil, card_uid)
|
||||
personal_nummer, err := strconv.Atoi(_personal_nummer)
|
||||
if(err != nil){
|
||||
log.Println("No user found under this card_uid!")
|
||||
log.Println("Cannot parse personal nubmer!")
|
||||
http.Error(w, "Cannot parse number", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
user, err := (*models.User).GetByPersonalNummer(nil, personal_nummer)
|
||||
if(err != nil){
|
||||
log.Println("No user found under this personal number!")
|
||||
http.Error(w, "No user found!", http.StatusNotFound)
|
||||
}
|
||||
|
||||
@@ -56,7 +66,9 @@ func loginUser(w http.ResponseWriter, r *http.Request){
|
||||
log.Printf("New succesfull user login from %s %s!\n", user.Vorname, user.Name)
|
||||
Session.Put(r.Context(), "user", user.PersonalNummer)
|
||||
http.Redirect(w, r, "/time", http.StatusSeeOther) //with this browser always uses GET
|
||||
}else{
|
||||
showForm(w, r, true)
|
||||
}
|
||||
|
||||
showForm(w, r)
|
||||
showForm(w, r, false)
|
||||
}
|
||||
|
||||
@@ -8,4 +8,6 @@ require github.com/lib/pq v1.10.9
|
||||
|
||||
require github.com/a-h/templ v0.3.833
|
||||
|
||||
require github.com/alexedwards/scs/v2 v2.8.0 // indirect
|
||||
require github.com/alexedwards/scs/v2 v2.8.0
|
||||
|
||||
require github.com/joho/godotenv v1.5.1
|
||||
|
||||
@@ -4,5 +4,7 @@ github.com/alexedwards/scs/v2 v2.8.0 h1:h31yUYoycPuL0zt14c0gd+oqxfRwIj6SOjHdKRZx
|
||||
github.com/alexedwards/scs/v2 v2.8.0/go.mod h1:ToaROZxyKukJKT/xLcVQAChi5k6+Pn1Gvmdl7h3RRj8=
|
||||
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
|
||||
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0=
|
||||
github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4=
|
||||
github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw=
|
||||
github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
|
||||
|
||||
@@ -10,6 +10,7 @@ import (
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"github.com/joho/godotenv"
|
||||
_ "github.com/lib/pq"
|
||||
)
|
||||
|
||||
@@ -17,6 +18,12 @@ import (
|
||||
|
||||
func main() {
|
||||
var err error
|
||||
|
||||
err = godotenv.Load(".env")
|
||||
if err != nil {
|
||||
log.Println("No .env file found in directory!")
|
||||
}
|
||||
|
||||
models.DB, err = OpenDatabase()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
|
||||
@@ -9,12 +9,11 @@ type User struct {
|
||||
CardUID string `json:"card_uid"`
|
||||
Name string `json:"name"`
|
||||
Vorname string `json:"vorname"`
|
||||
HauptbeschaeftigungsOrt int8 `json:"hauptbeschaeftigungsort"`
|
||||
PersonalNummer int `json:"personal_nummer"`
|
||||
}
|
||||
|
||||
func (u *User) GetAll() ([]User, error) {
|
||||
qStr, err := DB.Prepare((`SELECT card_uid, vorname, nachname, hauptbeschaeftigung_ort FROM personal_daten;`))
|
||||
qStr, err := DB.Prepare((`SELECT card_uid, vorname, nachname FROM personal_daten;`))
|
||||
var users []User
|
||||
if err != nil {
|
||||
fmt.Printf("Error preparing query statement %v\n", err)
|
||||
@@ -28,7 +27,7 @@ func (u *User) GetAll() ([]User, error) {
|
||||
defer rows.Close()
|
||||
for rows.Next() {
|
||||
var user User
|
||||
if err := rows.Scan(&user.CardUID, &user.Vorname, &user.Name, &user.HauptbeschaeftigungsOrt); err != nil {
|
||||
if err := rows.Scan(&user.CardUID, &user.Vorname, &user.Name); err != nil {
|
||||
return users, nil
|
||||
}
|
||||
users = append(users, user)
|
||||
@@ -69,11 +68,11 @@ func (u *User) Logout() error {
|
||||
|
||||
func (u *User) GetByCardUID(card_uid string) (User, error) {
|
||||
var user User
|
||||
qStr, err := DB.Prepare((`SELECT personal_nummer, card_uid, vorname, nachname, hauptbeschaeftigung_ort FROM personal_daten WHERE card_uid = $1;`))
|
||||
qStr, err := DB.Prepare((`SELECT personal_nummer, card_uid, vorname, nachname FROM personal_daten WHERE card_uid = $1;`))
|
||||
if err != nil {
|
||||
return user, err
|
||||
}
|
||||
err = qStr.QueryRow(card_uid).Scan(&user.PersonalNummer, &user.CardUID, &user.Vorname, &user.Name, &user.HauptbeschaeftigungsOrt)
|
||||
err = qStr.QueryRow(card_uid).Scan(&user.PersonalNummer, &user.CardUID, &user.Vorname, &user.Name)
|
||||
if err != nil{
|
||||
return user, err
|
||||
}
|
||||
@@ -83,11 +82,11 @@ func (u *User) GetByCardUID(card_uid string) (User, error) {
|
||||
func (u *User) GetByPersonalNummer (personalNummer int) (User, error) {
|
||||
var user User
|
||||
|
||||
qStr, err := DB.Prepare((`SELECT personal_nummer, card_uid, vorname, nachname, hauptbeschaeftigung_ort FROM personal_daten WHERE personal_nummer = $1;`))
|
||||
qStr, err := DB.Prepare((`SELECT personal_nummer, card_uid, vorname, nachname FROM personal_daten WHERE personal_nummer = $1;`))
|
||||
if err != nil {
|
||||
return user, err
|
||||
}
|
||||
err = qStr.QueryRow(personalNummer).Scan(&user.PersonalNummer, &user.CardUID, &user.Vorname, &user.Name, &user.HauptbeschaeftigungsOrt)
|
||||
err = qStr.QueryRow(personalNummer).Scan(&user.PersonalNummer, &user.CardUID, &user.Vorname, &user.Name)
|
||||
if err != nil{
|
||||
return user, err
|
||||
}
|
||||
|
||||
@@ -600,9 +600,21 @@
|
||||
.h-4 {
|
||||
height: calc(var(--spacing) * 4);
|
||||
}
|
||||
.h-\[90vh\] {
|
||||
height: 90vh;
|
||||
}
|
||||
.h-\[100vh\] {
|
||||
height: 100vh;
|
||||
}
|
||||
.h-full {
|
||||
height: 100%;
|
||||
}
|
||||
.w-1 {
|
||||
width: calc(var(--spacing) * 1);
|
||||
}
|
||||
.w-1\/2 {
|
||||
width: calc(1/2 * 100%);
|
||||
}
|
||||
.w-2 {
|
||||
width: calc(var(--spacing) * 2);
|
||||
}
|
||||
@@ -702,18 +714,24 @@
|
||||
.border-neutral-200 {
|
||||
border-color: var(--color-neutral-200);
|
||||
}
|
||||
.border-neutral-300 {
|
||||
border-color: var(--color-neutral-300);
|
||||
}
|
||||
.border-neutral-400 {
|
||||
border-color: var(--color-neutral-400);
|
||||
}
|
||||
.border-neutral-900 {
|
||||
border-color: var(--color-neutral-900);
|
||||
}
|
||||
.border-red-600 {
|
||||
border-color: var(--color-red-600);
|
||||
}
|
||||
.bg-accent {
|
||||
background-color: var(--color-accent);
|
||||
}
|
||||
.bg-neutral-100 {
|
||||
background-color: var(--color-neutral-100);
|
||||
}
|
||||
.bg-neutral-200 {
|
||||
background-color: var(--color-neutral-200);
|
||||
}
|
||||
.bg-neutral-300 {
|
||||
background-color: var(--color-neutral-300);
|
||||
}
|
||||
@@ -726,6 +744,9 @@
|
||||
.bg-purple-600 {
|
||||
background-color: var(--color-purple-600);
|
||||
}
|
||||
.bg-red-200 {
|
||||
background-color: var(--color-red-200);
|
||||
}
|
||||
.bg-red-600 {
|
||||
background-color: var(--color-red-600);
|
||||
}
|
||||
@@ -745,6 +766,10 @@
|
||||
font-size: var(--text-sm);
|
||||
line-height: var(--tw-leading, var(--text-sm--line-height));
|
||||
}
|
||||
.text-xs {
|
||||
font-size: var(--text-xs);
|
||||
line-height: var(--tw-leading, var(--text-xs--line-height));
|
||||
}
|
||||
.font-bold {
|
||||
--tw-font-weight: var(--font-weight-bold);
|
||||
font-weight: var(--font-weight-bold);
|
||||
@@ -817,6 +842,13 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
.hover\:border-neutral-500 {
|
||||
&:hover {
|
||||
@media (hover: hover) {
|
||||
border-color: var(--color-neutral-500);
|
||||
}
|
||||
}
|
||||
}
|
||||
.hover\:bg-neutral-200 {
|
||||
&:hover {
|
||||
@media (hover: hover) {
|
||||
@@ -824,13 +856,6 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
.hover\:bg-neutral-300 {
|
||||
&:hover {
|
||||
@media (hover: hover) {
|
||||
background-color: var(--color-neutral-300);
|
||||
}
|
||||
}
|
||||
}
|
||||
.hover\:bg-neutral-700 {
|
||||
&:hover {
|
||||
@media (hover: hover) {
|
||||
|
||||
@@ -1,10 +1,22 @@
|
||||
package templates
|
||||
|
||||
templ LoginForm(){
|
||||
@Style()
|
||||
<form method="POST">
|
||||
<input name="card_uid" type="text" placeholder="card_uid"/>
|
||||
<input name="password" type="passwort" placeholder="password"/>
|
||||
<button type="submit">Send</button>
|
||||
</form>
|
||||
templ LoginForm(failed bool){
|
||||
{{
|
||||
failedClass := ""
|
||||
if(failed){
|
||||
failedClass = "border border-red-600"
|
||||
}
|
||||
}}
|
||||
@Style()
|
||||
<div class="w-full h-[100vh] flex flex-col justify-center items-center">
|
||||
|
||||
<form method="POST" class={"w-1/2 flex flex-col gap-4 p-2", failedClass}>
|
||||
<input name="personal_nummer" placeholder="Personalnummer" type="text" class="w-full placeholder:text-neutral-400 text-neutral-700 text-sm border border-neutral-300 rounded-md px-3 py-2 transition duration-300 ease focus:outline-none hover:border-neutral-500"/>
|
||||
<input name="password" placeholder="Passwort" type="password" class="w-full placeholder:text-neutral-400 text-neutral-700 text-sm border border-neutral-300 rounded-md px-3 py-2 transition duration-300 ease focus:outline-none hover:border-neutral-500"/>
|
||||
if failed {
|
||||
<p class="text-red-600 text-sm" >Login fehlgeschlagen, bitte erneut versuchen!</p>
|
||||
}
|
||||
<button type="submit" class="cursor-pointer rounded-md text-neutral-800 p-2 md:px-4 border text-center text-sm hover:text-white transition-colors border-neutral-300 focus:bg-neutral-700 active:bg-neutral-700 hover:bg-neutral-700 disabled:pointer-events-none disabled:opacity-50">Login</button>
|
||||
</form>
|
||||
</div>
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@ package templates
|
||||
import "github.com/a-h/templ"
|
||||
import templruntime "github.com/a-h/templ/runtime"
|
||||
|
||||
func LoginForm() templ.Component {
|
||||
func LoginForm(failed bool) templ.Component {
|
||||
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
|
||||
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
|
||||
if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
|
||||
@@ -29,11 +29,48 @@ func LoginForm() templ.Component {
|
||||
templ_7745c5c3_Var1 = templ.NopComponent
|
||||
}
|
||||
ctx = templ.ClearChildren(ctx)
|
||||
|
||||
failedClass := ""
|
||||
if failed {
|
||||
failedClass = "border border-red-600"
|
||||
}
|
||||
templ_7745c5c3_Err = Style().Render(ctx, templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, "<form method=\"POST\"><input name=\"card_uid\" type=\"text\" placeholder=\"card_uid\"> <input name=\"password\" type=\"passwort\" placeholder=\"password\"> <button type=\"submit\">Send</button></form>")
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, "<div class=\"w-full h-[100vh] flex flex-col justify-center items-center\">")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var2 = []any{"w-1/2 flex flex-col gap-4 p-2", failedClass}
|
||||
templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var2...)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, "<form method=\"POST\" class=\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var3 string
|
||||
templ_7745c5c3_Var3, templ_7745c5c3_Err = templ.JoinStringErrs(templ.CSSClasses(templ_7745c5c3_Var2).String())
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/user.templ`, Line: 1, Col: 0}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var3))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 3, "\"><input name=\"personal_nummer\" placeholder=\"Personalnummer\" type=\"text\" class=\"w-full placeholder:text-neutral-400 text-neutral-700 text-sm border border-neutral-300 rounded-md px-3 py-2 transition duration-300 ease focus:outline-none hover:border-neutral-500\"> <input name=\"password\" placeholder=\"Passwort\" type=\"password\" class=\"w-full placeholder:text-neutral-400 text-neutral-700 text-sm border border-neutral-300 rounded-md px-3 py-2 transition duration-300 ease focus:outline-none hover:border-neutral-500\"> ")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
if failed {
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 4, "<p class=\"text-red-600 text-sm\">Login fehlgeschlagen, bitte erneut versuchen!</p>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 5, "<button type=\"submit\" class=\"cursor-pointer rounded-md text-neutral-800 p-2 md:px-4 border text-center text-sm hover:text-white transition-colors border-neutral-300 focus:bg-neutral-700 active:bg-neutral-700 hover:bg-neutral-700 disabled:pointer-events-none disabled:opacity-50\">Login</button></form></div>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
|
||||
40
DB/initdb/01_create_tables.sql
Normal file
40
DB/initdb/01_create_tables.sql
Normal file
@@ -0,0 +1,40 @@
|
||||
-- ----------------------------
|
||||
-- Table structure for anwesenheit
|
||||
-- ----------------------------
|
||||
DROP TABLE IF EXISTS "anwesenheit";
|
||||
CREATE TABLE "anwesenheit" (
|
||||
"counter_id" bigserial PRIMARY KEY,
|
||||
"timestamp" timestamp(6) DEFAULT CURRENT_TIMESTAMP,
|
||||
"card_uid" varchar(255),
|
||||
"check_in_out" int2,
|
||||
"geraet_id" int2
|
||||
);
|
||||
COMMENT ON COLUMN "anwesenheit"."check_in_out" IS '1=Check In 2=Check Out , 3=Check in Manuell, 4=Check out manuell255=Automatic Check Out';
|
||||
COMMENT ON COLUMN "anwesenheit"."geraet_id" IS 'ID des Lesegerätes';
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for personal_daten
|
||||
-- ----------------------------
|
||||
DROP TABLE IF EXISTS "personal_daten";
|
||||
CREATE TABLE "personal_daten" (
|
||||
"personal_nummer" int4 NOT NULL PRIMARY KEY,
|
||||
"aktiv_beschaeftigt" bool,
|
||||
"vorname" varchar(255),
|
||||
"nachname" varchar(255),
|
||||
"geburtsdatum" date,
|
||||
"plz" varchar(255),
|
||||
"adresse" varchar(255),
|
||||
"geschlecht" int2,
|
||||
"card_uid" varchar(255),
|
||||
"hauptbeschaeftigungs_ort" int2,
|
||||
"arbeitszeit_per_tag" float4,
|
||||
"arbeitszeit_min_start" time(6),
|
||||
"arbeitszeit_max_ende" time(6),
|
||||
"vorgesetzter_pers_nr" int4
|
||||
);
|
||||
COMMENT ON COLUMN "personal_daten"."geschlecht" IS '1==weiblich, 2==maennlich, 3==divers';
|
||||
|
||||
-- Insert into personal_daten
|
||||
|
||||
INSERT INTO "personal_daten" ("personal_nummer", "aktiv_beschaeftigt", "vorname", "nachname", "geburtsdatum", "plz", "adresse", "geschlecht", "card_uid", "hauptbeschaeftigungs_ort", "arbeitszeit_per_tag", "arbeitszeit_min_start", "arbeitszeit_max_ende", "vorgesetzter_pers_nr") VALUES
|
||||
(123, 't', 'Max', 'Mustermann', '2003-02-01', '08963', 'Altenburger Str. 44A', 1, 'acde-edca', 1, 7.5, '07:00:00', '20:00:00', 0);
|
||||
14
DB/initdb/02_create_user.sh
Normal file
14
DB/initdb/02_create_user.sh
Normal file
@@ -0,0 +1,14 @@
|
||||
#!/bin/bash
|
||||
set -e # Exit on error
|
||||
|
||||
echo "Creating PostgreSQL user and setting permissions... $POSTGRES_USER for API user $POSTGRES_API_USER"
|
||||
|
||||
psql -v ON_ERROR_STOP=1 --username "$POSTGRES_USER" --dbname "$POSTGRES_DB" <<-EOSQL
|
||||
CREATE USER $POSTGRES_API_USER WITH ENCRYPTED PASSWORD '$POSTGRES_API_PASSWORD';
|
||||
GRANT CONNECT ON DATABASE $POSTGRES_DB TO $POSTGRES_API_USER;
|
||||
GRANT USAGE ON SCHEMA public TO $POSTGRES_API_USER;
|
||||
GRANT SELECT, INSERT, UPDATE ON ALL TABLES IN SCHEMA public TO $POSTGRES_API_USER;
|
||||
GRANT USAGE, SELECT ON ALL SEQUENCES IN SCHEMA public TO $POSTGRES_API_USER;
|
||||
EOSQL
|
||||
|
||||
echo "User creation and permissions setup complete!"
|
||||
@@ -6,12 +6,10 @@ services:
|
||||
env_file:
|
||||
- .env
|
||||
environment:
|
||||
POSTGRES_USER: ${POSTGRES_ADMIN}
|
||||
POSTGRES_PASSWORD: ${POSTGRES_ADMIN_PASS}
|
||||
POSTGRES_DB: ${POSTGRES_DB}
|
||||
PGDATA: /var/lib/postgresql/data/pg_data
|
||||
volumes:
|
||||
- ${POSTGRES_PATH}:/var/lib/postgresql/data
|
||||
- ${POSTGRES_PATH}/initdb:/docker-entrypoint-initdb.d
|
||||
ports:
|
||||
- 5432:5432
|
||||
|
||||
@@ -28,8 +26,8 @@ services:
|
||||
environment:
|
||||
POSTGRES_HOST: db
|
||||
POSTGRES_DB: ${POSTGRES_DB}
|
||||
POSTGRES_USER: ${POSTGRES_USER}
|
||||
POSTGRES_PASS: ${POSTGRES_PASSWORD}
|
||||
POSTGRES_USER: ${POSTGRES_API_USER}
|
||||
POSTGRES_PASS: ${POSTGRES_API_PASSWORD}
|
||||
EXPOSED_PORT: ${EXPOSED_PORT}
|
||||
DEBUG: true
|
||||
ports:
|
||||
|
||||
@@ -6,8 +6,8 @@ services:
|
||||
env_file:
|
||||
- .env
|
||||
environment:
|
||||
POSTGRES_USER: ${POSTGRES_ADMIN}
|
||||
POSTGRES_PASSWORD: ${POSTGRES_ADMIN_PASS}
|
||||
POSTGRES_USER: ${POSTGRES_USER}
|
||||
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
|
||||
POSTGRES_DB: ${POSTGRES_DB}
|
||||
PGDATA: /var/lib/postgresql/data/pg_data
|
||||
volumes:
|
||||
@@ -21,8 +21,8 @@ services:
|
||||
environment:
|
||||
POSTGRES_HOST: db
|
||||
POSTGRES_DB: ${POSTGRES_DB}
|
||||
POSTGRES_USER: ${POSTGRES_USER}
|
||||
POSTGRES_PASS: ${POSTGRES_PASSWORD}
|
||||
POSTGRES_USER: ${POSTGRES_API_USER}
|
||||
POSTGRES_PASS: ${POSTGRES_API_PASSWORD}
|
||||
EXPOSED_PORT: ${EXPOSED_PORT}
|
||||
ports:
|
||||
- ${EXPOSED_PORT}:8080
|
||||
|
||||
17
Jenkinsfile
vendored
17
Jenkinsfile
vendored
@@ -16,22 +16,9 @@ pipeline {
|
||||
}
|
||||
}
|
||||
steps {
|
||||
sh 'make build_backend'
|
||||
}
|
||||
|
||||
}
|
||||
stage('Deploying image arbeitszeit-backend') {
|
||||
when {
|
||||
anyOf{
|
||||
changeset 'Jenkinsfile'
|
||||
changeset 'Makefile'
|
||||
changeset 'Backend/**'
|
||||
}
|
||||
}
|
||||
steps {
|
||||
sh 'make push_backend'
|
||||
}
|
||||
sh 'make backend'
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
4
Makefile
4
Makefile
@@ -36,3 +36,7 @@ push_%:
|
||||
full_%:
|
||||
make build_$*
|
||||
make push_$*
|
||||
|
||||
backend: login_registry
|
||||
docker buildx build --platform linux/amd64,linux/arm64 -t git.letsstein.de/tom/arbeitszeit-backend:latest Backend --push
|
||||
docker buildx build --platform linux/amd64,linux/arm64 -t git.letsstein.de/tom/arbeitszeit-backend:${GIT_COMMIT} Backend --push
|
||||
|
||||
6
db.sql
6
db.sql
@@ -8,6 +8,7 @@ CREATE TABLE "public"."anwesenheit" (
|
||||
);
|
||||
COMMENT ON COLUMN "public"."anwesenheit"."check_in_out" IS '1=Check In 2=Check Out 255=Automatic Check Out';
|
||||
COMMENT ON COLUMN "public"."anwesenheit"."geraet_id" IS 'ID des Lesegerätes';
|
||||
|
||||
-- @block create table personaldaten
|
||||
CREATE TABLE "public"."personal_daten" (
|
||||
"personal_nummer" SERIAL PRIMARY KEY,
|
||||
@@ -25,9 +26,13 @@ COMMENT ON COLUMN "public"."personal_daten"."akiv_beschaeftig" IS 'derzeit aktiv
|
||||
COMMENT ON COLUMN "public"."personal_daten"."geschlecht" IS 'w:1 m:2 div:3 kA:null ';
|
||||
COMMENT ON COLUMN "public"."personal_daten"."card_uid" IS 'RFID-Karten-UID';
|
||||
COMMENT ON COLUMN "public"."personal_daten"."hauptbeschaeftigung_ort" IS 'Chemnitz:1 Sayda:2';
|
||||
|
||||
|
||||
-- @block drop tables
|
||||
DROP TABLE IF EXISTS "public"."anwesenheit";
|
||||
DROP TABLE IF EXISTS "public"."personal_daten";
|
||||
|
||||
|
||||
-- @block insert into personal_daten
|
||||
INSERT INTO personal_daten (
|
||||
personal_nummer,
|
||||
@@ -53,6 +58,7 @@ VALUES (
|
||||
'test_card',
|
||||
'1'
|
||||
);
|
||||
|
||||
-- @block select
|
||||
SELECT *
|
||||
FROM personal_daten;
|
||||
|
||||
Reference in New Issue
Block a user