mirror of
https://github.com/SigNoz/signoz.git
synced 2026-08-10 15:00:47 +01:00
Compare commits
1 Commits
ns/harness
...
fix/root-u
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8b2a5ecb14 |
26
Makefile
26
Makefile
@@ -81,24 +81,16 @@ devenv-clickhouse-clean: ## Clean all ClickHouse data from filesystem
|
||||
##############################################################
|
||||
# go commands
|
||||
##############################################################
|
||||
SQLITE_PATH ?= signoz.db
|
||||
HTTP_HOST_PORT ?= 0.0.0.0:8080
|
||||
PRIVATE_HOST_PORT ?= 0.0.0.0:8085
|
||||
OPAMP_WS_ENDPOINT ?= 0.0.0.0:4320
|
||||
|
||||
.PHONY: go-run-enterprise
|
||||
go-run-enterprise: ## Runs the enterprise go backend server
|
||||
@SIGNOZ_INSTRUMENTATION_LOGS_LEVEL=debug \
|
||||
SIGNOZ_SQLSTORE_SQLITE_PATH=$(SQLITE_PATH) \
|
||||
SIGNOZ_SQLSTORE_SQLITE_PATH=signoz.db \
|
||||
SIGNOZ_WEB_ENABLED=false \
|
||||
SIGNOZ_TOKENIZER_JWT_SECRET=secret \
|
||||
SIGNOZ_ALERTMANAGER_PROVIDER=signoz \
|
||||
SIGNOZ_TELEMETRYSTORE_PROVIDER=clickhouse \
|
||||
SIGNOZ_TELEMETRYSTORE_CLICKHOUSE_DSN=tcp://127.0.0.1:9000 \
|
||||
SIGNOZ_TELEMETRYSTORE_CLICKHOUSE_CLUSTER=cluster \
|
||||
SIGNOZ_HTTP_HOST_PORT=$(HTTP_HOST_PORT) \
|
||||
SIGNOZ_PRIVATE_HOST_PORT=$(PRIVATE_HOST_PORT) \
|
||||
SIGNOZ_OPAMP_WS_ENDPOINT=$(OPAMP_WS_ENDPOINT) \
|
||||
go run -race \
|
||||
$(GO_BUILD_CONTEXT_ENTERPRISE)/*.go server
|
||||
|
||||
@@ -109,30 +101,16 @@ go-test: ## Runs go unit tests
|
||||
.PHONY: go-run-community
|
||||
go-run-community: ## Runs the community go backend server
|
||||
@SIGNOZ_INSTRUMENTATION_LOGS_LEVEL=debug \
|
||||
SIGNOZ_SQLSTORE_SQLITE_PATH=$(SQLITE_PATH) \
|
||||
SIGNOZ_SQLSTORE_SQLITE_PATH=signoz.db \
|
||||
SIGNOZ_WEB_ENABLED=false \
|
||||
SIGNOZ_TOKENIZER_JWT_SECRET=secret \
|
||||
SIGNOZ_ALERTMANAGER_PROVIDER=signoz \
|
||||
SIGNOZ_TELEMETRYSTORE_PROVIDER=clickhouse \
|
||||
SIGNOZ_TELEMETRYSTORE_CLICKHOUSE_DSN=tcp://127.0.0.1:9000 \
|
||||
SIGNOZ_TELEMETRYSTORE_CLICKHOUSE_CLUSTER=cluster \
|
||||
SIGNOZ_HTTP_HOST_PORT=$(HTTP_HOST_PORT) \
|
||||
SIGNOZ_PRIVATE_HOST_PORT=$(PRIVATE_HOST_PORT) \
|
||||
SIGNOZ_OPAMP_WS_ENDPOINT=$(OPAMP_WS_ENDPOINT) \
|
||||
go run -race \
|
||||
$(GO_BUILD_CONTEXT_COMMUNITY)/*.go server
|
||||
|
||||
.PHONY: go-stop
|
||||
go-stop: ## Stops the go backend server listening on HTTP_HOST_PORT
|
||||
@PORT=$(lastword $(subst :, ,$(HTTP_HOST_PORT))); \
|
||||
PIDS=$$(lsof -ti tcp:$$PORT); \
|
||||
if [ -n "$$PIDS" ]; then \
|
||||
kill $$PIDS; \
|
||||
echo "Stopped signoz server on port $$PORT (pid $$PIDS)"; \
|
||||
else \
|
||||
echo "No signoz server running on port $$PORT"; \
|
||||
fi
|
||||
|
||||
.PHONY: go-build-community $(GO_BUILD_ARCHS_COMMUNITY)
|
||||
go-build-community: ## Builds the go backend server for community
|
||||
go-build-community: $(GO_BUILD_ARCHS_COMMUNITY)
|
||||
|
||||
@@ -23421,6 +23421,12 @@ paths:
|
||||
responses:
|
||||
"204":
|
||||
description: No Content
|
||||
"400":
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/RenderErrorResponse'
|
||||
description: Bad Request
|
||||
"401":
|
||||
content:
|
||||
application/json:
|
||||
@@ -23767,6 +23773,12 @@ paths:
|
||||
responses:
|
||||
"200":
|
||||
description: OK
|
||||
"400":
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/RenderErrorResponse'
|
||||
description: Bad Request
|
||||
"401":
|
||||
content:
|
||||
application/json:
|
||||
@@ -23819,6 +23831,12 @@ paths:
|
||||
responses:
|
||||
"204":
|
||||
description: No Content
|
||||
"400":
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/RenderErrorResponse'
|
||||
description: Bad Request
|
||||
"401":
|
||||
content:
|
||||
application/json:
|
||||
@@ -23906,6 +23924,12 @@ paths:
|
||||
responses:
|
||||
"204":
|
||||
description: No Content
|
||||
"400":
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/RenderErrorResponse'
|
||||
description: Bad Request
|
||||
"401":
|
||||
content:
|
||||
application/json:
|
||||
|
||||
@@ -122,7 +122,7 @@ func (provider *provider) addUserRoutes(router *mux.Router) error {
|
||||
Response: nil,
|
||||
ResponseContentType: "",
|
||||
SuccessStatusCode: http.StatusNoContent,
|
||||
ErrorStatusCodes: []int{},
|
||||
ErrorStatusCodes: []int{http.StatusBadRequest},
|
||||
Deprecated: false,
|
||||
SecuritySchemes: []handler.OpenAPISecurityScheme{{Name: authtypes.IdentNProviderTokenizer.StringValue()}},
|
||||
})).Methods(http.MethodPut).GetError(); err != nil {
|
||||
@@ -173,7 +173,7 @@ func (provider *provider) addUserRoutes(router *mux.Router) error {
|
||||
Response: nil,
|
||||
ResponseContentType: "",
|
||||
SuccessStatusCode: http.StatusNoContent,
|
||||
ErrorStatusCodes: []int{http.StatusNotFound},
|
||||
ErrorStatusCodes: []int{http.StatusBadRequest, http.StatusNotFound},
|
||||
Deprecated: false,
|
||||
SecuritySchemes: newSecuritySchemes(types.RoleAdmin),
|
||||
})).Methods(http.MethodDelete).GetError(); err != nil {
|
||||
@@ -343,7 +343,7 @@ func (provider *provider) addUserRoutes(router *mux.Router) error {
|
||||
Response: nil,
|
||||
ResponseContentType: "",
|
||||
SuccessStatusCode: http.StatusOK,
|
||||
ErrorStatusCodes: []int{http.StatusNotFound},
|
||||
ErrorStatusCodes: []int{http.StatusBadRequest, http.StatusNotFound},
|
||||
Deprecated: true,
|
||||
SecuritySchemes: newSecuritySchemes(types.RoleAdmin),
|
||||
})).Methods(http.MethodPost).GetError(); err != nil {
|
||||
@@ -360,7 +360,7 @@ func (provider *provider) addUserRoutes(router *mux.Router) error {
|
||||
Response: nil,
|
||||
ResponseContentType: "",
|
||||
SuccessStatusCode: http.StatusNoContent,
|
||||
ErrorStatusCodes: []int{http.StatusNotFound},
|
||||
ErrorStatusCodes: []int{http.StatusBadRequest, http.StatusNotFound},
|
||||
Deprecated: true,
|
||||
SecuritySchemes: newSecuritySchemes(types.RoleAdmin),
|
||||
})).Methods(http.MethodDelete).GetError(); err != nil {
|
||||
|
||||
@@ -11,10 +11,10 @@ import (
|
||||
"github.com/SigNoz/signoz/pkg/valuer"
|
||||
)
|
||||
|
||||
var (
|
||||
HTTPHostPort = GetOrDefaultEnv("SIGNOZ_HTTP_HOST_PORT", "0.0.0.0:8080") // Address to serve http (query service)
|
||||
PrivateHostPort = GetOrDefaultEnv("SIGNOZ_PRIVATE_HOST_PORT", "0.0.0.0:8085") // Address to server internal services like alert manager
|
||||
OpAmpWsEndpoint = GetOrDefaultEnv("SIGNOZ_OPAMP_WS_ENDPOINT", "0.0.0.0:4320") // address for opamp websocket
|
||||
const (
|
||||
HTTPHostPort = "0.0.0.0:8080" // Address to serve http (query service)
|
||||
PrivateHostPort = "0.0.0.0:8085" // Address to server internal services like alert manager
|
||||
OpAmpWsEndpoint = "0.0.0.0:4320" // address for opamp websocket
|
||||
)
|
||||
|
||||
const MaxAllowedPointsInTimeSeries = 300
|
||||
|
||||
@@ -170,7 +170,7 @@ func (u *User) UpdateEmail(email valuer.Email) {
|
||||
// enrich the error with the specific operation using errors.WithAdditionalf.
|
||||
func (u *User) ErrIfRoot() error {
|
||||
if u.IsRoot {
|
||||
return errors.New(errors.TypeUnsupported, ErrCodeRootUserOperationUnsupported, "this operation is not supported for the root user")
|
||||
return errors.New(errors.TypeInvalidInput, ErrCodeRootUserOperationUnsupported, "this operation is not supported for the root user")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -179,7 +179,7 @@ func (u *User) ErrIfRoot() error {
|
||||
// This error can be enriched with specific operation by the called using errors.WithAdditionalf.
|
||||
func (u *User) ErrIfDeleted() error {
|
||||
if u.Status == UserStatusDeleted {
|
||||
return errors.New(errors.TypeUnsupported, ErrCodeUserStatusDeleted, "unsupported operation for deleted user")
|
||||
return errors.New(errors.TypeInvalidInput, ErrCodeUserStatusDeleted, "unsupported operation for deleted user")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -188,7 +188,7 @@ func (u *User) ErrIfDeleted() error {
|
||||
// This error can be enriched with specific operation by the called using errors.WithAdditionalf.
|
||||
func (u *User) ErrIfPending() error {
|
||||
if u.Status == UserStatusPendingInvite {
|
||||
return errors.New(errors.TypeUnsupported, ErrCodeUserStatusPendingInvite, "unsupported operation for pending user")
|
||||
return errors.New(errors.TypeInvalidInput, ErrCodeUserStatusPendingInvite, "unsupported operation for pending user")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -55,3 +55,33 @@ def test_impersonated_user_is_admin(signoz: types.SigNoz) -> None:
|
||||
)
|
||||
assert root_detail.status_code == HTTPStatus.OK
|
||||
assert_user_has_role(root_detail.json()["data"], "signoz-admin")
|
||||
|
||||
|
||||
def test_mutating_root_user_is_rejected(signoz: types.SigNoz) -> None:
|
||||
"""
|
||||
The root user is permanently protected, so mutating it is rejected with
|
||||
400 and a machine readable code. ErrIfRoot runs before the self-delete
|
||||
guard, so this holds even when the caller is the impersonated root
|
||||
identity itself.
|
||||
"""
|
||||
response = requests.get(
|
||||
signoz.self.host_configs["8080"].get("/api/v2/users"),
|
||||
timeout=2,
|
||||
)
|
||||
assert response.status_code == HTTPStatus.OK
|
||||
|
||||
root_user = next(
|
||||
(u for u in response.json()["data"] if u.get("isRoot") is True),
|
||||
None,
|
||||
)
|
||||
assert root_user is not None
|
||||
|
||||
response = requests.delete(
|
||||
signoz.self.host_configs["8080"].get(f"/api/v2/users/{root_user['id']}"),
|
||||
timeout=2,
|
||||
)
|
||||
|
||||
assert response.status_code == HTTPStatus.BAD_REQUEST, response.text
|
||||
error = response.json()["error"]
|
||||
assert error["type"] == "invalid-input"
|
||||
assert error["code"] == "root_user_operation_unsupported"
|
||||
|
||||
Reference in New Issue
Block a user