Skip to content

Commit 1263e53

Browse files
authored
feat(query): add api for users & roles (#17553)
* feat(query): add api for users & roles * z * z * z * z * z * z * z * z * z * z * z * z * z * z * z * z * z
1 parent fad982d commit 1263e53

File tree

8 files changed

+399
-17
lines changed

8 files changed

+399
-17
lines changed

src/query/service/src/servers/http/middleware/session.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,7 @@ pub enum EndpointKind {
9494
UploadToStage,
9595
SystemInfo,
9696
Catalog,
97+
Metadata,
9798
}
9899

99100
impl EndpointKind {
@@ -121,6 +122,7 @@ impl EndpointKind {
121122
| EndpointKind::SystemInfo
122123
| EndpointKind::HeartBeat
123124
| EndpointKind::UploadToStage
125+
| EndpointKind::Metadata
124126
| EndpointKind::Catalog => {
125127
if GlobalConfig::instance().query.management_mode {
126128
Ok(None)

src/query/service/src/servers/http/v1/catalog/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,12 @@ pub mod get_database_table;
1616
pub mod list_database_table_fields;
1717
pub mod list_database_tables;
1818
pub mod list_databases;
19+
pub mod search_databases;
1920
pub mod search_tables;
2021

2122
pub use get_database_table::get_database_table_handler;
2223
pub use list_database_table_fields::list_database_table_fields_handler;
2324
pub use list_database_tables::list_database_tables_handler;
2425
pub use list_databases::list_databases_handler;
26+
pub use search_databases::search_databases_handler;
2527
pub use search_tables::search_tables_handler;
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
// Copyright 2021 Datafuse Labs
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
use databend_common_catalog::catalog::CatalogManager;
16+
use databend_common_exception::Result;
17+
use poem::error::InternalServerError;
18+
use poem::error::Result as PoemResult;
19+
use poem::web::Json;
20+
use poem::IntoResponse;
21+
use serde::Deserialize;
22+
use serde::Serialize;
23+
24+
use crate::servers::http::v1::HttpQueryContext;
25+
26+
#[derive(Deserialize, Clone)]
27+
struct SearchDatabasesRequest {
28+
pub keyword: String,
29+
}
30+
31+
#[derive(Serialize, Deserialize, Eq, PartialEq, Debug, Default)]
32+
pub struct SearchDatabasesResponse {
33+
pub databases: Vec<DatabaseInfo>,
34+
pub warnings: Vec<String>,
35+
}
36+
37+
#[derive(Serialize, Deserialize, Eq, PartialEq, Debug, Default)]
38+
pub struct DatabaseInfo {
39+
pub name: String,
40+
}
41+
42+
#[async_backtrace::framed]
43+
async fn handle(ctx: &HttpQueryContext, keyword: String) -> Result<SearchDatabasesResponse> {
44+
let tenant = ctx.session.get_current_tenant();
45+
let visibility_checker = ctx.session.get_visibility_checker(false).await?;
46+
47+
let catalog = CatalogManager::instance().get_default_catalog(Default::default())?;
48+
49+
let mut databases = vec![];
50+
let warnings = vec![];
51+
52+
for db in catalog.list_databases(&tenant).await? {
53+
if !db.name().contains(&keyword) {
54+
continue;
55+
}
56+
if !visibility_checker.check_database_visibility(
57+
catalog.name().as_str(),
58+
db.name(),
59+
db.get_db_info().database_id.db_id,
60+
) {
61+
continue;
62+
}
63+
databases.push(DatabaseInfo {
64+
name: db.name().to_string(),
65+
});
66+
}
67+
68+
Ok(SearchDatabasesResponse {
69+
databases,
70+
warnings,
71+
})
72+
}
73+
74+
#[poem::handler]
75+
#[async_backtrace::framed]
76+
pub async fn search_databases_handler(
77+
ctx: &HttpQueryContext,
78+
Json(req): Json<SearchDatabasesRequest>,
79+
) -> PoemResult<impl IntoResponse> {
80+
let resp = handle(ctx, req.keyword)
81+
.await
82+
.map_err(InternalServerError)?;
83+
Ok(Json(resp))
84+
}

src/query/service/src/servers/http/v1/http_query_handlers.rs

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ use crate::servers::http::v1::catalog::get_database_table_handler;
5454
use crate::servers::http::v1::catalog::list_database_table_fields_handler;
5555
use crate::servers::http::v1::catalog::list_database_tables_handler;
5656
use crate::servers::http::v1::catalog::list_databases_handler;
57+
use crate::servers::http::v1::catalog::search_databases_handler;
5758
use crate::servers::http::v1::catalog::search_tables_handler;
5859
use crate::servers::http::v1::discovery_nodes;
5960
use crate::servers::http::v1::list_suggestions;
@@ -62,7 +63,10 @@ use crate::servers::http::v1::logout_handler;
6263
use crate::servers::http::v1::query::string_block::StringBlock;
6364
use crate::servers::http::v1::query::Progresses;
6465
use crate::servers::http::v1::refresh_handler;
66+
use crate::servers::http::v1::roles::list_roles_handler;
6567
use crate::servers::http::v1::upload_to_stage;
68+
use crate::servers::http::v1::users::create_user_handler;
69+
use crate::servers::http::v1::users::list_users_handler;
6670
use crate::servers::http::v1::verify_handler;
6771
use crate::servers::http::v1::HttpQueryContext;
6872
use crate::servers::http::v1::HttpQueryManager;
@@ -502,10 +506,21 @@ pub fn query_route() -> Route {
502506
EndpointKind::Catalog,
503507
),
504508
(
505-
"/catalog/tables/search",
509+
"/catalog/search/tables",
506510
post(search_tables_handler),
507511
EndpointKind::Catalog,
508512
),
513+
(
514+
"/catalog/search/databases",
515+
post(search_databases_handler),
516+
EndpointKind::Catalog,
517+
),
518+
(
519+
"/users",
520+
get(list_users_handler).post(create_user_handler),
521+
EndpointKind::Metadata,
522+
),
523+
("/roles", get(list_roles_handler), EndpointKind::Metadata),
509524
];
510525

511526
let mut route = Route::new();
@@ -518,6 +533,7 @@ pub fn query_route() -> Route {
518533
.with(CookieJarManager::new()),
519534
);
520535
}
536+
521537
route
522538
}
523539

src/query/service/src/servers/http/v1/mod.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,11 @@ pub mod catalog;
1616
mod discovery;
1717
mod http_query_handlers;
1818
mod query;
19+
pub mod roles;
1920
mod session;
2021
mod stage;
2122
mod suggestions;
23+
pub mod users;
2224
mod verify;
2325

2426
pub use discovery::discovery_nodes;
@@ -35,6 +37,7 @@ pub use query::ExpiringState;
3537
pub use query::HttpQueryContext;
3638
pub use query::HttpQueryManager;
3739
pub use query::HttpSessionConf;
40+
pub use roles::list_roles_handler;
3841
pub use session::login_handler::login_handler;
3942
pub use session::login_handler::LoginResponse;
4043
pub use session::logout_handler::logout_handler;
@@ -47,6 +50,8 @@ pub use stage::upload_to_stage;
4750
pub use stage::UploadToStageResponse;
4851
pub use suggestions::list_suggestions;
4952
pub use suggestions::SuggestionsResponse;
53+
pub use users::create_user_handler;
54+
pub use users::list_users_handler;
5055
pub use verify::verify_handler;
5156

5257
pub use crate::servers::http::clickhouse_handler::clickhouse_router;
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
// Copyright 2021 Datafuse Labs
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
use databend_common_exception::Result;
16+
use poem::error::InternalServerError;
17+
use poem::error::Result as PoemResult;
18+
use poem::web::Json;
19+
use poem::IntoResponse;
20+
use serde::Deserialize;
21+
use serde::Serialize;
22+
23+
use crate::servers::http::v1::HttpQueryContext;
24+
25+
#[derive(Serialize, Deserialize, Debug, Clone)]
26+
pub struct ListRolesResponse {
27+
pub roles: Vec<RoleInfo>,
28+
}
29+
30+
#[derive(Serialize, Deserialize, Debug, Clone)]
31+
pub struct RoleInfo {
32+
pub name: String,
33+
pub is_current: bool,
34+
pub is_default: bool,
35+
}
36+
37+
#[async_backtrace::framed]
38+
async fn handle(ctx: &HttpQueryContext) -> Result<ListRolesResponse> {
39+
let user = ctx.session.get_current_user()?;
40+
let current_role = ctx
41+
.session
42+
.get_current_role()
43+
.map_or("public".to_string(), |role| role.name);
44+
let default_role = user
45+
.option
46+
.default_role()
47+
.map_or("public".to_string(), |role| role.to_string());
48+
let mut roles = vec![];
49+
for role in user.grants.roles() {
50+
let is_current = role == current_role;
51+
let is_default = role == default_role;
52+
roles.push(RoleInfo {
53+
name: role.clone(),
54+
is_current,
55+
is_default,
56+
});
57+
}
58+
if roles.is_empty() {
59+
roles.push(RoleInfo {
60+
name: "public".to_string(),
61+
is_current: true,
62+
is_default: true,
63+
});
64+
}
65+
Ok(ListRolesResponse { roles })
66+
}
67+
68+
#[poem::handler]
69+
#[async_backtrace::framed]
70+
pub async fn list_roles_handler(ctx: &HttpQueryContext) -> PoemResult<impl IntoResponse> {
71+
let resp = handle(ctx).await.map_err(InternalServerError)?;
72+
Ok(Json(resp))
73+
}

0 commit comments

Comments
 (0)