diff --git a/config/config.go b/config/config.go index b57f515..538bc64 100644 --- a/config/config.go +++ b/config/config.go @@ -9,9 +9,11 @@ import ( ) type Config struct { - HouseholdName string `yaml:"household_name"` - Port string `yaml:"port"` - DatabasePath string `yaml:"database_path"` + HouseholdName string `yaml:"household_name"` + Port string `yaml:"port"` + DatabasePath string `yaml:"database_path"` + CertificatePath string `yaml:"certificate_path"` + PrivateKeyPath string `yaml:"private_key_path"` } const configPath = "./appdata/config.yaml" @@ -33,9 +35,11 @@ func CheckIfExists() error { } defaultConfig := Config{ - Port: "8080", - DatabasePath: "./appdata/database.db", - HouseholdName: "Example-Household", + Port: "8080", + DatabasePath: "./appdata/database.db", + HouseholdName: "Example-Household", + CertificatePath: "./appdata/cert.pem", + PrivateKeyPath: "./appdata/key.pem", } data, err := yaml.Marshal(defaultConfig) diff --git a/handlers/account.go b/handlers/account.go index d00b9cf..b4b8cbc 100644 --- a/handlers/account.go +++ b/handlers/account.go @@ -210,4 +210,31 @@ func RefreshToken(w http.ResponseWriter, r *http.Request) { http.Error(w, "Internal server error", http.StatusInternalServerError) return } + log.Println("POST [api/refresh] " + r.RemoteAddr + ": Successfully refreshed token") +} +func UserInfo(w http.ResponseWriter, r *http.Request) { + if r.Method != http.MethodGet { + log.Println("GET [api/userinfo] " + r.RemoteAddr + ": Method " + r.Method + " not allowed") + http.Error(w, "Method not allowed", http.StatusMethodNotAllowed) + return + } + query := r.URL.Query() + idParam := query.Get("id") + user, err := storage.GetUserById(idParam) + if err != nil { + log.Println("GET [api/userinfo] " + r.RemoteAddr + ": User " + idParam + " not found") + http.Error(w, "User not found", http.StatusNotFound) + return + } + w.Header().Set("Content-Type", "application/json") + err = json.NewEncoder(w).Encode(map[string]interface{}{ + "id": user.ID, + "name": user.Username, + "avatar_url": nil, + }) + if err != nil { + log.Println("GET [api/userinfo] " + r.RemoteAddr + ": " + err.Error()) + return + } + log.Println("GET [api/userinfo] " + r.RemoteAddr + ": Successfully retrieved user info") } diff --git a/handlers/expenses.go b/handlers/expenses.go index 8d3e299..a311f4a 100644 --- a/handlers/expenses.go +++ b/handlers/expenses.go @@ -15,6 +15,18 @@ func Expenses(w http.ResponseWriter, r *http.Request) { switch r.Method { case http.MethodGet: // -> Get Expenses + expenses, err := storage.GetAllExpenses() + if err != nil { + log.Println("GET [api/expense] " + r.RemoteAddr + ": " + err.Error()) + http.Error(w, "Something went wrong", http.StatusInternalServerError) + return + } + err = json.NewEncoder(w).Encode(expenses) + if err != nil { + log.Println("GET [api/expense] " + r.RemoteAddr + ": " + err.Error()) + return + } + log.Println("GET [api/expense] " + r.RemoteAddr + ": Successfully retrieved expenses") break case http.MethodPost: // -> Create Expense var body struct { diff --git a/main.go b/main.go index 56a8bfc..9aa39f7 100644 --- a/main.go +++ b/main.go @@ -7,17 +7,13 @@ import ( ) func main() { - var SERVER = server.InitServer() + var _server = server.InitServer() - err := storage.InitDB(SERVER.DatabasePath) + err := storage.InitDB(_server.DatabasePath) if err != nil { log.Fatal(err) return } - SERVER.Run() -} - -func Setup() { - //TODO: first configuration + _server.Run() } diff --git a/server/server.go b/server/server.go index 2bb8d4c..f18a8b1 100644 --- a/server/server.go +++ b/server/server.go @@ -10,9 +10,11 @@ import ( ) type Server struct { - Port string - JWTSecret []byte - DatabasePath string + Port string + JWTSecret []byte + DatabasePath string + CertificatePath string + PrivateKeyPath string } var cfg, _ = config.LoadConfig() @@ -42,9 +44,11 @@ func InitServer() *Server { } return &Server{ - Port: cfg.Port, - JWTSecret: []byte(jwtSecret), - DatabasePath: cfg.DatabasePath, + Port: cfg.Port, + JWTSecret: []byte(jwtSecret), + DatabasePath: cfg.DatabasePath, + CertificatePath: cfg.CertificatePath, + PrivateKeyPath: cfg.PrivateKeyPath, } } @@ -62,10 +66,11 @@ func (server *Server) Run() { mux.Handle("/api/expenses", auth.AuthMiddleware(server.JWTSecret)(http.HandlerFunc(handlers.Expenses))) mux.Handle("/api/balance", auth.AuthMiddleware(server.JWTSecret)(http.HandlerFunc(handlers.GetBalance))) mux.Handle("/api/ping", auth.AuthMiddleware(server.JWTSecret)(http.HandlerFunc(handlers.TestHandler))) + mux.Handle("/api/userinfo", auth.AuthMiddleware(server.JWTSecret)(http.HandlerFunc(handlers.UserInfo))) // Admin-only mux.Handle("/api/admin", auth.AuthMiddleware(server.JWTSecret)(auth.RequireRole("admin")(http.HandlerFunc(handlers.AdminPanel)))) log.Printf("Listening on port %s", server.Port) - log.Fatal(http.ListenAndServe(":"+server.Port, mux)) + log.Fatal(http.ListenAndServeTLS(":"+server.Port, server.CertificatePath, server.PrivateKeyPath, mux)) } diff --git a/storage/storage.go b/storage/storage.go index 11d3196..20cb232 100644 --- a/storage/storage.go +++ b/storage/storage.go @@ -120,7 +120,35 @@ func GetExpensesByUserId(userId string) ([]models.Expense, error) { return nil, nil } func GetAllExpenses() ([]models.Expense, error) { - return nil, nil + query := "SELECT * FROM expenses" + rows, err := DB.Query(query) + if err != nil { + return nil, err + } + defer rows.Close() + + var expenses []models.Expense + + for rows.Next() { + var expense models.Expense + var attachmentsJSON []byte + + err := rows.Scan(&expense.ID, &expense.PayerID, &expense.Amount, &expense.Title, &expense.Description, &attachmentsJSON, &expense.CreatedAt, &expense.LastUpdatedAt) + if err != nil { + return nil, err + } + if len(attachmentsJSON) > 0 { + err := json.Unmarshal(attachmentsJSON, &expense.Attachments) + if err != nil { + return nil, err + } + } + expenses = append(expenses, expense) + } + if err = rows.Err(); err != nil { + return nil, err + } + return expenses, nil } // Expense Shares