package service import ( "encoding/json" "io" "net/http" "os" makeshift "git.towk2.me/towk/makeshift/pkg" "github.com/go-chi/chi/v5" ) func (s *Service) ListPlugins() http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { var ( plugins map[string]makeshift.Plugin names []string body []byte err error ) plugins, err = LoadPluginsFromDir(s.PathForPlugins()) if err != nil { http.Error(w, err.Error(), http.StatusBadRequest) return } for name := range plugins { names = append(names, name) } body, err = json.Marshal(names) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } w.Write(body) } } func (s *Service) GetPluginInfo() http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { var ( pluginName = chi.URLParam(r, "name") path = s.PathForPluginWithName(pluginName) plugin makeshift.Plugin body []byte err error ) plugin, err = LoadPluginFromFile(path) if err != nil { http.Error(w, err.Error(), http.StatusBadRequest) return } body, err = json.Marshal(makeshift.PluginToMap(plugin)) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } w.Write(body) } } func (s *Service) GetPluginRaw() http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { var ( pluginName = chi.URLParam(r, "name") path = s.PathForPluginWithName(pluginName) rawPlugin []byte err error ) rawPlugin, err = os.ReadFile(path) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } w.Write(rawPlugin) } } func (s *Service) CreatePlugin() http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { var ( plugin makeshift.Plugin path string err error ) plugin, err = getPluginFromRequestBody(r) if err != nil { http.Error(w, err.Error(), http.StatusBadRequest) return } // helper to check for valid plugin name var hasValidName = func(name string) bool { return name != "" && len(name) < 64 } // check for a valid plugin name if !hasValidName(plugin.Name()) { http.Error(w, err.Error(), http.StatusBadRequest) return } // save plugin at path using it's name path = s.PathForPluginWithName(plugin.Name()) err = SavePluginToFile(path, &plugin) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } w.WriteHeader(http.StatusOK) } } func (s *Service) DeletePlugin() http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { var ( path string plugin makeshift.Plugin err error ) plugin, err = getPluginFromRequestBody(r) if err != nil { http.Error(w, err.Error(), http.StatusBadRequest) return } path = s.PathForPluginWithName(plugin.Name()) err = os.Remove(path) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } w.WriteHeader(http.StatusOK) } } func getPluginFromRequestBody(r *http.Request) (makeshift.Plugin, error) { var ( plugin makeshift.Plugin body []byte err error ) body, err = io.ReadAll(r.Body) if err != nil { return nil, err } err = json.Unmarshal(body, &plugin) if err != nil { return nil, err } return plugin, nil }