Get rid of $localhost pseudo user

This commit is contained in:
Ingo Oppermann
2023-03-09 21:10:04 +01:00
parent a0ef3ab5ee
commit 6e93c1d5a1
7 changed files with 68 additions and 78 deletions

View File

@@ -444,27 +444,11 @@ func (a *api) start() error {
// Create default policies for anonymous users in order to mimic the behaviour before IAM
iam.RemovePolicy("$anon", "$none", "", nil)
iam.RemovePolicy("$localhost", "$none", "", nil)
iam.AddPolicy("$anon", "$none", "fs:/**", []string{"GET", "HEAD", "OPTIONS"})
iam.AddPolicy("$anon", "$none", "api:/api", []string{"GET", "HEAD", "OPTIONS"})
iam.AddPolicy("$anon", "$none", "api:/api/v3/widget/process/**", []string{"GET", "HEAD", "OPTIONS"})
if !cfg.API.Auth.Enable {
iam.AddPolicy("$anon", "$none", "api:/api/**", []string{"ANY"})
iam.AddPolicy("$anon", "$none", "process:*", []string{"ANY"})
iam.AddPolicy("$anon", "$none", "iam:*", []string{"ANY"})
} else {
if cfg.API.Auth.DisableLocalhost {
iam.AddPolicy("$localhost", "$none", "api:/api", []string{"GET", "HEAD", "OPTIONS"})
iam.AddPolicy("$localhost", "$none", "api:/api/v3/widget/process/**", []string{"GET", "HEAD", "OPTIONS"})
iam.AddPolicy("$localhost", "$none", "api:/api/**", []string{"ANY"})
iam.AddPolicy("$localhost", "$none", "process:*", []string{"ANY"})
iam.AddPolicy("$localhost", "$none", "iam:*", []string{"ANY"})
}
}
if !cfg.Storage.Memory.Auth.Enable {
iam.AddPolicy("$anon", "$none", "fs:/memfs/**", []string{"ANY"})
}
@@ -671,7 +655,7 @@ func (a *api) start() error {
var identity iam.IdentityVerifier = nil
if len(config.Owner) == 0 {
identity, _ = a.iam.GetDefaultVerifier()
identity = a.iam.GetDefaultVerifier()
} else {
identity, _ = a.iam.GetVerifier(config.Owner)
}
@@ -697,7 +681,7 @@ func (a *api) start() error {
var identity iam.IdentityVerifier = nil
if len(config.Owner) == 0 {
identity, _ = a.iam.GetDefaultVerifier()
identity = a.iam.GetDefaultVerifier()
} else {
identity, _ = a.iam.GetVerifier(config.Owner)
}
@@ -1124,7 +1108,22 @@ func (a *api) start() error {
Router: router,
ReadOnly: cfg.API.ReadOnly,
IAM: a.iam,
IAMDisableLocalhost: cfg.API.Auth.Enable && cfg.API.Auth.DisableLocalhost,
IAMSkipper: func(ip string) bool {
if !cfg.API.Auth.Enable {
return true
} else {
isLocalhost := false
if ip == "127.0.0.1" || ip == "::1" {
isLocalhost = true
}
if isLocalhost && cfg.API.Auth.DisableLocalhost {
return true
}
}
return false
},
}
mainserverhandler, err := http.NewServer(serverConfig)

View File

@@ -17,9 +17,8 @@
// only allow JWT as authentication method.
//
// If the identity can't be detected, the identity of "$anon" is given, representing
// an anonmyous user. If the request originates from localhost and DisableLocalhost
// is configured, the identity will be $localhost, representing an anonymous user from
// localhost.
// an anonmyous user. If the Skipper function returns true for the request and the
// API is accessed, the username will be the one of the IAM superuser.
//
// The domain is provided as query parameter "group" for all API requests or the
// first path element after a mountpoint for filesystem requests.
@@ -57,7 +56,6 @@ type Config struct {
Skipper middleware.Skipper
Mounts []string
IAM iam.IAM
DisableLocalhost bool
WaitAfterFailedLogin bool
Logger log.Logger
}
@@ -66,7 +64,6 @@ var DefaultConfig = Config{
Skipper: middleware.DefaultSkipper,
Mounts: []string{},
IAM: nil,
DisableLocalhost: false,
WaitAfterFailedLogin: false,
Logger: nil,
}
@@ -111,15 +108,15 @@ func NewWithConfig(config Config) echo.MiddlewareFunc {
return func(next echo.HandlerFunc) echo.HandlerFunc {
return func(c echo.Context) error {
if config.Skipper(c) {
c.Set("user", "$anon")
return next(c)
}
if config.IAM == nil {
return api.Err(http.StatusForbidden, "Forbidden", "IAM is not provided")
}
isAPISuperuser := false
if config.Skipper(c) {
isAPISuperuser = true
}
var identity iam.IdentityVerifier = nil
var err error
@@ -173,11 +170,8 @@ func NewWithConfig(config Config) echo.MiddlewareFunc {
}
}
if config.DisableLocalhost {
ip := c.RealIP()
if ip == "127.0.0.1" || ip == "::1" {
username = "$localhost"
}
if isAPISuperuser {
username = config.IAM.GetDefaultVerifier().Name()
}
domain = c.QueryParam("group")

View File

@@ -93,7 +93,7 @@ type Config struct {
Router router.Router
ReadOnly bool
IAM iam.IAM
IAMDisableLocalhost bool
IAMSkipper func(ip string) bool
}
type CorsConfig struct {
@@ -132,8 +132,6 @@ type server struct {
middleware struct {
iplimit echo.MiddlewareFunc
log echo.MiddlewareFunc
accessJWT echo.MiddlewareFunc
refreshJWT echo.MiddlewareFunc
cors echo.MiddlewareFunc
cache echo.MiddlewareFunc
session echo.MiddlewareFunc
@@ -223,9 +221,11 @@ func NewServer(config Config) (Server, error) {
}
s.middleware.iam = mwiam.NewWithConfig(mwiam.Config{
Skipper: func(c echo.Context) bool {
return config.IAMSkipper(c.RealIP())
},
IAM: config.IAM,
Mounts: mounts,
DisableLocalhost: config.IAMDisableLocalhost,
WaitAfterFailedLogin: true,
Logger: s.logger.WithComponent("IAM"),
})

View File

@@ -28,7 +28,7 @@ type IAM interface {
GetVerifier(name string) (IdentityVerifier, error)
GetVerfierFromAuth0(name string) (IdentityVerifier, error)
GetDefaultVerifier() (IdentityVerifier, error)
GetDefaultVerifier() IdentityVerifier
CreateJWT(name string) (string, string, error)
@@ -107,10 +107,6 @@ func (i *iam) Enforce(name, domain, resource, action string) bool {
}
}
//if name == "$localhost" {
// superuser = true
//}
l := i.logger.Debug().WithFields(log.Fields{
"subject": name,
"domain": domain,
@@ -128,6 +124,10 @@ func (i *iam) Enforce(name, domain, resource, action string) bool {
if !ok {
l.Log("no match")
} else {
if name == "$superuser" {
rule = ""
}
l.WithField("rule", rule).Log("match")
}
@@ -166,8 +166,10 @@ func (i *iam) GetVerfierFromAuth0(name string) (IdentityVerifier, error) {
return i.im.GetVerifierFromAuth0(name)
}
func (i *iam) GetDefaultVerifier() (IdentityVerifier, error) {
return i.im.GetDefaultVerifier()
func (i *iam) GetDefaultVerifier() IdentityVerifier {
v, _ := i.im.GetDefaultVerifier()
return v
}
func (i *iam) CreateJWT(name string) (string, string, error) {

View File

@@ -424,12 +424,7 @@ func (r *restream) enforce(name, group, processid, action string) bool {
if len(name) == 0 {
// This is for backwards compatibility. Existing processes don't have an owner.
// All processes that will be added later will have an owner ($anon, ...).
identity, err := r.iam.GetDefaultVerifier()
if err != nil {
name = "$anon"
} else {
name = identity.Name()
}
name = r.iam.GetDefaultVerifier().Name()
}
if len(group) == 0 {

View File

@@ -428,7 +428,7 @@ func (s *server) findIdentityFromStreamKey(key string) (string, error) {
elements := strings.Split(key, ":")
if len(elements) == 1 {
identity, err = s.iam.GetDefaultVerifier()
identity = s.iam.GetDefaultVerifier()
token = elements[0]
} else {
identity, err = s.iam.GetVerifier(elements[0])

View File

@@ -387,7 +387,7 @@ func (s *server) findIdentityFromToken(key string) (string, error) {
elements := strings.Split(key, ":")
if len(elements) == 1 {
identity, err = s.iam.GetDefaultVerifier()
identity = s.iam.GetDefaultVerifier()
token = elements[0]
} else {
identity, err = s.iam.GetVerifier(elements[0])