Skip to content

Commit 308cf15

Browse files
committed
feat: match tests and general resource endpoints
1 parent c6df6a7 commit 308cf15

File tree

2 files changed

+244
-38
lines changed

2 files changed

+244
-38
lines changed

src/services/authorization.rs

Lines changed: 156 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ use rbs::to_value;
2929
use std::{
3030
borrow::Cow,
3131
collections::{BTreeSet, HashMap},
32+
ops::Deref,
3233
};
3334
use tonic::Request;
3435
use wildcard::Wildcard;
@@ -250,22 +251,29 @@ fn is_match(key: &String, endpoint: &Endpoint, permission: &Permission) -> bool
250251
return false;
251252
}
252253

253-
let wildcard = Wildcard::new(second.as_bytes()).unwrap();
254+
let ids = match endpoint {
255+
Endpoint::Target(Some(id))
256+
| Endpoint::Prompt(Some(id))
257+
| Endpoint::Field(Some(id))
258+
| Endpoint::Response(Some(id)) => vec![id],
259+
Endpoint::Export(Some(list)) => list.iter().collect(),
260+
Endpoint::Authorize(Some(boxed_endpoint)) => match boxed_endpoint.deref() {
261+
Endpoint::Target(Some(id))
262+
| Endpoint::Prompt(Some(id))
263+
| Endpoint::Field(Some(id))
264+
| Endpoint::Response(Some(id)) => vec![id],
265+
Endpoint::Export(Some(list)) => list.iter().collect(),
266+
_ => Vec::new(),
267+
},
268+
_ => Vec::new(),
269+
};
254270

255-
match endpoint {
256-
Endpoint::Target(Some(id)) | Endpoint::Prompt(Some(id)) | Endpoint::Field(Some(id)) => {
257-
if wildcard.is_match(id.as_bytes()) {
258-
debug!(
259-
"ResourceAuthorization {} does not match {:?} with {:?}",
260-
key, endpoint, permission
261-
);
271+
if ids.is_empty() {
272+
second.eq("*")
273+
} else {
274+
let wildcard = Wildcard::new(second.as_bytes()).unwrap();
262275

263-
true
264-
} else {
265-
false
266-
}
267-
}
268-
_ => false,
276+
ids.iter().all(|id| wildcard.is_match(id.as_bytes()))
269277
}
270278
}
271279

@@ -363,3 +371,137 @@ async fn get_target_id_by_field_id(connection: &DatabaseConnection, id: &str) ->
363371

364372
id.ok_or(FeedbackFusionError::Unauthorized)
365373
}
374+
375+
#[cfg(test)]
376+
mod tests {
377+
use std::borrow::Cow;
378+
379+
use crate::{authorization::is_match, Endpoint, Permission};
380+
381+
#[test]
382+
fn test_is_match_empty() {
383+
assert!(!is_match(
384+
&"".to_owned(),
385+
&Endpoint::Target(Some(Cow::Borrowed("Foo"))),
386+
&Permission::Write
387+
));
388+
}
389+
390+
#[test]
391+
fn test_is_match_invalid_format() {
392+
let endpoint = &Endpoint::Target(Some(Cow::Borrowed("Foo")));
393+
let permission = &Permission::Write;
394+
395+
assert!(!is_match(&"Foo".to_owned(), endpoint, permission));
396+
assert!(!is_match(&"Foo::Bar".to_owned(), endpoint, permission));
397+
assert!(!is_match(
398+
&"Foo::Bar::FooBar".to_owned(),
399+
endpoint,
400+
permission
401+
));
402+
}
403+
404+
#[test]
405+
fn test_is_match_endpoint_matches() {
406+
let endpoint = &Endpoint::Target(Some(Cow::Borrowed("Foo")));
407+
let permission = &Permission::Write;
408+
409+
assert!(is_match(
410+
&"Target::Foo::Write".to_owned(),
411+
endpoint,
412+
permission
413+
));
414+
assert!(!is_match(
415+
&"Targett::Foo::Write".to_owned(),
416+
endpoint,
417+
permission
418+
));
419+
assert!(!is_match(
420+
&"Target::Foo::Write".to_owned(),
421+
&Endpoint::Prompt(None),
422+
permission
423+
));
424+
}
425+
426+
#[test]
427+
fn test_is_match_permission_matches() {
428+
let endpoint = &Endpoint::Target(Some(Cow::Borrowed("Foo")));
429+
let permission = &Permission::Write;
430+
431+
assert!(is_match(
432+
&"Target::Foo::Write".to_owned(),
433+
endpoint,
434+
permission
435+
));
436+
assert!(!is_match(
437+
&"Target::Foo::Writer".to_owned(),
438+
endpoint,
439+
permission
440+
));
441+
assert!(!is_match(
442+
&"Target::Foo::Write".to_owned(),
443+
endpoint,
444+
&Permission::Read
445+
));
446+
}
447+
448+
#[test]
449+
fn test_is_match_wildcard() {
450+
let endpoint = &Endpoint::Target(Some(Cow::Borrowed("FooBar")));
451+
let permission = &Permission::Write;
452+
453+
assert!(is_match(
454+
&"Target::FooBar::Write".to_owned(),
455+
endpoint,
456+
permission
457+
));
458+
459+
assert!(!is_match(
460+
&"Target::FooBa::Write".to_owned(),
461+
endpoint,
462+
permission
463+
));
464+
465+
assert!(is_match(
466+
&"Target::*::Write".to_owned(),
467+
endpoint,
468+
permission
469+
));
470+
471+
assert!(is_match(
472+
&"Target::F*r::Write".to_owned(),
473+
endpoint,
474+
permission
475+
));
476+
477+
assert!(!is_match(
478+
&"Target::f*r::Write".to_owned(),
479+
endpoint,
480+
permission
481+
));
482+
}
483+
484+
#[test]
485+
fn test_is_match_full_wildcard() {
486+
let endpoint = &Endpoint::Target(None);
487+
let permission = &Permission::Write;
488+
489+
assert!(!is_match(
490+
&"Target::FooBar::Write".to_owned(),
491+
endpoint,
492+
permission
493+
));
494+
495+
assert!(is_match(
496+
&"Target::*::Write".to_owned(),
497+
endpoint,
498+
permission
499+
));
500+
501+
assert!(!is_match(
502+
&"Target::F*::Write".to_owned(),
503+
endpoint,
504+
permission
505+
));
506+
}
507+
}

src/services/v1/authorization.rs

Lines changed: 88 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -25,11 +25,11 @@ use crate::{
2525
prelude::*,
2626
};
2727
use feedback_fusion_common::proto::{
28-
AuthorizationGrant as ProtoAuthorizationGrant,
29-
AuthorizationType as ProtoAuthorizationType,
30-
// GetResourceAuthorizationRequest, ResourceAuthorization as ProtoResourceAuthorization,
31-
ResourceAuthorizationList,
32-
ResourceKind as ProtoResourceKind,
28+
AuthorizationGrant as ProtoAuthorizationGrant, AuthorizationType as ProtoAuthorizationType,
29+
DeleteResourceAuthorizationRequest, GetResourceAuthorizationRequest,
30+
GetResourceAuthorizationsRequest, ResourceAuthorization as ProtoResourceAuthorization,
31+
ResourceAuthorizationList, ResourceAuthorizationPage, ResourceKind as ProtoResourceKind,
32+
UpdateResourceAuthorizationRequest,
3333
};
3434

3535
use feedback_fusion_common::proto::CreateResourceAuthorizationRequest;
@@ -104,22 +104,86 @@ pub async fn create_resource_authorization(
104104
}))
105105
}
106106

107-
//pub async fn get_resoruce_authorization(
108-
// context: &FeedbackFusionV1Context,
109-
// request: Request<GetResourceAuthorizationRequest>,
110-
// _user_context: UserContext,
111-
//) -> Result<Response<ProtoResourceAuthorization>> {
112-
// let connection = context.connection();
113-
// let data = request.into_inner();
114-
// data.validate()?;
115-
//
116-
// let authorization = database_request!(
117-
// ResourceAuthorization::select_by_id(connection, data.id.as_str()).await,
118-
// "Select authorization by id"
119-
// )?
120-
// .ok_or(FeedbackFusionError::BadRequest(
121-
// "ResourceAuthorization not found".to_owned(),
122-
// ))?;
123-
//
124-
// Ok(Response::new(authorization.into()))
125-
//}
107+
pub async fn get_resoruce_authorization(
108+
context: &FeedbackFusionV1Context,
109+
request: Request<GetResourceAuthorizationRequest>,
110+
_user_context: UserContext,
111+
) -> Result<Response<ProtoResourceAuthorization>> {
112+
let connection = context.connection();
113+
let data = request.into_inner();
114+
data.validate()?;
115+
116+
let authorization = database_request!(
117+
ResourceAuthorization::select_by_id(connection, data.id.as_str()).await,
118+
"Select authorization by id"
119+
)?
120+
.ok_or(FeedbackFusionError::BadRequest(
121+
"ResourceAuthorization not found".to_owned(),
122+
))?;
123+
124+
Ok(Response::new(authorization.into()))
125+
}
126+
127+
pub async fn get_resource_authorizations(
128+
context: &FeedbackFusionV1Context,
129+
request: Request<GetResourceAuthorizationsRequest>,
130+
_user_context: UserContext,
131+
) -> Result<Response<ResourceAuthorizationPage>> {
132+
let _connection = context.connection();
133+
let _data = request.into_inner();
134+
135+
todo!();
136+
}
137+
138+
pub async fn update_resource_authorization(
139+
context: &FeedbackFusionV1Context,
140+
request: Request<UpdateResourceAuthorizationRequest>,
141+
_user_context: UserContext,
142+
) -> Result<Response<ProtoResourceAuthorization>> {
143+
let connection = context.connection();
144+
let data = request.into_inner();
145+
data.validate()?;
146+
147+
let mut authorization = database_request!(
148+
ResourceAuthorization::select_by_id(connection, data.id.as_str()).await,
149+
"Select ResourceAuthorization by id"
150+
)?
151+
.ok_or(FeedbackFusionError::BadRequest(
152+
"ResourceAuthorization not found".to_owned(),
153+
))?;
154+
155+
authorization.set_resource_id(data.resource_id);
156+
if let Some(grant) = data.authorization_grant {
157+
authorization
158+
.set_authorization_grant((&ProtoAuthorizationGrant::try_from(grant).unwrap()).into());
159+
}
160+
161+
if let Some(authorization_type) = data.authorization_type {
162+
authorization.set_authorization_type(
163+
(&ProtoAuthorizationType::try_from(authorization_type).unwrap()).into(),
164+
);
165+
}
166+
167+
database_request!(
168+
ResourceAuthorization::update_by_column(connection, &authorization, "id").await,
169+
"Update Resourceauthorization"
170+
)?;
171+
172+
Ok(Response::new(authorization.into()))
173+
}
174+
175+
pub async fn delete_resoruce_authorization(
176+
context: &FeedbackFusionV1Context,
177+
request: Request<DeleteResourceAuthorizationRequest>,
178+
_user_context: UserContext,
179+
) -> Result<Response<()>> {
180+
let connection = context.connection();
181+
let data = request.into_inner();
182+
183+
database_request!(
184+
ResourceAuthorization::delete_by_column(connection, "id", data.id.as_str()).await,
185+
"Delete ResourceAuthorization by id"
186+
)?;
187+
188+
Ok(Response::new(()))
189+
}

0 commit comments

Comments
 (0)