Skip to content
Snippets Groups Projects
Commit 1d19e692 authored by albrecht's avatar albrecht
Browse files

erste laufende Version erstellt

parent 4e37f9af
No related branches found
No related tags found
No related merge requests found
package model
import "gorm.io/gorm"
type Warenkorb struct {
gorm.Model
Positionen []Position `gorm:"foreignKey:ID;constraint:OnUpdate:CASCADE,OnDelete:CASCADE"`
Gesamtpreis float64 `gorm:"notNull;default:0.0"`
Username string `gorm:"unique"`
}
package service
import (
"fmt"
"strings"
"time"
"github.com/dgrijalva/jwt-go"
)
func GenerateAdminJWTToken(username string, isAdmin bool, expiration time.Time) (string, error) {
claims := jwt.MapClaims{
"username": username,
"isAdmin": isAdmin,
"exp": expiration.Unix(),
}
token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
// Generiere den Token mit einem geheimen Schlüssel
tokenString, err := token.SignedString([]byte("key-replacement"))
if err != nil {
return "", err
}
return tokenString, nil
}
// Funktion zum Extrahieren von Informationen aus dem JWT-Token
func ExtractTokenData(tokenString string) (string, bool, error) {
tokenString = strings.TrimPrefix(tokenString, "Bearer ")
// Token parsen
token, err := jwt.Parse(tokenString, func(token *jwt.Token) (interface{}, error) {
// Geheimer Schlüssel für die Token-Validierung
return []byte("key-replacement"), nil
})
if err != nil {
return "", false, err
}
// Überprüfen, ob das Token gültig ist
if !token.Valid {
return "", false, fmt.Errorf("invalid token")
}
if claims, ok := token.Claims.(jwt.MapClaims); ok {
expirationTime := time.Unix(int64(claims["exp"].(float64)), 0)
if time.Now().After(expirationTime) {
return "", false, fmt.Errorf("token has expired")
}
} else {
return "", false, fmt.Errorf("invalid token claims")
}
// Claims aus dem Token extrahieren
claims, ok := token.Claims.(jwt.MapClaims)
if !ok {
return "", false, fmt.Errorf("invalid token claims")
}
// Benutzername und isAdmin aus den Claims erhalten
username, ok := claims["username"].(string)
if !ok {
return "", false, fmt.Errorf("invalid username claim")
}
isAdmin, ok := claims["isAdmin"].(bool)
if !ok {
return "", false, fmt.Errorf("invalid isAdmin claim")
}
return username, isAdmin, nil
}
package service
import (
"errors"
"fmt"
log "github.com/sirupsen/logrus"
"gitlab.reutlingen-university.de/albrecht/gomazon/db"
"gitlab.reutlingen-university.de/albrecht/gomazon/model"
"gorm.io/gorm"
)
type BankAccountService struct{}
// Bankkonto erstellen
func (s *BankAccountService) CreateBankAccount(bankAccount model.BankAccount) (*model.BankAccount, error) {
// Überprüfen, ob der Benutzername bereits vorhanden ist
existingAccount := &model.BankAccount{}
result := db.DB.Where("username = ?", bankAccount.Username).First(existingAccount)
if result.Error == nil {
return existingAccount, nil
} else if !errors.Is(result.Error, gorm.ErrRecordNotFound) {
return nil, result.Error
}
// Hier den Code für die Datenbankoperation zum Erstellen des Bankkontos einfügen
result = db.DB.Create(&bankAccount)
if result.Error != nil {
return nil, result.Error
}
return &bankAccount, nil
}
func (s *BankAccountService) UpdateBankAccount(username string, amount float64) (*model.BankAccount, error) {
// Bankkonto des Benutzernamens finden
bankAccount := &model.BankAccount{}
result := db.DB.Where("username = ?", username).First(bankAccount)
if result.Error != nil {
if errors.Is(result.Error, gorm.ErrRecordNotFound) {
log.Errorf("Bankkonto mit Benutzernamen %s nicht gefunden", username)
}
return nil, result.Error
}
// Überprüfen, ob der Betrag zu einem negativen Kontostand führen würde
if amount < 0 && bankAccount.Balance+amount < 0 {
log.Error("Abhebungsbetrag übersteigt das Guthaben auf dem Bankkonto")
return nil, fmt.Errorf("der Abhebungsbetrag übersteigt das Guthaben auf dem Bankkonto")
}
// Einzahlung oder Abhebung vom Bankkonto durchführen
bankAccount.Balance += amount
// Bankkonto in einer einzelnen Datenbankoperation speichern
result = db.DB.Save(bankAccount)
if result.Error != nil {
return nil, result.Error
}
return bankAccount, nil
}
func (s *BankAccountService) GetBankAccountByUsername(username string) (*model.BankAccount, error) {
bankAccount := &model.BankAccount{}
result := db.DB.Where("username = ?", username).First(bankAccount)
if result.Error != nil {
return nil, result.Error
}
return bankAccount, nil
}
package service
import (
log "github.com/sirupsen/logrus"
"gitlab.reutlingen-university.de/albrecht/gomazon/db"
"gitlab.reutlingen-university.de/albrecht/gomazon/model"
)
type BewertungService struct {
ProduktService *ProduktService
}
func (s *BewertungService) CreateBewertung(produktID uint, bewertung *model.Bewertung) error {
bewertung.ProduktId = produktID
result := db.DB.Create(bewertung)
if result.Error != nil {
return result.Error
}
produkt, err := s.ProduktService.GetProduktByID(produktID)
if err != nil {
log.Errorf("Error in CreateBewertung: GetProduktByID failed")
return nil
}
err = RecalculateGesamtratingForProdukt(produkt)
if err != nil {
log.Errorf("Recalculation failed")
return nil
}
entry := log.WithField("ID", produktID)
entry.Info("Successfully added new rating to a product.")
entry.Tracef("Stored: %v", produktID)
return nil
}
func (s *BewertungService) DeleteBewertung(bewertungID uint) error {
bewertung, err := s.ProduktService.GetBewertungByID(bewertungID)
if err != nil {
log.Errorf("failed to get Produkt: %v", err)
return nil
}
result := db.DB.Delete(&bewertung)
if result.Error != nil {
return result.Error
}
return nil
}
func (s *ProduktService) GetBewertungByID(id uint) (*model.Bewertung, error) {
var bewertung model.Bewertung
result := db.DB.First(&bewertung, id)
if result.Error != nil {
return nil, result.Error
}
return &bewertung, nil
}
func (s *ProduktService) ReadBewertungen() ([]model.Bewertung, error) {
var bewertungen []model.Bewertung
result := db.DB.Find(&bewertungen)
if result.Error != nil {
return nil, result.Error
}
return bewertungen, nil
}
func RecalculateGesamtratingForProdukt(produkt *model.Produkt) error {
// Gesamtrating zurücksetzen
produkt.Gesamtrating = 0.0
// Bewertungen für das Produkt aus der Datenbank abrufen
var bewertungen []model.Bewertung
err := db.DB.Where("produkt_id = ?", produkt.ID).Find(&bewertungen).Error
if err != nil {
return err
}
numRatings := len(bewertungen)
if numRatings > 0 {
totalRating := 0
for _, bewertung := range bewertungen {
totalRating += bewertung.Bewertung
}
produkt.Gesamtrating = float64(totalRating) / float64(numRatings)
}
// Produkt in der Datenbank aktualisieren
err = db.DB.Save(produkt).Error
if err != nil {
return err
}
return nil
}
package service
import (
"gitlab.reutlingen-university.de/albrecht/gomazon/db"
"gitlab.reutlingen-university.de/albrecht/gomazon/model"
)
type ProduktService struct{}
func (s *ProduktService) CreateProdukt(produkt model.Produkt) (*model.Produkt, error) {
result := db.DB.Create(&produkt)
if result.Error != nil {
return nil, result.Error
}
return &produkt, nil
}
func (s *ProduktService) ReadProdukte() ([]model.Produkt, error) {
var produkte []model.Produkt
result := db.DB.Find(&produkte)
if result.Error != nil {
return nil, result.Error
}
return produkte, nil
}
func (s *ProduktService) UpdateProdukt(id uint, produktChanges model.Produkt) (*model.Produkt, error) {
produkt, err := s.GetProduktByID(id)
if err != nil {
return nil, err
}
produkt.Name = produktChanges.Name
produkt.Description = produktChanges.Description
produkt.Preis = produktChanges.Preis
produkt.Bewertungen = produktChanges.Bewertungen
result := db.DB.Save(&produkt)
if result.Error != nil {
return nil, result.Error
}
return produkt, nil
}
func (s *ProduktService) DeleteProdukt(id uint) error {
produkt, err := s.GetProduktByID(id)
if err != nil {
return err
}
result := db.DB.Delete(&produkt)
if result.Error != nil {
return result.Error
}
return nil
}
func (s *ProduktService) GetProduktByID(id uint) (*model.Produkt, error) {
var produkt model.Produkt
result := db.DB.First(&produkt, id)
if result.Error != nil {
return nil, result.Error
}
return &produkt, nil
}
package service
import (
"errors"
"gitlab.reutlingen-university.de/albrecht/gomazon/db"
"gitlab.reutlingen-university.de/albrecht/gomazon/model"
"gorm.io/gorm"
)
type WarenkorbService struct {
BankAccountService *BankAccountService
}
// Warenkorb erstellen
func (s *WarenkorbService) CreateWarenkorb(warenkorb model.Warenkorb) (*model.Warenkorb, error) {
// Überprüfen, ob der Warenkorb für den Benutzernamen bereits vorhanden ist
existingWarenkorb := &model.Warenkorb{}
result := db.DB.Where("username = ?", warenkorb.Username).First(existingWarenkorb)
if result.Error == nil {
return existingWarenkorb, nil
} else if !errors.Is(result.Error, gorm.ErrRecordNotFound) {
return nil, result.Error
}
// Hier den Code für die Datenbankoperation zum Erstellen des Warenkorbs einfügen
result = db.DB.Create(&warenkorb)
if result.Error != nil {
return nil, result.Error
}
return &warenkorb, nil
}
// Einzelnes Produkt zum Warenkorb hinzufügen
func (s *WarenkorbService) AddProductToWarenkorb(username string, produktID uint, menge int) (*model.Warenkorb, error) {
warenkorb := &model.Warenkorb{}
result := db.DB.Preload("Positionen").Where("username = ?", username).First(warenkorb)
if result.Error != nil {
return nil, result.Error
}
produkt := &model.Produkt{}
result = db.DB.First(produkt, produktID)
if result.Error != nil {
return nil, result.Error
}
gesPreis := produkt.Preis * float64(menge)
position := model.Position{
Menge: menge,
ProduktId: produkt.ID,
Preis: produkt.Preis,
Gesamtpreis: gesPreis,
}
warenkorb.Positionen = append(warenkorb.Positionen, position)
warenkorb.Gesamtpreis += position.Gesamtpreis
result = db.DB.Save(warenkorb)
if result.Error != nil {
return nil, result.Error
}
return warenkorb, nil
}
// Bezahlfunktion für den Warenkorb
func (s *WarenkorbService) Bezahlen(username string) error {
warenkorb := &model.Warenkorb{}
result := db.DB.Preload("Positionen").Where("username = ?", username).First(warenkorb)
if result.Error != nil {
return result.Error
}
bankAccount, err := s.BankAccountService.GetBankAccountByUsername(username)
if err != nil {
return err
}
// Überprüfen, ob das Bankkonto ausreichend Guthaben hat
if bankAccount.Balance < warenkorb.Gesamtpreis {
return errors.New("nicht genügend Guthaben auf dem Bankkonto")
}
// Banküberweisung durchführen
_, err = s.BankAccountService.UpdateBankAccount(username, -warenkorb.Gesamtpreis)
if err != nil {
return err
}
// Einträge im Warenkorb zurücksetzen
for i := range warenkorb.Positionen {
warenkorb.Positionen[i].Menge = 0
}
warenkorb.Gesamtpreis = 0.0
result = db.DB.Save(warenkorb)
if result.Error != nil {
return result.Error
}
return nil
}
#!/usr/bin/env bash
# Use this script to test if a given TCP host/port are available
WAITFORIT_cmdname=${0##*/}
echoerr() { if [[ $WAITFORIT_QUIET -ne 1 ]]; then echo "$@" 1>&2; fi }
usage()
{
cat << USAGE >&2
Usage:
$WAITFORIT_cmdname host:port [-s] [-t timeout] [-- command args]
-h HOST | --host=HOST Host or IP under test
-p PORT | --port=PORT TCP port under test
Alternatively, you specify the host and port as host:port
-s | --strict Only execute subcommand if the test succeeds
-q | --quiet Don't output any status messages
-t TIMEOUT | --timeout=TIMEOUT
Timeout in seconds, zero for no timeout
-- COMMAND ARGS Execute command with args after the test finishes
USAGE
exit 1
}
wait_for()
{
if [[ $WAITFORIT_TIMEOUT -gt 0 ]]; then
echoerr "$WAITFORIT_cmdname: waiting $WAITFORIT_TIMEOUT seconds for $WAITFORIT_HOST:$WAITFORIT_PORT"
else
echoerr "$WAITFORIT_cmdname: waiting for $WAITFORIT_HOST:$WAITFORIT_PORT without a timeout"
fi
WAITFORIT_start_ts=$(date +%s)
while :
do
if [[ $WAITFORIT_ISBUSY -eq 1 ]]; then
nc -z $WAITFORIT_HOST $WAITFORIT_PORT
WAITFORIT_result=$?
else
(echo -n > /dev/tcp/$WAITFORIT_HOST/$WAITFORIT_PORT) >/dev/null 2>&1
WAITFORIT_result=$?
fi
if [[ $WAITFORIT_result -eq 0 ]]; then
WAITFORIT_end_ts=$(date +%s)
echoerr "$WAITFORIT_cmdname: $WAITFORIT_HOST:$WAITFORIT_PORT is available after $((WAITFORIT_end_ts - WAITFORIT_start_ts)) seconds"
break
fi
sleep 1
done
return $WAITFORIT_result
}
wait_for_wrapper()
{
# In order to support SIGINT during timeout: http://unix.stackexchange.com/a/57692
if [[ $WAITFORIT_QUIET -eq 1 ]]; then
timeout $WAITFORIT_BUSYTIMEFLAG $WAITFORIT_TIMEOUT $0 --quiet --child --host=$WAITFORIT_HOST --port=$WAITFORIT_PORT --timeout=$WAITFORIT_TIMEOUT &
else
timeout $WAITFORIT_BUSYTIMEFLAG $WAITFORIT_TIMEOUT $0 --child --host=$WAITFORIT_HOST --port=$WAITFORIT_PORT --timeout=$WAITFORIT_TIMEOUT &
fi
WAITFORIT_PID=$!
trap "kill -INT -$WAITFORIT_PID" INT
wait $WAITFORIT_PID
WAITFORIT_RESULT=$?
if [[ $WAITFORIT_RESULT -ne 0 ]]; then
echoerr "$WAITFORIT_cmdname: timeout occurred after waiting $WAITFORIT_TIMEOUT seconds for $WAITFORIT_HOST:$WAITFORIT_PORT"
fi
return $WAITFORIT_RESULT
}
# process arguments
while [[ $# -gt 0 ]]
do
case "$1" in
*:* )
WAITFORIT_hostport=(${1//:/ })
WAITFORIT_HOST=${WAITFORIT_hostport[0]}
WAITFORIT_PORT=${WAITFORIT_hostport[1]}
shift 1
;;
--child)
WAITFORIT_CHILD=1
shift 1
;;
-q | --quiet)
WAITFORIT_QUIET=1
shift 1
;;
-s | --strict)
WAITFORIT_STRICT=1
shift 1
;;
-h)
WAITFORIT_HOST="$2"
if [[ $WAITFORIT_HOST == "" ]]; then break; fi
shift 2
;;
--host=*)
WAITFORIT_HOST="${1#*=}"
shift 1
;;
-p)
WAITFORIT_PORT="$2"
if [[ $WAITFORIT_PORT == "" ]]; then break; fi
shift 2
;;
--port=*)
WAITFORIT_PORT="${1#*=}"
shift 1
;;
-t)
WAITFORIT_TIMEOUT="$2"
if [[ $WAITFORIT_TIMEOUT == "" ]]; then break; fi
shift 2
;;
--timeout=*)
WAITFORIT_TIMEOUT="${1#*=}"
shift 1
;;
--)
shift
WAITFORIT_CLI=("$@")
break
;;
--help)
usage
;;
*)
echoerr "Unknown argument: $1"
usage
;;
esac
done
if [[ "$WAITFORIT_HOST" == "" || "$WAITFORIT_PORT" == "" ]]; then
echoerr "Error: you need to provide a host and port to test."
usage
fi
WAITFORIT_TIMEOUT=${WAITFORIT_TIMEOUT:-15}
WAITFORIT_STRICT=${WAITFORIT_STRICT:-0}
WAITFORIT_CHILD=${WAITFORIT_CHILD:-0}
WAITFORIT_QUIET=${WAITFORIT_QUIET:-0}
# Check to see if timeout is from busybox?
WAITFORIT_TIMEOUT_PATH=$(type -p timeout)
WAITFORIT_TIMEOUT_PATH=$(realpath $WAITFORIT_TIMEOUT_PATH 2>/dev/null || readlink -f $WAITFORIT_TIMEOUT_PATH)
WAITFORIT_BUSYTIMEFLAG=""
if [[ $WAITFORIT_TIMEOUT_PATH =~ "busybox" ]]; then
WAITFORIT_ISBUSY=1
# Check if busybox timeout uses -t flag
# (recent Alpine versions don't support -t anymore)
if timeout &>/dev/stdout | grep -q -e '-t '; then
WAITFORIT_BUSYTIMEFLAG="-t"
fi
else
WAITFORIT_ISBUSY=0
fi
if [[ $WAITFORIT_CHILD -gt 0 ]]; then
wait_for
WAITFORIT_RESULT=$?
exit $WAITFORIT_RESULT
else
if [[ $WAITFORIT_TIMEOUT -gt 0 ]]; then
wait_for_wrapper
WAITFORIT_RESULT=$?
else
wait_for
WAITFORIT_RESULT=$?
fi
fi
if [[ $WAITFORIT_CLI != "" ]]; then
if [[ $WAITFORIT_RESULT -ne 0 && $WAITFORIT_STRICT -eq 1 ]]; then
echoerr "$WAITFORIT_cmdname: strict mode, refusing to execute subprocess"
exit $WAITFORIT_RESULT
fi
exec "${WAITFORIT_CLI[@]}"
else
exit $WAITFORIT_RESULT
fi
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment