mirror of
https://github.com/datarhei/core.git
synced 2025-10-05 16:07:07 +08:00
Change anon user to localhost user only if DisableLocalhost is set
This commit is contained in:
@@ -441,8 +441,7 @@ func (a *api) start() error {
|
|||||||
return fmt.Errorf("iam: %w", err)
|
return fmt.Errorf("iam: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create default policies for anonymous users in order to mimic
|
// Create default policies for anonymous users in order to mimic the behaviour before IAM
|
||||||
// the behaviour before IAM
|
|
||||||
|
|
||||||
iam.RemovePolicy("$anon", "$none", "", nil)
|
iam.RemovePolicy("$anon", "$none", "", nil)
|
||||||
iam.RemovePolicy("$localhost", "$none", "", nil)
|
iam.RemovePolicy("$localhost", "$none", "", nil)
|
||||||
@@ -451,16 +450,14 @@ func (a *api) start() error {
|
|||||||
iam.AddPolicy("$anon", "$none", "api:/api", []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"})
|
iam.AddPolicy("$anon", "$none", "api:/api/v3/widget/process/**", []string{"GET", "HEAD", "OPTIONS"})
|
||||||
|
|
||||||
iam.AddPolicy("$localhost", "$none", "api:/api", []string{"GET", "HEAD", "OPTIONS"})
|
|
||||||
iam.AddPolicy("$localhost", "$none", "api:/api/v3/widget/process/**", []string{"GET", "HEAD", "OPTIONS"})
|
|
||||||
|
|
||||||
if !cfg.API.Auth.Enable {
|
if !cfg.API.Auth.Enable {
|
||||||
iam.AddPolicy("$anon", "$none", "api:/api/**", []string{"ANY"})
|
iam.AddPolicy("$anon", "$none", "api:/api/**", []string{"ANY"})
|
||||||
iam.AddPolicy("$anon", "$none", "process:*", []string{"ANY"})
|
iam.AddPolicy("$anon", "$none", "process:*", []string{"ANY"})
|
||||||
iam.AddPolicy("$localhost", "$none", "api:/api/**", []string{"ANY"})
|
|
||||||
iam.AddPolicy("$localhost", "$none", "process:*", []string{"ANY"})
|
|
||||||
} else {
|
} else {
|
||||||
if cfg.API.Auth.DisableLocalhost {
|
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", "api:/api/**", []string{"ANY"})
|
||||||
iam.AddPolicy("$localhost", "$none", "process:*", []string{"ANY"})
|
iam.AddPolicy("$localhost", "$none", "process:*", []string{"ANY"})
|
||||||
}
|
}
|
||||||
@@ -1125,7 +1122,7 @@ func (a *api) start() error {
|
|||||||
Router: router,
|
Router: router,
|
||||||
ReadOnly: cfg.API.ReadOnly,
|
ReadOnly: cfg.API.ReadOnly,
|
||||||
IAM: a.iam,
|
IAM: a.iam,
|
||||||
IAMDisableLocalhost: cfg.API.Auth.DisableLocalhost,
|
IAMDisableLocalhost: cfg.API.Auth.Enable && cfg.API.Auth.DisableLocalhost,
|
||||||
}
|
}
|
||||||
|
|
||||||
mainserverhandler, err := http.NewServer(serverConfig)
|
mainserverhandler, err := http.NewServer(serverConfig)
|
||||||
|
@@ -36,9 +36,8 @@ func NewAbout(restream restream.Restreamer, auths func() []string) *AboutHandler
|
|||||||
// @Router /api [get]
|
// @Router /api [get]
|
||||||
func (p *AboutHandler) About(c echo.Context) error {
|
func (p *AboutHandler) About(c echo.Context) error {
|
||||||
user, _ := c.Get("user").(string)
|
user, _ := c.Get("user").(string)
|
||||||
disablelocalhost, _ := c.Get("disablelocalhost").(bool)
|
|
||||||
|
|
||||||
if user == "$anon" || (user == "$localhost" && !disablelocalhost) {
|
if user == "$anon" {
|
||||||
return c.JSON(http.StatusOK, api.MinimalAbout{
|
return c.JSON(http.StatusOK, api.MinimalAbout{
|
||||||
App: app.Name,
|
App: app.Name,
|
||||||
Auths: p.auths(),
|
Auths: p.auths(),
|
||||||
|
@@ -17,8 +17,9 @@
|
|||||||
// only allow JWT as authentication method.
|
// only allow JWT as authentication method.
|
||||||
//
|
//
|
||||||
// If the identity can't be detected, the identity of "$anon" is given, representing
|
// If the identity can't be detected, the identity of "$anon" is given, representing
|
||||||
// an anonmyous user. If the request originates from localhost, the identity will
|
// an anonmyous user. If the request originates from localhost and DisableLocalhost
|
||||||
// be $localhost, representing an anonymous user from localhost.
|
// is configured, the identity will be $localhost, representing an anonymous user from
|
||||||
|
// localhost.
|
||||||
//
|
//
|
||||||
// The domain is provided as query parameter "group" for all API requests or the
|
// The domain is provided as query parameter "group" for all API requests or the
|
||||||
// first path element after a mountpoint for filesystem requests.
|
// first path element after a mountpoint for filesystem requests.
|
||||||
@@ -53,21 +54,25 @@ import (
|
|||||||
|
|
||||||
type Config struct {
|
type Config struct {
|
||||||
// Skipper defines a function to skip middleware.
|
// Skipper defines a function to skip middleware.
|
||||||
Skipper middleware.Skipper
|
Skipper middleware.Skipper
|
||||||
Mounts []string
|
Mounts []string
|
||||||
IAM iam.IAM
|
IAM iam.IAM
|
||||||
DisableLocalhost bool
|
DisableLocalhost bool
|
||||||
Logger log.Logger
|
WaitAfterFailedLogin bool
|
||||||
|
Logger log.Logger
|
||||||
}
|
}
|
||||||
|
|
||||||
var DefaultConfig = Config{
|
var DefaultConfig = Config{
|
||||||
Skipper: middleware.DefaultSkipper,
|
Skipper: middleware.DefaultSkipper,
|
||||||
Mounts: []string{},
|
Mounts: []string{},
|
||||||
IAM: nil,
|
IAM: nil,
|
||||||
DisableLocalhost: false,
|
DisableLocalhost: false,
|
||||||
Logger: nil,
|
WaitAfterFailedLogin: false,
|
||||||
|
Logger: nil,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var realm = "datarhei-core"
|
||||||
|
|
||||||
type iammiddleware struct {
|
type iammiddleware struct {
|
||||||
iam iam.IAM
|
iam iam.IAM
|
||||||
mounts []string
|
mounts []string
|
||||||
@@ -106,9 +111,6 @@ func NewWithConfig(config Config) echo.MiddlewareFunc {
|
|||||||
|
|
||||||
return func(next echo.HandlerFunc) echo.HandlerFunc {
|
return func(next echo.HandlerFunc) echo.HandlerFunc {
|
||||||
return func(c echo.Context) error {
|
return func(c echo.Context) error {
|
||||||
|
|
||||||
c.Set("disablelocalhost", config.DisableLocalhost)
|
|
||||||
|
|
||||||
if config.Skipper(c) {
|
if config.Skipper(c) {
|
||||||
c.Set("user", "$anon")
|
c.Set("user", "$anon")
|
||||||
return next(c)
|
return next(c)
|
||||||
@@ -129,14 +131,18 @@ func NewWithConfig(config Config) echo.MiddlewareFunc {
|
|||||||
if resource == "/api/login" {
|
if resource == "/api/login" {
|
||||||
identity, err = mw.findIdentityFromUserpass(c)
|
identity, err = mw.findIdentityFromUserpass(c)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
time.Sleep(5 * time.Second)
|
if config.WaitAfterFailedLogin {
|
||||||
|
time.Sleep(5 * time.Second)
|
||||||
|
}
|
||||||
return api.Err(http.StatusForbidden, "Forbidden", "%s", err)
|
return api.Err(http.StatusForbidden, "Forbidden", "%s", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if identity == nil {
|
if identity == nil {
|
||||||
identity, err = mw.findIdentityFromAuth0(c)
|
identity, err = mw.findIdentityFromAuth0(c)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
time.Sleep(5 * time.Second)
|
if config.WaitAfterFailedLogin {
|
||||||
|
time.Sleep(5 * time.Second)
|
||||||
|
}
|
||||||
return api.Err(http.StatusForbidden, "Forbidden", "%s", err)
|
return api.Err(http.StatusForbidden, "Forbidden", "%s", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -150,22 +156,28 @@ func NewWithConfig(config Config) echo.MiddlewareFunc {
|
|||||||
if resource == "/api/login/refresh" {
|
if resource == "/api/login/refresh" {
|
||||||
usefor, _ := c.Get("usefor").(string)
|
usefor, _ := c.Get("usefor").(string)
|
||||||
if usefor != "refresh" {
|
if usefor != "refresh" {
|
||||||
time.Sleep(5 * time.Second)
|
if config.WaitAfterFailedLogin {
|
||||||
|
time.Sleep(5 * time.Second)
|
||||||
|
}
|
||||||
return api.Err(http.StatusForbidden, "Forbidden", "invalid token")
|
return api.Err(http.StatusForbidden, "Forbidden", "invalid token")
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
usefor, _ := c.Get("usefor").(string)
|
usefor, _ := c.Get("usefor").(string)
|
||||||
if usefor != "access" {
|
if usefor != "access" {
|
||||||
time.Sleep(5 * time.Second)
|
if config.WaitAfterFailedLogin {
|
||||||
|
time.Sleep(5 * time.Second)
|
||||||
|
}
|
||||||
return api.Err(http.StatusForbidden, "Forbidden", "invalid token")
|
return api.Err(http.StatusForbidden, "Forbidden", "invalid token")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ip := c.RealIP()
|
if config.DisableLocalhost {
|
||||||
if ip == "127.0.0.1" || ip == "::1" {
|
ip := c.RealIP()
|
||||||
username = "$localhost"
|
if ip == "127.0.0.1" || ip == "::1" {
|
||||||
|
username = "$localhost"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
domain = c.QueryParam("group")
|
domain = c.QueryParam("group")
|
||||||
@@ -173,14 +185,23 @@ func NewWithConfig(config Config) echo.MiddlewareFunc {
|
|||||||
} else {
|
} else {
|
||||||
identity, err = mw.findIdentityFromBasicAuth(c)
|
identity, err = mw.findIdentityFromBasicAuth(c)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if err == ErrUnauthorized {
|
if err == ErrAuthRequired {
|
||||||
c.Response().Header().Set(echo.HeaderWWWAuthenticate, "Basic realm=datarhei-core")
|
c.Response().Header().Set(echo.HeaderWWWAuthenticate, "Basic realm="+realm)
|
||||||
return api.Err(http.StatusUnauthorized, "Unauthorized", "%s", err)
|
return api.Err(http.StatusUnauthorized, "Unauthorized", "%s", err)
|
||||||
} else if err == ErrBadRequest {
|
} else {
|
||||||
return api.Err(http.StatusBadRequest, "Bad request", "%s", err)
|
if config.WaitAfterFailedLogin {
|
||||||
}
|
time.Sleep(5 * time.Second)
|
||||||
|
}
|
||||||
|
|
||||||
return api.Err(http.StatusForbidden, "Forbidden", "%s", err)
|
if err == ErrBadRequest {
|
||||||
|
return api.Err(http.StatusBadRequest, "Bad request", "%s", err)
|
||||||
|
} else if err == ErrUnauthorized {
|
||||||
|
c.Response().Header().Set(echo.HeaderWWWAuthenticate, "Basic realm="+realm)
|
||||||
|
return api.Err(http.StatusUnauthorized, "Unauthorized", "%s", err)
|
||||||
|
} else {
|
||||||
|
return api.Err(http.StatusForbidden, "Forbidden", "%s", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
domain = mw.findDomainFromFilesystem(resource)
|
domain = mw.findDomainFromFilesystem(resource)
|
||||||
@@ -208,6 +229,7 @@ func NewWithConfig(config Config) echo.MiddlewareFunc {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var ErrAuthRequired = errors.New("unauthorized")
|
||||||
var ErrUnauthorized = errors.New("unauthorized")
|
var ErrUnauthorized = errors.New("unauthorized")
|
||||||
var ErrBadRequest = errors.New("bad request")
|
var ErrBadRequest = errors.New("bad request")
|
||||||
|
|
||||||
@@ -224,7 +246,7 @@ func (m *iammiddleware) findIdentityFromBasicAuth(c echo.Context) (iam.IdentityV
|
|||||||
}
|
}
|
||||||
|
|
||||||
if !m.iam.Enforce("$anon", domain, "fs:"+path, c.Request().Method) {
|
if !m.iam.Enforce("$anon", domain, "fs:"+path, c.Request().Method) {
|
||||||
return nil, ErrUnauthorized
|
return nil, ErrAuthRequired
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil, nil
|
return nil, nil
|
||||||
|
@@ -147,7 +147,7 @@ func TestFindDomainFromFilesystem(t *testing.T) {
|
|||||||
|
|
||||||
mw := &iammiddleware{
|
mw := &iammiddleware{
|
||||||
iam: iam,
|
iam: iam,
|
||||||
mounts: []string{"/memfs", "/"},
|
mounts: []string{"/", "/memfs"},
|
||||||
}
|
}
|
||||||
|
|
||||||
domain := mw.findDomainFromFilesystem("/")
|
domain := mw.findDomainFromFilesystem("/")
|
||||||
|
@@ -223,10 +223,11 @@ func NewServer(config Config) (Server, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
s.middleware.iam = mwiam.NewWithConfig(mwiam.Config{
|
s.middleware.iam = mwiam.NewWithConfig(mwiam.Config{
|
||||||
IAM: config.IAM,
|
IAM: config.IAM,
|
||||||
Mounts: mounts,
|
Mounts: mounts,
|
||||||
DisableLocalhost: config.IAMDisableLocalhost,
|
DisableLocalhost: config.IAMDisableLocalhost,
|
||||||
Logger: s.logger.WithComponent("IAM"),
|
WaitAfterFailedLogin: true,
|
||||||
|
Logger: s.logger.WithComponent("IAM"),
|
||||||
})
|
})
|
||||||
|
|
||||||
s.handler.about = api.NewAbout(
|
s.handler.about = api.NewAbout(
|
||||||
|
Reference in New Issue
Block a user