| @@ -16,6 +16,9 @@ package controllers | |||
| import ( | |||
| "encoding/json" | |||
| "fmt" | |||
| "net" | |||
| "strings" | |||
| "github.com/casbin/casibase/object" | |||
| ) | |||
| @@ -42,6 +45,34 @@ func (c *ApiController) GetStores() { | |||
| c.ResponseOk(stores) | |||
| } | |||
| func isIpAddress(host string) bool { | |||
| // Attempt to split the host and port, ignoring the error | |||
| hostWithoutPort, _, err := net.SplitHostPort(host) | |||
| if err != nil { | |||
| // If an error occurs, it might be because there's no port | |||
| // In that case, use the original host string | |||
| hostWithoutPort = host | |||
| } | |||
| // Attempt to parse the host as an IP address (both IPv4 and IPv6) | |||
| ip := net.ParseIP(hostWithoutPort) | |||
| // if host is not nil is an IP address else is not an IP address | |||
| return ip != nil | |||
| } | |||
| func getOriginFromHost(host string) string { | |||
| protocol := "https://" | |||
| if !strings.Contains(host, ".") { | |||
| // "localhost:14000" | |||
| protocol = "http://" | |||
| } else if isIpAddress(host) { | |||
| // "192.168.0.10" | |||
| protocol = "http://" | |||
| } | |||
| return fmt.Sprintf("%s%s", protocol, host) | |||
| } | |||
| func (c *ApiController) GetStore() { | |||
| id := c.Input().Get("id") | |||
| @@ -61,7 +92,9 @@ func (c *ApiController) GetStore() { | |||
| return | |||
| } | |||
| err = store.Populate() | |||
| host := c.Ctx.Request.Host | |||
| origin := getOriginFromHost(host) | |||
| err = store.Populate(origin) | |||
| if err != nil { | |||
| // gentle error | |||
| c.ResponseOk(store, err.Error()) | |||
| @@ -16,6 +16,7 @@ package object | |||
| import ( | |||
| "fmt" | |||
| urllib "net/url" | |||
| "strings" | |||
| "github.com/casbin/casibase/storage" | |||
| @@ -79,7 +80,7 @@ func isObjectLeaf(object *storage.Object) bool { | |||
| return isLeaf | |||
| } | |||
| func (store *Store) Populate() error { | |||
| func (store *Store) Populate(origin string) error { | |||
| storageProviderObj, err := store.GetStorageProviderObj() | |||
| if err != nil { | |||
| return err | |||
| @@ -118,7 +119,7 @@ func (store *Store) Populate() error { | |||
| lastModifiedTime := object.LastModified | |||
| isLeaf := isObjectLeaf(object) | |||
| size := object.Size | |||
| url := object.Url | |||
| url, _ := urllib.JoinPath(origin, object.Url) | |||
| tokens := strings.Split(strings.Trim(object.Key, "/"), "/") | |||
| store.createPathIfNotExisted(tokens, size, url, lastModifiedTime, isLeaf) | |||
| @@ -19,14 +19,19 @@ import ( | |||
| "net/http" | |||
| "strings" | |||
| "github.com/casbin/casibase/conf" | |||
| "github.com/casbin/casibase/controllers" | |||
| "github.com/astaxie/beego" | |||
| "github.com/astaxie/beego/context" | |||
| "github.com/casbin/casibase/conf" | |||
| "github.com/casbin/casibase/controllers" | |||
| "github.com/casbin/casibase/util" | |||
| ) | |||
| const ( | |||
| headerAllowOrigin = "Access-Control-Allow-Origin" | |||
| headerAllowMethods = "Access-Control-Allow-Methods" | |||
| headerAllowHeaders = "Access-Control-Allow-Headers" | |||
| ) | |||
| func TransparentStatic(ctx *context.Context) { | |||
| urlPath := ctx.Request.URL.Path | |||
| if strings.HasPrefix(urlPath, "/api/") { | |||
| @@ -47,6 +52,17 @@ func TransparentStatic(ctx *context.Context) { | |||
| } | |||
| } | |||
| if strings.HasPrefix(urlPath, "/storage") { | |||
| ctx.Output.Header(headerAllowOrigin, "*") | |||
| ctx.Output.Header(headerAllowMethods, "POST, GET, OPTIONS, DELETE") | |||
| ctx.Output.Header(headerAllowHeaders, "Content-Type, Authorization") | |||
| urlPath = strings.TrimPrefix(urlPath, "/storage/") | |||
| urlPath = strings.Replace(urlPath, "|", ":", 1) | |||
| http.ServeFile(ctx.ResponseWriter, ctx.Request, urlPath) | |||
| return | |||
| } | |||
| path := "web/build" | |||
| if urlPath == "/" { | |||
| path += "/index.html" | |||
| @@ -52,11 +52,15 @@ func (p *LocalFileSystemStorageProvider) ListObjects(prefix string) ([]*Object, | |||
| path = strings.ReplaceAll(path, "\\", "/") | |||
| relativePath := strings.TrimPrefix(path, fullPath) | |||
| relativePath = strings.TrimPrefix(relativePath, "/") | |||
| url := strings.Replace(path, ":", "|", 1) | |||
| url = fmt.Sprintf("storage/%s", url) | |||
| objects = append(objects, &Object{ | |||
| Key: relativePath, | |||
| LastModified: modTime.Format(time.RFC3339), | |||
| Size: info.Size(), | |||
| Url: "", | |||
| Url: url, | |||
| }) | |||
| } | |||
| return nil | |||