// List return files func List() echo.HandlerFunc { return func(c echo.Context) error { appPath := c.Param("app_path") if appPath == "" { return api.ErrorNotFound(c, nil) } path := c.P(1) app, err := api.GetApp(appPath) if err != nil { return api.ErrorInternal(c, err) } if app == nil { return api.ErrorNotFound(c, nil) } parser, err := storage.NewLocalParser(api.Owner(c), appPath) if err != nil { return api.ErrorInternal(c, err) } files, err := parser.Storage.GetFiles(parser.Storage.GetRootPrefix(path)) if err != nil { return api.ErrorInternal(c, err) } return c.JSON(http.StatusOK, files) } }
// Delete file func Delete() echo.HandlerFunc { return func(c echo.Context) error { appPath := c.Param("app_path") if appPath == "" { return api.ErrorNotFound(c, nil) } path := c.P(1) if api.IsAnonymous(c) { return api.ErrorUnauthorized(c, nil) } app, err := api.GetApp(appPath) if err != nil { return api.ErrorInternal(c, err) } if app == nil { return api.ErrorNotFound(c, nil) } parser, err := storage.NewLocalParser(api.Owner(c), appPath) if err != nil { return api.ErrorInternal(c, err) } parser.Storage.Delete(parser.Storage.GetSourceKey(path)) output := &get3w.FileDeleteOutput{ LastModified: timeutils.ToString(time.Now()), } return c.JSON(http.StatusOK, output) } }
// Get file content func Get() echo.HandlerFunc { return func(c echo.Context) error { appPath := c.Param("app_path") if appPath == "" { return api.ErrorNotFound(c, nil) } path := c.P(1) app, err := api.GetApp(appPath) if err != nil { return api.ErrorInternal(c, err) } if app == nil { return api.ErrorNotFound(c, nil) } parser, err := storage.NewLocalParser(api.Owner(c), appPath) if err != nil { return api.ErrorInternal(c, err) } data, err := parser.Storage.Read(parser.Storage.GetSourceKey(path)) if err != nil { return api.ErrorNotFound(c, nil) } output := &get3w.FileGetOutput{ Content: base64.StdEncoding.EncodeToString(data), } return c.JSON(http.StatusOK, output) } }
// Save app func Save() echo.HandlerFunc { return func(c echo.Context) error { appPath := c.Param("app_path") if appPath == "" { return api.ErrorNotFound(c, nil) } if api.IsAnonymous(c) { return api.ErrorUnauthorized(c, nil) } input := &get3w.AppSaveInput{} err := api.LoadRequestInput(c, input) if err != nil { return api.ErrorBadRequest(c, err) } parser, err := storage.NewLocalParser(api.Owner(c), appPath) if err != nil { return api.ErrorInternal(c, err) } err = parser.APISave(input.Payloads) if err != nil { return api.ErrorInternal(c, err) } return c.JSON(http.StatusOK, &get3w.AppSaveOutput{ LastModified: timeutils.ToString(time.Now()), }) } }
// Push file content func Push() echo.HandlerFunc { return func(c echo.Context) error { appPath := c.Param("app_path") if appPath == "" { return api.ErrorNotFound(c, nil) } if api.IsAnonymous(c) { return api.ErrorUnauthorized(c, nil) } input := &get3w.FilesPushInput{} err := api.LoadRequestInput(c, input) if err != nil { return api.ErrorBadRequest(c, err) } app, err := api.GetApp(appPath) if err != nil { return api.ErrorInternal(c, err) } if app == nil { return api.ErrorNotFound(c, nil) } parser, err := storage.NewLocalParser(api.Owner(c), appPath) if err != nil { return api.ErrorInternal(c, err) } data, err := base64.StdEncoding.DecodeString(input.Blob) if err != nil { return api.ErrorInternal(c, err) } pathBytesMap, err := ioutils.UnPack(data) if err != nil { return api.ErrorInternal(c, err) } for _, addedPath := range input.Added { parser.Storage.Write(parser.Storage.GetSourceKey(addedPath), pathBytesMap[addedPath]) } for _, modifiedPath := range input.Modified { parser.Storage.Write(parser.Storage.GetSourceKey(modifiedPath), pathBytesMap[modifiedPath]) } for _, removedPath := range input.Removed { parser.Storage.Delete(parser.Storage.GetSourceKey(removedPath)) } output := &get3w.FileEditOutput{ LastModified: timeutils.ToString(time.Now()), } return c.JSON(http.StatusOK, output) } }
// Login user login func Login() echo.HandlerFunc { return func(c echo.Context) error { input := &get3w.UserLoginInput{} err := api.LoadRequestInput(c, input) if err != nil { return api.ErrorBadRequest(c, err) } if input.Account == "" || input.Password == "" { return api.ErrorUnauthorized(c, nil) } client := get3w.NewClient("") output, _, err := client.Users.Login(input) if err != nil { return api.ErrorUnauthorized(c, err) } config, _ := home.LoadConfig() config.AuthConfig = home.AuthConfig{ Username: output.User.Username, Password: input.Password, AccessToken: output.AccessToken, } if err := config.Save(); err != nil { return api.ErrorInternal(c, fmt.Errorf("ERROR: failed to save config file: %v", err)) } return c.JSON(http.StatusOK, output) } }
// Edit file content func Edit() echo.HandlerFunc { return func(c echo.Context) error { appPath := c.Param("app_path") if appPath == "" { return api.ErrorNotFound(c, nil) } path := c.P(1) if api.IsAnonymous(c) { return api.ErrorUnauthorized(c, nil) } input := &get3w.FileEditInput{} err := api.LoadRequestInput(c, input) if err != nil { return api.ErrorBadRequest(c, err) } app, err := api.GetApp(appPath) if err != nil { return api.ErrorInternal(c, err) } if app == nil { return api.ErrorNotFound(c, nil) } parser, err := storage.NewLocalParser(api.Owner(c), appPath) if err != nil { return api.ErrorInternal(c, err) } data, err := base64.StdEncoding.DecodeString(input.Content) if err != nil { return api.ErrorInternal(c, err) } err = parser.Storage.Write(parser.Storage.GetSourceKey(path), data) if err != nil { return api.ErrorInternal(c, err) } output := &get3w.FileEditOutput{ LastModified: timeutils.ToString(time.Now()), } return c.JSON(http.StatusOK, output) } }
// Sync app func Sync() echo.HandlerFunc { return func(c echo.Context) error { appPath := c.Param("app_path") if appPath == "" { return api.ErrorNotFound(c, nil) } if api.IsAnonymous(c) { return api.ErrorUnauthorized(c, nil) } app, err := api.GetApp(appPath) if err != nil { return api.ErrorInternal(c, err) } if app == nil { return api.ErrorNotFound(c, nil) } config, err := home.LoadConfig() if err != nil { return api.ErrorInternal(c, err) } parser, err := storage.NewLocalParser(api.Owner(c), appPath) if err != nil { return api.ErrorInternal(c, err) } buffer := bytes.NewBufferString("") shouldLogin, err := parser.Push(&config.AuthConfig, buffer) if shouldLogin { return api.ErrorUnauthorized(c, nil) } if err != nil { return api.ErrorInternal(c, err) } return c.JSON(http.StatusOK, &get3w.AppSyncOutput{ Log: strings.Replace(buffer.String(), "\n", "<br />", -1), }) } }
// Logout user logout func Logout() echo.HandlerFunc { return func(c echo.Context) error { config, _ := home.LoadConfig() err := config.Logout() if err != nil { return api.ErrorInternal(c, err) } return c.JSON(http.StatusOK, map[string]interface{}{}) } }
// Create create folder func Create() echo.HandlerFunc { return func(c echo.Context) error { appPath := c.Param("app_path") if appPath == "" { return api.ErrorNotFound(c, nil) } if api.IsAnonymous(c) { return api.ErrorUnauthorized(c, nil) } input := &get3w.FolderCreateInput{} err := api.LoadRequestInput(c, input) if err != nil { return api.ErrorBadRequest(c, err) } if input.Path == "" { return api.ErrorBadRequest(c, nil) } app, err := api.GetApp(appPath) if err != nil { return api.ErrorInternal(c, err) } if app == nil { return api.ErrorNotFound(c, nil) } parser, err := storage.NewLocalParser(api.Owner(c), appPath) if err != nil { return api.ErrorInternal(c, err) } parser.Storage.NewFolder(parser.Storage.GetSourcePrefix(input.Path)) output := &get3w.FolderCreateOutput{ LastModified: timeutils.ToString(time.Now()), } return c.JSON(http.StatusOK, output) } }
// List return apps func List() echo.HandlerFunc { return func(c echo.Context) error { if api.IsAnonymous(c) { return api.ErrorUnauthorized(c, nil) } config, err := home.LoadConfig() if err != nil { return api.ErrorInternal(c, err) } return c.JSON(http.StatusOK, config.Apps) } }
// Checksum get path and checksum map of all files, dedicated to cli func Checksum() echo.HandlerFunc { return func(c echo.Context) error { appPath := c.Param("app_path") if appPath == "" { return api.ErrorNotFound(c, nil) } app, err := api.GetApp(appPath) if err != nil { return api.ErrorInternal(c, err) } if app == nil { return api.ErrorNotFound(c, nil) } parser, err := storage.NewLocalParser(api.Owner(c), appPath) if err != nil { return api.ErrorInternal(c, err) } files, err := parser.Storage.GetAllFiles(parser.Storage.GetSourcePrefix("")) if err != nil { return api.ErrorInternal(c, err) } output := &get3w.FilesChecksumOutput{ Files: make(map[string]string), } for _, file := range files { output.Files[file.Path] = file.Checksum } return c.JSON(http.StatusOK, output) } }
// Publish app func Publish() echo.HandlerFunc { return func(c echo.Context) error { appPath := c.Param("app_path") if appPath == "" { return api.ErrorNotFound(c, nil) } if api.IsAnonymous(c) { return api.ErrorUnauthorized(c, nil) } parser, err := storage.NewLocalParser(api.Owner(c), appPath) if err != nil { return api.ErrorInternal(c, err) } parser.Build(true) return c.String(http.StatusOK, "") } }
// Load app func Load() echo.HandlerFunc { return func(c echo.Context) error { appPath := c.Param("app_path") if appPath == "" { return api.ErrorNotFound(c, nil) } if api.IsAnonymous(c) { return api.ErrorUnauthorized(c, nil) } input := &get3w.AppLoadInput{} err := api.LoadRequestInput(c, input) if err != nil { return api.ErrorBadRequest(c, err) } app, err := api.GetApp(appPath) if err != nil { return api.ErrorInternal(c, err) } if app == nil { return api.ErrorNotFound(c, nil) } parser, err := storage.NewLocalParser(api.Owner(c), appPath) if err != nil { return api.ErrorBadRequest(c, err) } parser.APILoad() output := &get3w.AppLoadOutput{ LastModified: timeutils.ToString(time.Now()), App: app, Config: parser.Config, Sites: parser.Sites, } return c.JSON(http.StatusOK, output) } }
// Get app func Get() echo.HandlerFunc { return func(c echo.Context) error { appPath := c.Param("app_path") if appPath == "" { return api.ErrorNotFound(c, nil) } if api.IsAnonymous(c) { return api.ErrorUnauthorized(c, nil) } app, err := api.GetApp(appPath) if err != nil { return api.ErrorInternal(c, err) } if app == nil { return api.ErrorNotFound(c, nil) } return c.JSON(http.StatusOK, app) } }
// Add app, for open and clone operation func Add() echo.HandlerFunc { return func(c echo.Context) error { if api.IsAnonymous(c) { return api.ErrorUnauthorized(c, nil) } owner := api.Owner(c) input := &get3w.AppAddInput{} err := api.LoadRequestInput(c, input) if err != nil { return api.ErrorBadRequest(c, err) } dirPath := input.DirPath dirExists := true if dirPath == "" { dirExists = false } else { stat, err := os.Lstat(dirPath) if err != nil { dirExists = false } else if !stat.IsDir() { dirExists = false } } if !dirExists { return api.ErrorNotFound(c, nil) } config, err := home.LoadConfig() if err != nil { return api.ErrorBadRequest(c, err) } success := true configExists := true var app *get3w.App var appPath string if input.Origin != "" { appPath, err = addFromCloud(dirPath, input.Origin, &config.AuthConfig) if err != nil { return api.ErrorBadRequest(c, err) } } else { appPath, configExists, err = addFromLocal(dirPath, config) if err != nil { return api.ErrorBadRequest(c, err) } } if input.Check && !configExists { success = false } if success { parser, err := storage.NewLocalParser(config.AuthConfig.Username, appPath) if err != nil { return api.ErrorInternal(c, err) } app = &get3w.App{ Owner: owner, Name: parser.Name, Description: parser.Config.Description, Tags: "", Path: appPath, Private: false, CreatedAt: timeutils.ToString(time.Now()), UpdatedAt: timeutils.ToString(time.Now()), } exists := false for _, app := range config.Apps { if app.Path == appPath { exists = true break } } if !exists { config.Apps = append(config.Apps, app) config.Save() } } output := &get3w.AppAddOutput{ Config: configExists, App: app, } return c.JSON(http.StatusOK, output) } }
// Upload files func Upload() echo.HandlerFunc { return func(c echo.Context) error { appPath := c.Param("app_path") if appPath == "" { return api.ErrorNotFound(c, nil) } if api.IsAnonymous(c) { return api.ErrorUnauthorized(c, nil) } location := c.Query("location") app, err := api.GetApp(appPath) if err != nil { return api.ErrorInternal(c, err) } if app == nil { return api.ErrorNotFound(c, nil) } parser, err := storage.NewLocalParser(api.Owner(c), appPath) if err != nil { return api.ErrorInternal(c, err) } req := c.Request().(*standard.Request) mr, err := req.MultipartReader() if err != nil { return api.ErrorInternal(c, err) } files := []*get3w.File{} for { part, err := mr.NextPart() if err != nil { if err == io.EOF { break } return api.ErrorInternal(c, err) } defer part.Close() data, err := ioutil.ReadAll(part) if err != nil { return api.ErrorInternal(c, err) } filename := part.FileName() err = parser.Storage.Write(parser.Storage.GetSourceKey(location, filename), data) if err != nil { return api.ErrorInternal(c, err) } file := &get3w.File{ IsDir: false, Path: strings.Trim(path.Join(location, filename), "/"), Name: filename, Size: 0, Checksum: "", LastModified: timeutils.ToString(time.Now()), } files = append(files, file) } return c.JSON(http.StatusOK, files) } }
// Run the server func Run() { e := echo.New() e.Use(middleware.Logger()) e.Use(middleware.Recover()) e.Use(api.StoreHeaders()) e.SetHTTPErrorHandler(func(err error, c echo.Context) { if he, ok := err.(*echo.HTTPError); ok { api.Error(c, he.Code, he) } else { api.ErrorInternal(c, err) } }) e.Get("/static/proxy.html", api.StaticProxy()) e.Get("/static/xdomain.min.js", api.StaticXDomain()) // Apps Files start e.Post("/api/apps/:app_path/files/actions/checksum", files.Checksum()) e.Delete("/api/apps/:app_path/files/*", files.Delete()) e.Put("/api/apps/:app_path/files/*", files.Edit()) e.Get("/api/apps/:app_path/*", files.Get()) e.Get("/api/apps/:app_path/files", files.List()) e.Get("/api/apps/:app_path/files/*", files.List()) e.Post("/api/apps/:app_path/files/actions/push", files.Push()) e.Post("/api/apps/:app_path/files/actions/upload", files.Upload()) // Apps Folders start e.Post("/api/apps/:app_path/folders", folders.Create()) e.Delete("/api/apps/:app_path/folders", folders.Delete()) // Apps start e.Post("/api/apps", apps.Add()) e.Delete("/api/apps/:app_path", apps.Delete()) // e.Patch("/api/apps/:app_path", apps.Edit) e.Get("/api/apps/:app_path", apps.Get()) e.Get("/api/apps", apps.List()) e.Post("/api/apps/:app_path/actions/load", apps.Load()) e.Post("/api/apps/:app_path/actions/publish", apps.Publish()) e.Post("/api/apps/:app_path/actions/save", apps.Save()) // e.Post("/api/apps/:app_path/actions/star", apps.Star) e.Post("/api/apps/:app_path/actions/sync", apps.Sync()) // Status start e.Get("/api/status", status.Get()) // Users start e.Post("/api/users/actions/login", users.Login()) e.Post("/api/users/actions/logout", users.Logout()) // Root start e.Get("/s/:app_name/*", root.Get()) e.Get("/s/:app_name/", root.Get()) e.Get("/s/:app_name", root.Get()) // Static start e.Static("/signup", "resources/app/signup") e.Static("/", "resources/app") e.Run(standard.New(port)) }