Skip to content

Commit c0741f2

Browse files
fixes on RBAC (#916)
1. role assignment to all the priviledges fixes as per sheet - https://docs.google.com/spreadsheets/d/1N-LHWTcyVzdAFR5bAPnOpRLQXdgaQ6wBHQ47skUFlPI/edit?gid=0#gid=0 2. login API restricted for ingestors 3. added authorization for metrics API
1 parent a3b63bb commit c0741f2

File tree

6 files changed

+106
-20
lines changed

6 files changed

+106
-20
lines changed

server/src/handlers/http/cluster/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,7 @@ pub async fn fetch_daily_stats_from_ingestors(
174174

175175
let res = reqwest::Client::new()
176176
.get(uri)
177+
.header(header::AUTHORIZATION, &ingestor.token)
177178
.header(header::CONTENT_TYPE, "application/json")
178179
.send()
179180
.await;
@@ -526,6 +527,7 @@ async fn fetch_cluster_metrics() -> Result<Vec<Metrics>, PostError> {
526527

527528
let res = reqwest::Client::new()
528529
.get(uri)
530+
.header(header::AUTHORIZATION, &ingestor.token)
529531
.header(header::CONTENT_TYPE, "application/json")
530532
.send()
531533
.await;

server/src/handlers/http/modal/ingest_server.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,7 @@ impl IngestServer {
181181
.service(Server::get_about_factory())
182182
.service(Self::analytics_factory())
183183
.service(Server::get_liveness_factory())
184+
.service(Server::get_metrics_webscope())
184185
.service(Server::get_readiness_factory()),
185186
)
186187
.service(Server::get_ingest_otel_factory());
@@ -226,7 +227,7 @@ impl IngestServer {
226227
web::resource("/info").route(
227228
web::get()
228229
.to(logstream::get_stream_info)
229-
.authorize_for_stream(Action::GetStream),
230+
.authorize_for_stream(Action::GetStreamInfo),
230231
),
231232
)
232233
.service(

server/src/handlers/http/modal/query_server.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,7 @@ impl QueryServer {
165165
.service(Server::get_llm_webscope())
166166
.service(Server::get_oauth_webscope(oidc_client))
167167
.service(Server::get_user_role_webscope())
168+
.service(Server::get_metrics_webscope())
168169
.service(Self::get_cluster_web_scope()),
169170
)
170171
.service(Server::get_generated());

server/src/handlers/http/modal/server.rs

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -180,12 +180,19 @@ impl Server {
180180
.service(Self::get_filters_webscope())
181181
.service(Self::get_llm_webscope())
182182
.service(Self::get_oauth_webscope(oidc_client))
183-
.service(Self::get_user_role_webscope()),
183+
.service(Self::get_user_role_webscope())
184+
.service(Self::get_metrics_webscope()),
184185
)
185186
.service(Self::get_ingest_otel_factory())
186187
.service(Self::get_generated());
187188
}
188189

190+
pub fn get_metrics_webscope() -> Scope {
191+
web::scope("/metrics").service(
192+
web::resource("").route(web::get().to(metrics::get).authorize(Action::Metrics)),
193+
)
194+
}
195+
189196
// get the dashboards web scope
190197
pub fn get_dashboards_webscope() -> Scope {
191198
web::scope("/dashboards")
@@ -312,7 +319,7 @@ impl Server {
312319
web::resource("/info").route(
313320
web::get()
314321
.to(logstream::get_stream_info)
315-
.authorize_for_stream(Action::GetStream),
322+
.authorize_for_stream(Action::GetStreamInfo),
316323
),
317324
)
318325
.service(
@@ -423,8 +430,10 @@ impl Server {
423430
// get the oauth webscope
424431
pub fn get_oauth_webscope(oidc_client: Option<OpenIdClient>) -> Scope {
425432
let oauth = web::scope("/o")
426-
.service(resource("/login").route(web::get().to(oidc::login)))
427-
.service(resource("/logout").route(web::get().to(oidc::logout)))
433+
.service(resource("/login").route(web::get().to(oidc::login).authorize(Action::Login)))
434+
.service(
435+
resource("/logout").route(web::get().to(oidc::logout).authorize(Action::Login)),
436+
)
428437
.service(resource("/code").route(web::get().to(oidc::reply_login)));
429438

430439
if let Some(client) = oidc_client {

server/src/metrics/mod.rs

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,9 @@ pub mod prom_utils;
2020
pub mod storage;
2121

2222
use crate::{handlers::http::metrics_path, stats::FullStats};
23+
use actix_web::Responder;
2324
use actix_web_prometheus::{PrometheusMetrics, PrometheusMetricsBuilder};
25+
use error::MetricsError;
2426
use once_cell::sync::Lazy;
2527
use prometheus::{HistogramOpts, HistogramVec, IntCounterVec, IntGaugeVec, Opts, Registry};
2628

@@ -287,3 +289,42 @@ pub async fn fetch_stats_from_storage(stream_name: &str, stats: FullStats) {
287289
.with_label_values(&["data", stream_name, "parquet"])
288290
.set(stats.lifetime_stats.storage as i64);
289291
}
292+
293+
use actix_web::HttpResponse;
294+
295+
pub async fn get() -> Result<impl Responder, MetricsError> {
296+
Ok(HttpResponse::Ok().body(format!("{:?}", build_metrics_handler())))
297+
}
298+
299+
pub mod error {
300+
301+
use actix_web::http::header::ContentType;
302+
use http::StatusCode;
303+
304+
#[derive(Debug, thiserror::Error)]
305+
pub enum MetricsError {
306+
#[error("{0}")]
307+
Custom(String, StatusCode),
308+
}
309+
310+
impl actix_web::ResponseError for MetricsError {
311+
fn status_code(&self) -> http::StatusCode {
312+
match self {
313+
Self::Custom(_, _) => StatusCode::INTERNAL_SERVER_ERROR,
314+
}
315+
}
316+
317+
fn error_response(&self) -> actix_web::HttpResponse<actix_web::body::BoxBody> {
318+
actix_web::HttpResponse::build(self.status_code())
319+
.insert_header(ContentType::plaintext())
320+
.body(self.to_string())
321+
}
322+
}
323+
324+
#[allow(dead_code)]
325+
fn construct_custom_error() {
326+
let error =
327+
MetricsError::Custom("Some error".to_string(), StatusCode::INTERNAL_SERVER_ERROR);
328+
println!("{:?}", error);
329+
}
330+
}

server/src/rbac/role.rs

Lines changed: 47 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ pub enum Action {
2424
Query,
2525
CreateStream,
2626
ListStream,
27-
GetStream,
27+
GetStreamInfo,
2828
GetSchema,
2929
GetStats,
3030
DeleteStream,
@@ -63,6 +63,8 @@ pub enum Action {
6363
DeleteFilter,
6464
ListCache,
6565
RemoveCache,
66+
Login,
67+
Metrics,
6668
}
6769

6870
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
@@ -102,7 +104,9 @@ impl RoleBuilder {
102104
self.stream.clone().unwrap(),
103105
self.tag.clone(),
104106
),
105-
Action::PutUser
107+
Action::Login
108+
| Action::Metrics
109+
| Action::PutUser
106110
| Action::ListUser
107111
| Action::PutUserRoles
108112
| Action::GetUserRoles
@@ -115,7 +119,7 @@ impl RoleBuilder {
115119
| Action::ListRole
116120
| Action::CreateStream
117121
| Action::DeleteStream
118-
| Action::GetStream
122+
| Action::GetStreamInfo
119123
| Action::ListStream
120124
| Action::ListCluster
121125
| Action::ListClusterMetrics
@@ -201,11 +205,14 @@ pub mod model {
201205
fn editor_perm_builder() -> RoleBuilder {
202206
RoleBuilder {
203207
actions: vec![
208+
Action::Login,
209+
Action::Metrics,
204210
Action::Ingest,
205211
Action::Query,
206212
Action::CreateStream,
213+
Action::DeleteStream,
207214
Action::ListStream,
208-
Action::GetStream,
215+
Action::GetStreamInfo,
209216
Action::GetSchema,
210217
Action::GetStats,
211218
Action::GetRetention,
@@ -217,8 +224,15 @@ pub mod model {
217224
Action::DeleteHotTierEnabled,
218225
Action::PutAlert,
219226
Action::GetAlert,
220-
Action::GetAbout,
221227
Action::QueryLLM,
228+
Action::CreateFilter,
229+
Action::ListFilter,
230+
Action::GetFilter,
231+
Action::DeleteFilter,
232+
Action::ListDashboard,
233+
Action::GetDashboard,
234+
Action::CreateDashboard,
235+
Action::DeleteDashboard,
222236
],
223237
stream: Some("*".to_string()),
224238
tag: None,
@@ -228,17 +242,31 @@ pub mod model {
228242
fn writer_perm_builder() -> RoleBuilder {
229243
RoleBuilder {
230244
actions: vec![
231-
Action::Ingest,
245+
Action::Login,
232246
Action::Query,
233247
Action::ListStream,
234-
Action::GetStream,
235248
Action::GetSchema,
236249
Action::GetStats,
237-
Action::GetRetention,
250+
Action::PutRetention,
238251
Action::PutAlert,
239252
Action::GetAlert,
240-
Action::GetAbout,
253+
Action::GetRetention,
254+
Action::PutHotTierEnabled,
255+
Action::GetHotTierEnabled,
256+
Action::DeleteHotTierEnabled,
257+
Action::ListDashboard,
258+
Action::GetDashboard,
259+
Action::CreateDashboard,
260+
Action::DeleteDashboard,
261+
Action::Ingest,
241262
Action::QueryLLM,
263+
Action::GetStreamInfo,
264+
Action::GetCacheEnabled,
265+
Action::PutCacheEnabled,
266+
Action::GetFilter,
267+
Action::ListFilter,
268+
Action::CreateFilter,
269+
Action::DeleteFilter,
242270
],
243271
stream: None,
244272
tag: None,
@@ -248,17 +276,21 @@ pub mod model {
248276
fn reader_perm_builder() -> RoleBuilder {
249277
RoleBuilder {
250278
actions: vec![
279+
Action::Login,
251280
Action::Query,
252281
Action::ListStream,
253-
Action::GetStream,
254282
Action::GetSchema,
255283
Action::GetStats,
256-
Action::GetRetention,
257-
Action::GetAlert,
258-
Action::GetAbout,
259284
Action::QueryLLM,
260-
Action::ListCluster,
261-
Action::GetHotTierEnabled,
285+
Action::ListFilter,
286+
Action::GetFilter,
287+
Action::CreateFilter,
288+
Action::DeleteFilter,
289+
Action::ListDashboard,
290+
Action::GetDashboard,
291+
Action::CreateDashboard,
292+
Action::DeleteDashboard,
293+
Action::GetStreamInfo,
262294
],
263295
stream: None,
264296
tag: None,

0 commit comments

Comments
 (0)