mirror of
https://github.com/ditkrg/traefik-users-blocker-plugin.git
synced 2026-01-23 03:56:58 +00:00
Compare commits
8 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 8d3b1b71e5 | |||
| e9cbcb04c4 | |||
| 7a03599d16 | |||
| cabcbbb166 | |||
| 4f258ba7f3 | |||
| 57968638d2 | |||
| fb7dce9887 | |||
| 149616a5ad |
@ -11,6 +11,5 @@ testData:
|
|||||||
- userId1
|
- userId1
|
||||||
- userId2
|
- userId2
|
||||||
paths:
|
paths:
|
||||||
- prefix: /v1/users
|
- base: /v1/users
|
||||||
value: testValue
|
path: /testValue
|
||||||
- prefix: /v1/organizations
|
|
||||||
|
|||||||
16
docker-compose.yaml
Normal file
16
docker-compose.yaml
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
version: '3'
|
||||||
|
|
||||||
|
services:
|
||||||
|
reverse-proxy:
|
||||||
|
image: traefik:v3.0
|
||||||
|
command:
|
||||||
|
- --api.insecure=true
|
||||||
|
- --providers.docker
|
||||||
|
- "--experimental.localPlugins.usersblocker.moduleName=github.com/ditkrg/traefik-users-blocker-plugin"
|
||||||
|
ports:
|
||||||
|
- "80:80"
|
||||||
|
- "8080:8080"
|
||||||
|
volumes:
|
||||||
|
# So that Traefik can listen to the Docker events
|
||||||
|
- /var/run/docker.sock:/var/run/docker.sock
|
||||||
|
- ./:/plugins-local/src/github.com/ditkrg/traefik-users-blocker-plugin
|
||||||
39
main.go
39
main.go
@ -4,12 +4,17 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"os"
|
||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type Rule struct {
|
||||||
|
AllowedSubPaths []string `json:"allowedSubPaths,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
type Path struct {
|
type Path struct {
|
||||||
Prefix string `json:"prefix,omitempty"`
|
Path string `json:"base,omitempty"`
|
||||||
MustContain string `json:"mustContain,omitempty"`
|
Rule Rule `json:"rule,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type Config struct {
|
type Config struct {
|
||||||
@ -37,8 +42,8 @@ func New(ctx context.Context, next http.Handler, config *Config, name string) (h
|
|||||||
}
|
}
|
||||||
|
|
||||||
for _, path := range config.Paths {
|
for _, path := range config.Paths {
|
||||||
if path.Prefix == "" {
|
if path.Path == "" {
|
||||||
return nil, fmt.Errorf("Paths.Prefix cannot be empty")
|
return nil, fmt.Errorf("Paths.Path cannot be empty")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -53,6 +58,9 @@ func New(ctx context.Context, next http.Handler, config *Config, name string) (h
|
|||||||
func (a *UsersBlocker) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
|
func (a *UsersBlocker) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
|
||||||
userId := req.Header["X-Auth-User-Id"][0]
|
userId := req.Header["X-Auth-User-Id"][0]
|
||||||
|
|
||||||
|
message := fmt.Sprintf("{requestPath: %s, userId: %s}\n", req.URL.Path, userId)
|
||||||
|
os.Stdout.WriteString(message)
|
||||||
|
|
||||||
var isUserBlocked bool
|
var isUserBlocked bool
|
||||||
|
|
||||||
for _, id := range a.userId {
|
for _, id := range a.userId {
|
||||||
@ -67,16 +75,29 @@ func (a *UsersBlocker) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for _, path := range a.paths {
|
for _, path := range a.paths {
|
||||||
isPathBlocked := strings.HasPrefix(req.URL.Path, path.Prefix)
|
isPathMatched := strings.HasPrefix(req.URL.Path, path.Path)
|
||||||
|
|
||||||
if isPathBlocked && path.MustContain != "" {
|
if !isPathMatched {
|
||||||
isPathBlocked = !strings.Contains(req.URL.Path, path.MustContain)
|
a.next.ServeHTTP(rw, req)
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if isPathBlocked {
|
if len(path.Rule.AllowedSubPaths) == 0 {
|
||||||
http.Error(rw, "Forbidden", http.StatusForbidden)
|
message := fmt.Sprintf("blocked path %s (matched with %s) for user %s", req.URL.Path, path.Path, userId)
|
||||||
|
os.Stdout.WriteString(message)
|
||||||
|
http.Error(rw, message, http.StatusForbidden)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for _, allowedSubPath := range path.Rule.AllowedSubPaths {
|
||||||
|
isAllowedSubPathMatched := strings.HasPrefix(req.URL.Path, path.Path+allowedSubPath)
|
||||||
|
if !isAllowedSubPathMatched {
|
||||||
|
message := fmt.Sprintf("blocked path %s (matched with %s) for user %s", req.URL.Path, path.Path+path.Path+allowedSubPath, userId)
|
||||||
|
os.Stdout.WriteString(message)
|
||||||
|
http.Error(rw, message, http.StatusForbidden)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
a.next.ServeHTTP(rw, req)
|
a.next.ServeHTTP(rw, req)
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user