add logo reset endpoint

when resetting the logo we are falling back to the embedded logo asset
This commit is contained in:
David Christofas
2023-02-13 13:22:52 +01:00
parent 7c17ddb0b0
commit 45d1ba25c0
6 changed files with 90 additions and 0 deletions

View File

@@ -28,6 +28,10 @@ func (f *FileSystem) Open(original string) (http.File, error) {
return f.fs.Open(original)
}
func (f *FileSystem) OpenEmbedded(name string) (http.File, error) {
return f.fs.Open(name)
}
// Create creates a new file in the assetPath
func (f *FileSystem) Create(name string) (*os.File, error) {
fullPath := f.jailPath(name)

View File

@@ -76,6 +76,46 @@ func (p Web) UploadLogo(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusOK)
}
// ResetLogo implements the endpoint to reset the instance logo.
// The config will be changed back to use the embedded logo asset.
func (p Web) ResetLogo(w http.ResponseWriter, r *http.Request) {
user := revactx.ContextMustGetUser(r.Context())
rsp, err := p.gatewayClient.CheckPermission(r.Context(), &permissionsapi.CheckPermissionRequest{
Permission: "change-logo",
SubjectRef: &permissionsapi.SubjectReference{
Spec: &permissionsapi.SubjectReference_UserId{
UserId: user.Id,
},
},
})
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
return
}
if rsp.Status.Code != rpc.Code_CODE_OK {
w.WriteHeader(http.StatusForbidden)
return
}
f, err := p.fs.OpenEmbedded(_themesConfigPath)
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
return
}
defer f.Close()
originalPath, err := p.getLogoPath(f)
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
return
}
if err := p.updateLogoThemeConfig(originalPath); err != nil {
w.WriteHeader(http.StatusInternalServerError)
return
}
}
func (p Web) storeAsset(name string, asset io.Reader) error {
dst, err := p.fs.Create(name)
if err != nil {
@@ -87,6 +127,35 @@ func (p Web) storeAsset(name string, asset io.Reader) error {
return err
}
func (p Web) getLogoPath(r io.Reader) (string, error) {
// This decoding of the themes.json file is not optimal. If we need to decode it for other
// usecases as well we should consider decoding to a struct.
var m map[string]interface{}
_ = json.NewDecoder(r).Decode(&m)
webCfg, ok := m["web"].(map[string]interface{})
if !ok {
return "", errInvalidThemeConfig
}
defaultCfg, ok := webCfg["default"].(map[string]interface{})
if !ok {
return "", errInvalidThemeConfig
}
logoCfg, ok := defaultCfg["logo"].(map[string]interface{})
if !ok {
return "", errInvalidThemeConfig
}
logoPath, ok := logoCfg["login"].(string)
if !ok {
return "", errInvalidThemeConfig
}
return logoPath, nil
}
func (p Web) updateLogoThemeConfig(logoPath string) error {
f, err := p.fs.Open(_themesConfigPath)
if err == nil {

View File

@@ -33,3 +33,8 @@ func (i instrument) Config(w http.ResponseWriter, r *http.Request) {
func (i instrument) UploadLogo(w http.ResponseWriter, r *http.Request) {
i.next.UploadLogo(w, r)
}
// ResetLogo implements the Service interface.
func (i instrument) ResetLogo(w http.ResponseWriter, r *http.Request) {
i.next.ResetLogo(w, r)
}

View File

@@ -33,3 +33,8 @@ func (l logging) Config(w http.ResponseWriter, r *http.Request) {
func (l logging) UploadLogo(w http.ResponseWriter, r *http.Request) {
l.next.UploadLogo(w, r)
}
// ResetLogo implements the Service interface.
func (l logging) ResetLogo(w http.ResponseWriter, r *http.Request) {
l.next.ResetLogo(w, r)
}

View File

@@ -31,6 +31,7 @@ type Service interface {
ServeHTTP(http.ResponseWriter, *http.Request)
Config(http.ResponseWriter, *http.Request)
UploadLogo(http.ResponseWriter, *http.Request)
ResetLogo(http.ResponseWriter, *http.Request)
}
// NewService returns a service implementation for Service.
@@ -56,6 +57,7 @@ func NewService(opts ...Option) Service {
account.JWTSecret(options.Config.TokenManager.JWTSecret),
))
r.Post("/", svc.UploadLogo)
r.Delete("/", svc.ResetLogo)
})
r.Mount("/", svc.Static(options.Config.HTTP.CacheTTL))
})

View File

@@ -29,3 +29,8 @@ func (t tracing) Config(w http.ResponseWriter, r *http.Request) {
func (t tracing) UploadLogo(w http.ResponseWriter, r *http.Request) {
t.next.UploadLogo(w, r)
}
// ResetLogo implements the Service interface.
func (t tracing) ResetLogo(w http.ResponseWriter, r *http.Request) {
t.next.ResetLogo(w, r)
}