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)
}
@@ -1117,14 +1101,29 @@ func (a *api) start() error {
Cors: http.CorsConfig{
Origins: cfg.Storage.CORS.Origins,
},
RTMP: a.rtmpserver,
SRT: a.srtserver,
Config: a.config.store,
Sessions: a.sessions,
Router: router,
ReadOnly: cfg.API.ReadOnly,
IAM: a.iam,
IAMDisableLocalhost: cfg.API.Auth.Enable && cfg.API.Auth.DisableLocalhost,
RTMP: a.rtmpserver,
SRT: a.srtserver,
Config: a.config.store,
Sessions: a.sessions,
Router: router,
ReadOnly: cfg.API.ReadOnly,
IAM: a.iam,
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

@@ -75,25 +75,25 @@ import (
var ListenAndServe = http.ListenAndServe
type Config struct {
Logger log.Logger
LogBuffer log.BufferWriter
Restream restream.Restreamer
Metrics monitor.HistoryReader
Prometheus prometheus.Reader
MimeTypesFile string
Filesystems []fs.FS
IPLimiter net.IPLimiter
Profiling bool
Cors CorsConfig
RTMP rtmp.Server
SRT srt.Server
Config cfgstore.Store
Cache cache.Cacher
Sessions session.RegistryReader
Router router.Router
ReadOnly bool
IAM iam.IAM
IAMDisableLocalhost bool
Logger log.Logger
LogBuffer log.BufferWriter
Restream restream.Restreamer
Metrics monitor.HistoryReader
Prometheus prometheus.Reader
MimeTypesFile string
Filesystems []fs.FS
IPLimiter net.IPLimiter
Profiling bool
Cors CorsConfig
RTMP rtmp.Server
SRT srt.Server
Config cfgstore.Store
Cache cache.Cacher
Sessions session.RegistryReader
Router router.Router
ReadOnly bool
IAM iam.IAM
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])