143 lines
4.8 KiB
Go
143 lines
4.8 KiB
Go
package main
|
|
|
|
import (
|
|
"fmt"
|
|
"os"
|
|
_ "ttime/docs"
|
|
"ttime/internal/config"
|
|
"ttime/internal/database"
|
|
"ttime/internal/handlers/projects"
|
|
"ttime/internal/handlers/reports"
|
|
"ttime/internal/handlers/users"
|
|
|
|
"github.com/BurntSushi/toml"
|
|
"github.com/gofiber/fiber/v2"
|
|
"github.com/gofiber/fiber/v2/middleware/logger"
|
|
"github.com/gofiber/swagger"
|
|
|
|
jwtware "github.com/gofiber/contrib/jwt"
|
|
)
|
|
|
|
// @title TTime API
|
|
// @version 0.0.1
|
|
// @description This is the API for TTime, a time tracking application.
|
|
|
|
// @license.name AGPL
|
|
// @license.url https://www.gnu.org/licenses/agpl-3.0.html
|
|
|
|
// @securityDefinitions.apikey JWT
|
|
// @in header
|
|
// @name Authorization
|
|
// @description Use the JWT token provided by the login endpoint to authenticate requests. **Prefix the token with "Bearer ".**
|
|
|
|
// @host localhost:8080
|
|
// @BasePath /api
|
|
|
|
// @externalDocs.description OpenAPI
|
|
// @externalDocs.url https://swagger.io/resources/open-api/
|
|
|
|
/**
|
|
Main function for starting the server and initializing configurations.
|
|
Reads configuration from file, pretty prints it, connects to the database,
|
|
migrates it, and sets up routes for the server.
|
|
*/
|
|
|
|
func main() {
|
|
conf, err := config.ReadConfigFromFile("config.toml")
|
|
if err != nil {
|
|
conf = config.NewConfig()
|
|
_ = conf.WriteConfigToFile("config.toml")
|
|
}
|
|
|
|
// Pretty print the current config with toml
|
|
_ = toml.NewEncoder(os.Stdout).Encode(conf)
|
|
|
|
fmt.Printf("Starting server on http://localhost:%d\n", conf.Port)
|
|
fmt.Printf("For documentation, go to http://localhost:%d/swagger/index.html\n", conf.Port)
|
|
|
|
// Connect to the database
|
|
db := database.DbConnect(conf.DbPath)
|
|
|
|
// Migrate the database
|
|
if err = db.Migrate(); err != nil {
|
|
fmt.Println("Error migrating database: ", err)
|
|
os.Exit(1)
|
|
}
|
|
|
|
// Migrate sample data, should not be used in production
|
|
if err = db.MigrateSampleData(); err != nil {
|
|
fmt.Println("Error migrating sample data: ", err)
|
|
os.Exit(1)
|
|
}
|
|
|
|
// Create the server
|
|
server := fiber.New()
|
|
|
|
// We want some logs
|
|
server.Use(logger.New())
|
|
|
|
// Sets up db middleware, accessed as Local "db" key
|
|
server.Use(database.DbMiddleware(&db))
|
|
|
|
// Mounts the swagger documentation, this is available at /swagger/index.html
|
|
server.Get("/swagger/*", swagger.HandlerDefault)
|
|
|
|
// Mount our static files (Beware of the security implications of this!)
|
|
// This will likely be replaced by an embedded filesystem in the future
|
|
server.Static("/", "./static")
|
|
|
|
// Create a group for our API
|
|
api := server.Group("/api")
|
|
|
|
// Register our unprotected routes
|
|
api.Post("/register", users.Register)
|
|
api.Post("/login", users.Login)
|
|
|
|
// Every route from here on will require a valid
|
|
// JWT bearer token authentication in the header
|
|
server.Use(jwtware.New(jwtware.Config{
|
|
SigningKey: jwtware.SigningKey{Key: []byte("secret")},
|
|
}))
|
|
|
|
// All user related routes
|
|
// userGroup := api.Group("/user") // Not currently in use
|
|
api.Get("/users/all", users.ListAllUsers)
|
|
api.Get("/project/getAllUsers", users.GetAllUsersProject)
|
|
api.Get("/username", users.GetUserName)
|
|
api.Post("/login", users.Login)
|
|
api.Post("/register", users.Register)
|
|
api.Post("/loginrenew", users.LoginRenew)
|
|
api.Post("/promoteToAdmin", users.PromoteToAdmin)
|
|
api.Put("/changeUserName", users.ChangeUserName)
|
|
api.Delete("/userdelete/:username", users.UserDelete) // Perhaps just use POST to avoid headaches
|
|
|
|
// All project related routes
|
|
// projectGroup := api.Group("/project") // Not currently in use
|
|
api.Get("/getProjectTimes/:projectName", projects.GetProjectTimesHandler)
|
|
api.Get("/getUserProjects/:username", projects.GetUserProjects)
|
|
api.Get("/project/:projectId", projects.GetProject)
|
|
api.Get("/checkIfProjectManager/:projectName", projects.IsProjectManagerHandler)
|
|
api.Get("/getUsersProject/:projectName", projects.ListAllUsersProject)
|
|
api.Post("/project", projects.CreateProject)
|
|
api.Post("/ProjectRoleChange", projects.ProjectRoleChange)
|
|
api.Put("/promoteToPm/:projectName", projects.PromoteToPm)
|
|
api.Put("/addUserToProject/:projectName", projects.AddUserToProjectHandler)
|
|
api.Delete("/removeUserFromProject/:projectName", projects.RemoveUserFromProject)
|
|
api.Delete("/removeProject/:projectName", projects.RemoveProject)
|
|
api.Delete("/project/:projectID", projects.DeleteProject)
|
|
|
|
// All report related routes
|
|
// reportGroup := api.Group("/report") // Not currently in use
|
|
api.Get("/getWeeklyReport", reports.GetWeeklyReport)
|
|
api.Get("/getUnsignedReports/:projectName", reports.GetUnsignedReports)
|
|
api.Get("/getAllWeeklyReports/:projectName", reports.GetAllWeeklyReports)
|
|
api.Post("/submitWeeklyReport", reports.SubmitWeeklyReport)
|
|
api.Put("/signReport/:reportId", reports.SignReport)
|
|
api.Put("/updateWeeklyReport", reports.UpdateWeeklyReport)
|
|
|
|
// Announce the port we are listening on and start the server
|
|
err = server.Listen(fmt.Sprintf(":%d", conf.Port))
|
|
if err != nil {
|
|
fmt.Println("Error starting server: ", err)
|
|
}
|
|
}
|