package service import ( "encoding/json" "fmt" "os" "time" configurator "git.towk2.me/towk/configurator/pkg" "github.com/go-chi/chi/middleware" "github.com/go-chi/chi/v5" ) const ( PLUGINS_RELPATH = "/plugins" TEMPLATES_RELPATH = "/templates" PROFILES_RELPATH = "/profiles" ) type Service struct { RootPath string `yaml:"root,omitempty"` Environment map[string]string // max counts PluginsMaxCount int ProfilesMaxCount int } // New creates the directories at specified path func New() *Service { return &Service{ RootPath: ".", Environment: map[string]string{ "CONFIGURATOR_HOST_URI": "", "ACCESS_TOKEN": "", }, PluginsMaxCount: 64, ProfilesMaxCount: 256, } } // Serve() starts the configurator service and waits for requests. func (s *Service) Serve() error { router := chi.NewRouter() router.Use(middleware.RequestID) router.Use(middleware.RealIP) router.Use(middleware.Logger) router.Use(middleware.Recoverer) router.Use(middleware.StripSlashes) router.Use(middleware.Timeout(60 * time.Second)) if s.requireAuth() { } else { // general router.Get("/download", s.Download()) router.Post("/upload", s.Upload()) router.Get("/list", s.List()) // profiles router.Get("/profiles", s.GetProfiles()) // router.Post("/profiles", s.CreateProfiles()) router.Get("/profile/{id}", s.GetProfile()) router.Post("/profile/{id}", s.CreateProfile()) router.Get("/profile/{id}/data", s.GetProfileData()) router.Post("/profile/{id}/data", s.SetProfileData()) router.Delete("/profile/{id}/data", s.DeleteProfileData()) router.Post("/profile/{id}/paths/{path}", s.CreateProfilePath()) router.Delete("/profile/{id}/paths/{path}", s.DeleteProfilePath()) router.Get("/profile/{id}/paths/{path}", s.GetProfilePath()) // plugins router.Get("/plugins", s.GetPlugins()) router.Post("/plugins", s.CreatePlugins()) router.Delete("/plugins/{id}", s.DeletePlugins()) } // always available public routes go here router.HandleFunc("/status", s.GetStatus) return nil } func (s *Service) requireAuth() bool { return false } func (s *Service) FetchJwks(uri string) { } func LoadProfileFromFile(path string) (*Profile, error) { return LoadFromJSONFile[Profile](path) } func LoadPluginFromFile(path string) (*configurator.Plugin, error) { return LoadFromJSONFile[configurator.Plugin](path) } func LoadFromJSONFile[T any](path string) (*T, error) { var ( res *T contents []byte err error ) contents, err = os.ReadFile(path) if err != nil { return nil, fmt.Errorf("failed to read plugin file: %v", err) } err = json.Unmarshal(contents, &res) if err != nil { return nil, fmt.Errorf("failed to unmarshal plugin: %v", err) } return res, err } func (s *Service) BuildProfilePath(id string) string { return s.RootPath + PLUGINS_RELPATH + "/" + id }