blob: 7816dfc56af5c41c168d50993959d7c6d3c070cb [file] [log] [blame]
Davit Tabidze207ce082024-04-09 19:15:25 +04001package welcome
2
3import (
4 "embed"
5 "fmt"
6 "html/template"
7 "log"
8 "net/http"
9 "strings"
Davit Tabidze56f86a42024-04-09 19:15:25 +040010
11 "github.com/giolekva/pcloud/core/installer"
Davit Tabidze207ce082024-04-09 19:15:25 +040012)
13
14//go:embed launcher-tmpl/launcher.html
15var indexHTML embed.FS
16
17//go:embed static/*
18var files embed.FS
19
20type AppLauncherInfo struct {
Davit Tabidze56f86a42024-04-09 19:15:25 +040021 Name string
22 Icon template.HTML
23 Help []installer.HelpDocument
24 Url string
Davit Tabidze207ce082024-04-09 19:15:25 +040025}
26
27type AppDirectory interface {
28 GetAllApps() ([]AppLauncherInfo, error)
29}
30
Davit Tabidze56f86a42024-04-09 19:15:25 +040031type AppManagerDirectory struct {
32 AppManager *installer.AppManager
33}
34
gio09a3e5b2024-04-26 14:11:06 +040035func (d *AppManagerDirectory) GetAllApps() ([]AppLauncherInfo, error) {
36 all, err := d.AppManager.FindAllInstances()
37 if err != nil {
38 return nil, err
39 }
40 ret := []AppLauncherInfo{}
41 for _, a := range all {
42 if a.URL == "" && len(a.Help) == 0 {
43 continue
44 }
45 ret = append(ret, AppLauncherInfo{
46 Name: a.AppId,
47 Icon: template.HTML(a.Icon),
48 Help: a.Help,
49 Url: a.URL,
50 })
51 }
52 return ret, nil
53}
54
Davit Tabidze207ce082024-04-09 19:15:25 +040055type LauncherServer struct {
56 port int
57 logoutUrl string
58 appDirectory AppDirectory
59 homeTmpl *template.Template
60}
61
62func NewLauncherServer(
63 port int,
64 logoutUrl string,
65 appDirectory AppDirectory,
66) (*LauncherServer, error) {
67 tmpl, err := indexHTML.ReadFile("launcher-tmpl/launcher.html")
68 if err != nil {
69 return nil, fmt.Errorf("failed to parse template: %v", err)
70 }
71 t := template.New("index").Funcs(template.FuncMap{
72 "GetUserInitials": getUserInitials,
73 "CleanAppName": cleanAppName,
74 })
75 t, err = t.Parse(string(tmpl))
76 if err != nil {
77 return nil, fmt.Errorf("failed to parse template: %v", err)
78 }
79 return &LauncherServer{
80 port,
81 logoutUrl,
82 appDirectory,
83 t,
84 }, nil
85}
86
87func getUserInitials(username string) string {
88 if username == "" {
89 return ""
90 }
91 return strings.ToUpper(username[:1])
92}
93
94func cleanAppName(name string) string {
95 cleanName := strings.ToLower(name)
96 cleanName = strings.ReplaceAll(cleanName, " ", "-")
97 return cleanName
98}
99
Davit Tabidze56f86a42024-04-09 19:15:25 +0400100func getLoggedInUser(r *http.Request) (string, error) {
101 if user := r.Header.Get("X-User"); user != "" {
102 return user, nil
103 } else {
104 return "", fmt.Errorf("unauthenticated")
105 }
106 // return "Username", nil
107}
108
Davit Tabidze207ce082024-04-09 19:15:25 +0400109func (s *LauncherServer) Start() {
110 http.Handle("/static/", http.FileServer(http.FS(files)))
111 http.HandleFunc("/", s.homeHandler)
112 log.Fatal(http.ListenAndServe(fmt.Sprintf(":%d", s.port), nil))
113}
114
115type homeHandlerData struct {
116 LoggedInUsername string
117 AllAppsInfo []AppLauncherInfo
118}
119
120func (s *LauncherServer) homeHandler(w http.ResponseWriter, r *http.Request) {
Davit Tabidze56f86a42024-04-09 19:15:25 +0400121 loggedInUsername, err := getLoggedInUser(r)
122 if err != nil {
123 http.Error(w, "User Not Logged In", http.StatusUnauthorized)
124 return
125 }
Davit Tabidze207ce082024-04-09 19:15:25 +0400126 allAppsInfo, err := s.appDirectory.GetAllApps()
127 if err != nil {
Davit Tabidze56f86a42024-04-09 19:15:25 +0400128 http.Error(w, err.Error(), http.StatusInternalServerError)
Davit Tabidze207ce082024-04-09 19:15:25 +0400129 }
130 data := homeHandlerData{
131 LoggedInUsername: loggedInUsername,
132 AllAppsInfo: allAppsInfo,
133 }
134 if err := s.homeTmpl.Execute(w, data); err != nil {
135 http.Error(w, err.Error(), http.StatusInternalServerError)
136 return
137 }
138}