Alerting: Fix fine-grained rule access control to use 403 for authorization error (#79239)

* use 403 for authorization error
* update silences API
* add ForbiddenError to rule API responses
This commit is contained in:
Yuri Tseretyan
2023-12-07 13:43:58 -05:00
committed by GitHub
parent aa12c6c772
commit 2be7605794
17 changed files with 629 additions and 444 deletions
+83 -393
View File
@@ -280,9 +280,6 @@
},
"type": "object"
},
"AlertStateType": {
"type": "string"
},
"AlertingFileExport": {
"properties": {
"apiVersion": {
@@ -404,80 +401,6 @@
},
"type": "object"
},
"Annotation": {
"properties": {
"alertId": {
"format": "int64",
"type": "integer"
},
"alertName": {
"type": "string"
},
"avatarUrl": {
"type": "string"
},
"created": {
"format": "int64",
"type": "integer"
},
"dashboardId": {
"format": "int64",
"type": "integer"
},
"dashboardUID": {
"type": "string"
},
"data": {
"$ref": "#/definitions/Json"
},
"email": {
"type": "string"
},
"id": {
"format": "int64",
"type": "integer"
},
"login": {
"type": "string"
},
"newState": {
"type": "string"
},
"panelId": {
"format": "int64",
"type": "integer"
},
"prevState": {
"type": "string"
},
"tags": {
"items": {
"type": "string"
},
"type": "array"
},
"text": {
"type": "string"
},
"time": {
"format": "int64",
"type": "integer"
},
"timeEnd": {
"format": "int64",
"type": "integer"
},
"updated": {
"format": "int64",
"type": "integer"
},
"userId": {
"format": "int64",
"type": "integer"
}
},
"type": "object"
},
"ApiRuleNode": {
"properties": {
"alert": {
@@ -657,75 +580,12 @@
},
"type": "array"
},
"CookieType": {
"type": "string"
},
"CounterResetHint": {
"description": "or alternatively that we are dealing with a gauge histogram, where counter resets do not apply.",
"format": "uint8",
"title": "CounterResetHint contains the known information about a counter reset,",
"type": "integer"
},
"CreateLibraryElementCommand": {
"description": "CreateLibraryElementCommand is the command for adding a LibraryElement",
"properties": {
"folderId": {
"description": "ID of the folder where the library element is stored.\n\nDeprecated: use FolderUID instead",
"format": "int64",
"type": "integer"
},
"folderUid": {
"description": "UID of the folder where the library element is stored.",
"type": "string"
},
"kind": {
"description": "Kind of element to create, Use 1 for library panels or 2 for c.\nDescription:\n1 - library panels\n2 - library variables",
"enum": [
1,
2
],
"format": "int64",
"type": "integer"
},
"model": {
"description": "The JSON model for the library element.",
"type": "object"
},
"name": {
"description": "Name of the library element.",
"type": "string"
},
"uid": {
"type": "string"
}
},
"type": "object"
},
"DashboardACLUpdateItem": {
"properties": {
"permission": {
"$ref": "#/definitions/PermissionType"
},
"role": {
"enum": [
"None",
"Viewer",
"Editor",
"Admin"
],
"type": "string"
},
"teamId": {
"format": "int64",
"type": "integer"
},
"userId": {
"format": "int64",
"type": "integer"
}
},
"type": "object"
},
"DataLink": {
"description": "DataLink define what",
"properties": {
@@ -988,6 +848,9 @@
},
"EvalQueriesPayload": {
"properties": {
"condition": {
"type": "string"
},
"data": {
"items": {
"$ref": "#/definitions/AlertQuery"
@@ -1195,6 +1058,14 @@
"title": "FloatHistogram is similar to Histogram but uses float64 for all\ncounts. Additionally, bucket counts are absolute and not deltas.",
"type": "object"
},
"ForbiddenError": {
"properties": {
"body": {
"$ref": "#/definitions/PublicError"
}
},
"type": "object"
},
"Frame": {
"description": "Each Field is well typed by its FieldType and supports optional Labels.\n\nA Frame is a general data container for Grafana. A Frame can be table data\nor time series data depending on its content and field types.",
"properties": {
@@ -1960,82 +1831,6 @@
},
"type": "array"
},
"LegacyAlert": {
"properties": {
"Created": {
"format": "date-time",
"type": "string"
},
"DashboardID": {
"format": "int64",
"type": "integer"
},
"EvalData": {
"$ref": "#/definitions/Json"
},
"ExecutionError": {
"type": "string"
},
"For": {
"$ref": "#/definitions/Duration"
},
"Frequency": {
"format": "int64",
"type": "integer"
},
"Handler": {
"format": "int64",
"type": "integer"
},
"ID": {
"format": "int64",
"type": "integer"
},
"Message": {
"type": "string"
},
"Name": {
"type": "string"
},
"NewStateDate": {
"format": "date-time",
"type": "string"
},
"OrgID": {
"format": "int64",
"type": "integer"
},
"PanelID": {
"format": "int64",
"type": "integer"
},
"Settings": {
"$ref": "#/definitions/Json"
},
"Severity": {
"type": "string"
},
"Silenced": {
"type": "boolean"
},
"State": {
"$ref": "#/definitions/AlertStateType"
},
"StateChanges": {
"format": "int64",
"type": "integer"
},
"Updated": {
"format": "date-time",
"type": "string"
},
"Version": {
"format": "int64",
"type": "integer"
}
},
"type": "object"
},
"LinkTransformationConfig": {
"properties": {
"expression": {
@@ -2107,48 +1902,6 @@
},
"type": "array"
},
"MetricRequest": {
"properties": {
"debug": {
"type": "boolean"
},
"from": {
"description": "From Start time in epoch timestamps in milliseconds or relative using Grafana time units.",
"example": "now-1h",
"type": "string"
},
"queries": {
"description": "queries.refId Specifies an identifier of the query. Is optional and default to “A”.\nqueries.datasourceId Specifies the data source to be queried. Each query in the request must have an unique datasourceId.\nqueries.maxDataPoints - Species maximum amount of data points that dashboard panel can render. Is optional and default to 100.\nqueries.intervalMs - Specifies the time interval in milliseconds of time series. Is optional and defaults to 1000.",
"example": [
{
"datasource": {
"uid": "PD8C576611E62080A"
},
"format": "table",
"intervalMs": 86400000,
"maxDataPoints": 1092,
"rawSql": "SELECT 1 as valueOne, 2 as valueTwo",
"refId": "A"
}
],
"items": {
"$ref": "#/definitions/Json"
},
"type": "array"
},
"to": {
"description": "To End time in epoch timestamps in milliseconds or relative using Grafana time units.",
"example": "now",
"type": "string"
}
},
"required": [
"from",
"to",
"queries"
],
"type": "object"
},
"MultiStatus": {
"type": "object"
},
@@ -2182,24 +1935,6 @@
},
"type": "object"
},
"NewApiKeyResult": {
"properties": {
"id": {
"example": 1,
"format": "int64",
"type": "integer"
},
"key": {
"example": "glsa_yscW25imSKJIuav8zF37RZmnbiDvB05G_fcaaf58a",
"type": "string"
},
"name": {
"example": "grafana",
"type": "string"
}
},
"type": "object"
},
"NotFound": {
"type": "object"
},
@@ -2230,12 +1965,58 @@
},
"NotificationPolicyExport": {
"properties": {
"Policy": {
"$ref": "#/definitions/RouteExport"
"continue": {
"type": "boolean"
},
"group_by": {
"items": {
"type": "string"
},
"type": "array"
},
"group_interval": {
"type": "string"
},
"group_wait": {
"type": "string"
},
"match": {
"additionalProperties": {
"type": "string"
},
"description": "Deprecated. Remove before v1.0 release.",
"type": "object"
},
"match_re": {
"$ref": "#/definitions/MatchRegexps"
},
"matchers": {
"$ref": "#/definitions/Matchers"
},
"mute_time_intervals": {
"items": {
"type": "string"
},
"type": "array"
},
"object_matchers": {
"$ref": "#/definitions/ObjectMatchers"
},
"orgId": {
"format": "int64",
"type": "integer"
},
"receiver": {
"type": "string"
},
"repeat_interval": {
"type": "string"
},
"routes": {
"items": {
"$ref": "#/definitions/RouteExport"
},
"type": "array"
}
},
"title": "NotificationPolicyExport is the provisioned file export of alerting.NotificiationPolicyV1.",
@@ -2504,56 +2285,9 @@
},
"type": "object"
},
"PatchPrefsCmd": {
"properties": {
"cookies": {
"items": {
"$ref": "#/definitions/CookieType"
},
"type": "array"
},
"homeDashboardId": {
"default": 0,
"description": "The numerical :id of a favorited dashboard",
"format": "int64",
"type": "integer"
},
"homeDashboardUID": {
"type": "string"
},
"language": {
"type": "string"
},
"queryHistory": {
"$ref": "#/definitions/QueryHistoryPreference"
},
"theme": {
"enum": [
"light",
"dark"
],
"type": "string"
},
"timezone": {
"enum": [
"utc",
"browser"
],
"type": "string"
},
"weekStart": {
"type": "string"
}
},
"type": "object"
},
"PermissionDenied": {
"type": "object"
},
"PermissionType": {
"format": "int64",
"type": "integer"
},
"Point": {
"description": "If H is not nil, then this is a histogram point and only (T, H) is valid.\nIf H is nil, then only (T, V) is valid.",
"properties": {
@@ -3057,6 +2791,26 @@
},
"type": "object"
},
"PublicError": {
"description": "PublicError is derived from Error and only contains information\navailable to the end user.",
"properties": {
"extra": {
"additionalProperties": {},
"type": "object"
},
"message": {
"type": "string"
},
"messageId": {
"type": "string"
},
"statusCode": {
"format": "int64",
"type": "integer"
}
},
"type": "object"
},
"PushoverConfig": {
"properties": {
"device": {
@@ -3113,14 +2867,6 @@
},
"type": "object"
},
"QueryHistoryPreference": {
"properties": {
"homeTab": {
"type": "string"
}
},
"type": "object"
},
"QueryStat": {
"description": "The embedded FieldConfig's display name must be set.\nIt corresponds to the QueryResultMetaStat on the frontend (https://github.com/grafana/grafana/blob/master/packages/grafana-data/src/types/data.ts#L53).",
"properties": {
@@ -4218,7 +3964,6 @@
"type": "object"
},
"URL": {
"description": "The general form represented is:\n\n[scheme:][//[userinfo@]host][/]path[?query][#fragment]\n\nURLs that do not start with a slash after the scheme are interpreted as:\n\nscheme:opaque[?query][#fragment]\n\nNote that the Path field is stored in decoded form: /%47%6f%2f becomes /Go/.\nA consequence is that it is impossible to tell which slashes in the Path were\nslashes in the raw URL and which were %2f. This distinction is rarely important,\nbut when it is, the code should use the EscapedPath method, which preserves\nthe original encoding of Path.\n\nThe RawPath field is an optional field which is only set when the default\nencoding of Path is different from the escaped path. See the EscapedPath method\nfor more details.\n\nURL's String method uses the EscapedPath method to obtain the path.",
"properties": {
"ForceQuery": {
"type": "boolean"
@@ -4254,62 +3999,7 @@
"$ref": "#/definitions/Userinfo"
}
},
"title": "A URL represents a parsed URL (technically, a URI reference).",
"type": "object"
},
"UpdateDashboardACLCommand": {
"properties": {
"items": {
"items": {
"$ref": "#/definitions/DashboardACLUpdateItem"
},
"type": "array"
}
},
"type": "object"
},
"UpdatePrefsCmd": {
"properties": {
"cookies": {
"items": {
"$ref": "#/definitions/CookieType"
},
"type": "array"
},
"homeDashboardId": {
"default": 0,
"description": "The numerical :id of a favorited dashboard",
"format": "int64",
"type": "integer"
},
"homeDashboardUID": {
"type": "string"
},
"language": {
"type": "string"
},
"queryHistory": {
"$ref": "#/definitions/QueryHistoryPreference"
},
"theme": {
"enum": [
"light",
"dark",
"system"
],
"type": "string"
},
"timezone": {
"enum": [
"utc",
"browser"
],
"type": "string"
},
"weekStart": {
"type": "string"
}
},
"title": "URL is a custom URL type that allows validation at configuration load time.",
"type": "object"
},
"UpdateRuleGroupResponse": {
@@ -4515,7 +4205,6 @@
"type": "object"
},
"alertGroup": {
"description": "AlertGroup alert group",
"properties": {
"alerts": {
"description": "alerts",
@@ -4644,7 +4333,6 @@
"type": "object"
},
"gettableAlert": {
"description": "GettableAlert gettable alert",
"properties": {
"annotations": {
"$ref": "#/definitions/labelSet"
@@ -4707,6 +4395,7 @@
"type": "array"
},
"gettableSilence": {
"description": "GettableSilence gettable silence",
"properties": {
"comment": {
"description": "comment",
@@ -4755,6 +4444,7 @@
"type": "object"
},
"gettableSilences": {
"description": "GettableSilences gettable silences",
"items": {
"$ref": "#/definitions/gettableSilence"
},
@@ -4905,7 +4595,6 @@
"type": "array"
},
"postableSilence": {
"description": "PostableSilence postable silence",
"properties": {
"comment": {
"description": "comment",
@@ -4943,6 +4632,7 @@
"type": "object"
},
"receiver": {
"description": "Receiver receiver",
"properties": {
"active": {
"description": "active",