Skip to content
Snippets Groups Projects
Commit 78eee03a authored by q3k's avatar q3k
Browse files

Merge branch 'rahix/flow3r-seed' into 'main'

api: Add a flow3r seed which can be used for app installation

See merge request flow3r/api!1
parents 2692df79 690220f9
No related branches found
No related tags found
No related merge requests found
......@@ -33,6 +33,7 @@ func main() {
http.HandleFunc("/api/release/", s.handleReleaseMirror)
http.HandleFunc("/api/apps/zip/", s.handleAppZip)
http.HandleFunc("/api/apps/tar/", s.handleAppTargz)
http.HandleFunc("/api/apps/", s.handleApp)
log.Printf("Listening on %s...", flagListen)
http.ListenAndServe(flagListen, nil)
}
......@@ -6,6 +6,7 @@ import (
"bytes"
"compress/gzip"
"context"
"crypto/md5"
"encoding/json"
"fmt"
"io"
......@@ -39,6 +40,7 @@ type appInfo struct {
version int
commit string
stars int
flow3rSeed string
commitObj *object.Commit
zip []byte
......@@ -358,6 +360,16 @@ func (s *server) getAppInfo(ctx context.Context, pathInRepo, repo string) (*appI
return nil, fmt.Errorf("targzing failed: %w", err)
}
app.targz = tbytes
// Calculate an 8 digit flow3r seed which can be used to install the
// app. This is based on md5 so ambitious hack3rs can force a certain
// app seed :)
flow3rSeedMd5 := md5.Sum([]byte(repo))
app.flow3rSeed = "";
for i := 0; i < 8; i++ {
app.flow3rSeed += string(flow3rSeedMd5[i] % 5 + byte('0'))
}
return app, nil
}
......@@ -455,14 +467,7 @@ func (s *server) getAppRegistry(ctx context.Context) ([]*appDescriptor, error) {
return res, nil
}
func (s *server) handleApps(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
apps, err := s.getApps(ctx)
if err != nil {
return
}
type app struct {
type jsonApp struct {
RepoURL string `json:"repoUrl"`
Commit string `json:"commit"`
DownloadURL string `json:"downloadUrl"`
......@@ -473,11 +478,35 @@ func (s *server) handleApps(w http.ResponseWriter, r *http.Request) {
Description string `json:"description"`
Version int `json:"version"`
Stars int `json:"stars"`
Flow3rSeed string `json:"flow3rSeed"`
}
func makeJsonApp(a *appDescriptor) (jsonApp) {
return jsonApp {
RepoURL: "https://git.flow3r.garden/" + a.repository,
Commit: a.appInfo.commit,
DownloadURL: fmt.Sprintf("%sapps/zip/%s.zip", flagBaseURL, a.repository),
TarDownloadURL: fmt.Sprintf("%sapps/tar/%s.tar.gz", flagBaseURL, a.repository),
Name: a.appInfo.name,
Menu: a.appInfo.menu,
Author: a.appInfo.author,
Description: a.appInfo.description,
Version: a.appInfo.version,
Stars: a.appInfo.stars,
Flow3rSeed: a.appInfo.flow3rSeed,
}
}
func (s *server) handleApps(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
apps, err := s.getApps(ctx)
if err != nil {
return
}
type res struct {
DT time.Time `json:"isodatetime"`
Apps []app `json:"apps"`
Apps []jsonApp `json:"apps"`
}
resp := res{
......@@ -488,18 +517,7 @@ func (s *server) handleApps(w http.ResponseWriter, r *http.Request) {
continue
}
// Guarenteed to be exactly 2 parts because of the regex
resp.Apps = append(resp.Apps, app{
RepoURL: "https://git.flow3r.garden/" + a.repository,
Commit: a.appInfo.commit,
DownloadURL: fmt.Sprintf("%sapps/zip/%s.zip", flagBaseURL, a.repository),
TarDownloadURL: fmt.Sprintf("%sapps/tar/%s.tar.gz", flagBaseURL, a.repository),
Name: a.appInfo.name,
Menu: a.appInfo.menu,
Author: a.appInfo.author,
Description: a.appInfo.description,
Version: a.appInfo.version,
Stars: a.appInfo.stars,
})
resp.Apps = append(resp.Apps, makeJsonApp(a))
}
w.Header().Add("Access-Control-Allow-Origin", "*")
w.Header().Add("Content-Type", "application/json")
......@@ -507,6 +525,41 @@ func (s *server) handleApps(w http.ResponseWriter, r *http.Request) {
j.Encode(resp)
}
var (
reAppURL = regexp.MustCompile("^/api/apps/([0-4]{8}).json$")
)
func (s *server) handleApp(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
matches := reAppURL.FindStringSubmatch(r.URL.Path)
if matches == nil {
http.NotFound(w, r)
return
}
flow3rSeed := matches[1]
apps, err := s.getApps(ctx)
if err != nil {
return
}
for _, a := range apps {
if a.appInfo == nil {
continue
}
if a.appInfo.flow3rSeed == flow3rSeed {
w.Header().Add("Access-Control-Allow-Origin", "*")
w.Header().Add("Content-Type", "application/json")
j := json.NewEncoder(w)
j.Encode(makeJsonApp(a))
return
}
}
http.NotFound(w, r)
}
var (
reAppZipURL = regexp.MustCompile(`^/api/apps/zip/([^/]+)/([^/]+)\.zip$`)
reAppTargzURL = regexp.MustCompile(`^/api/apps/tar/([^/]+)/([^/]+)\.tar\.gz$`)
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment