blob: df4f863bcd1aed8f9697d4b7805d91291457d7e0 [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
Davit Tabidze207ce082024-04-09 19:15:25 +040035type LauncherServer struct {
36 port int
37 logoutUrl string
38 appDirectory AppDirectory
39 homeTmpl *template.Template
40}
41
42func NewLauncherServer(
43 port int,
44 logoutUrl string,
45 appDirectory AppDirectory,
46) (*LauncherServer, error) {
47 tmpl, err := indexHTML.ReadFile("launcher-tmpl/launcher.html")
48 if err != nil {
49 return nil, fmt.Errorf("failed to parse template: %v", err)
50 }
51 t := template.New("index").Funcs(template.FuncMap{
52 "GetUserInitials": getUserInitials,
53 "CleanAppName": cleanAppName,
54 })
55 t, err = t.Parse(string(tmpl))
56 if err != nil {
57 return nil, fmt.Errorf("failed to parse template: %v", err)
58 }
59 return &LauncherServer{
60 port,
61 logoutUrl,
62 appDirectory,
63 t,
64 }, nil
65}
66
67func getUserInitials(username string) string {
68 if username == "" {
69 return ""
70 }
71 return strings.ToUpper(username[:1])
72}
73
74func cleanAppName(name string) string {
75 cleanName := strings.ToLower(name)
76 cleanName = strings.ReplaceAll(cleanName, " ", "-")
77 return cleanName
78}
79
Davit Tabidze56f86a42024-04-09 19:15:25 +040080func (d *AppManagerDirectory) GetAllApps() ([]AppLauncherInfo, error) {
81 allAppInstances, err := d.AppManager.FindAllInstances()
82 if err != nil {
83 return nil, err
84 }
85 var ret []AppLauncherInfo
86 for _, appInstance := range allAppInstances {
87 appLauncherInfo := AppLauncherInfo{
88 Name: appInstance.AppId,
89 Icon: template.HTML(appInstance.Icon),
90 Help: appInstance.Help,
91 Url: appInstance.Url,
92 }
93 ret = append(ret, appLauncherInfo)
94 }
95 return ret, nil
96}
97
98func getLoggedInUser(r *http.Request) (string, error) {
99 if user := r.Header.Get("X-User"); user != "" {
100 return user, nil
101 } else {
102 return "", fmt.Errorf("unauthenticated")
103 }
104 // return "Username", nil
105}
106
Davit Tabidze207ce082024-04-09 19:15:25 +0400107func (s *LauncherServer) Start() {
108 http.Handle("/static/", http.FileServer(http.FS(files)))
109 http.HandleFunc("/", s.homeHandler)
110 log.Fatal(http.ListenAndServe(fmt.Sprintf(":%d", s.port), nil))
111}
112
113type homeHandlerData struct {
114 LoggedInUsername string
115 AllAppsInfo []AppLauncherInfo
116}
117
118func (s *LauncherServer) homeHandler(w http.ResponseWriter, r *http.Request) {
Davit Tabidze56f86a42024-04-09 19:15:25 +0400119 loggedInUsername, err := getLoggedInUser(r)
120 if err != nil {
121 http.Error(w, "User Not Logged In", http.StatusUnauthorized)
122 return
123 }
Davit Tabidze207ce082024-04-09 19:15:25 +0400124 allAppsInfo, err := s.appDirectory.GetAllApps()
125 if err != nil {
Davit Tabidze56f86a42024-04-09 19:15:25 +0400126 http.Error(w, err.Error(), http.StatusInternalServerError)
Davit Tabidze207ce082024-04-09 19:15:25 +0400127 }
128 data := homeHandlerData{
129 LoggedInUsername: loggedInUsername,
130 AllAppsInfo: allAppsInfo,
131 }
132 if err := s.homeTmpl.Execute(w, data); err != nil {
133 http.Error(w, err.Error(), http.StatusInternalServerError)
134 return
135 }
136}