Skip to content

Commit

Permalink
test(api-keys): update e2e bats tests for receive scope
Browse files Browse the repository at this point in the history
bodymindarts committed Feb 22, 2024

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
1 parent 0021d65 commit 1de1a0a
Showing 6 changed files with 82 additions and 24 deletions.
70 changes: 69 additions & 1 deletion bats/core/api-keys/api-keys.bats
Original file line number Diff line number Diff line change
@@ -86,7 +86,7 @@ new_key_name() {
@test "api-keys: can create read-only" {
key_name="$(new_key_name)"

variables="{\"input\":{\"name\":\"${key_name}\",\"readOnly\": true}}"
variables="{\"input\":{\"name\":\"${key_name}\",\"scopes\": [\"READ\"]}}"

exec_graphql 'alice' 'api-key-create' "$variables"
key="$(graphql_output '.data.apiKeyCreate.apiKey')"
@@ -123,3 +123,71 @@ new_key_name() {
errors="$(graphql_output '.errors | length')"
[[ "${errors}" = "0" ]] || exit 1
}

@test "api-keys: receive can create on-chain address" {
key_name="$(new_key_name)"

variables="{\"input\":{\"name\":\"${key_name}\",\"scopes\": [\"RECEIVE\"]}}"

exec_graphql 'alice' 'api-key-create' "$variables"
key="$(graphql_output '.data.apiKeyCreate.apiKey')"
secret="$(graphql_output '.data.apiKeyCreate.apiKeySecret')"
cache_value "api-key-secret" "$secret"

readOnly=$(echo "$key" | jq -r '.readOnly')
[[ "${readOnly}" = "false" ]] || exit 1

key_id=$(echo "$key" | jq -r '.id')
cache_value "api-key-id" "$key_id"

btc_wallet_name="alice.btc_wallet_id"
variables=$(
jq -n \
--arg wallet_id "$(read_value $btc_wallet_name)" \
'{input: {walletId: $wallet_id}}'
)
exec_graphql 'api-key-secret' 'on-chain-address-create' "$variables"

errors="$(graphql_output '.errors | length')"
[[ "${errors}" = "0" ]] || exit 1
}

@test "api-keys: receive key cannot mutate or read" {
key_name="$(new_key_name)"

variables="{\"input\":{\"name\":\"${key_name}\"}}"
exec_graphql 'api-key-secret' 'api-key-create' "$variables"
errors="$(graphql_output '.errors | length')"
[[ "${errors}" = "1" ]] || exit 1

variables="{\"input\":{\"currency\":\"USD\"}}"
exec_graphql 'api-key-secret' 'update-display-currency' "$variables"
errors="$(graphql_output '.errors | length')"
[[ "${errors}" = "1" ]] || exit 1

exec_graphql 'api-key-secret' 'api-keys'

name="$(graphql_output '.errors | length')"
[[ "${errors}" = "1" ]] || exit 1
}

@test "api-keys: receive + read can read" {
key_name="$(new_key_name)"

variables="{\"input\":{\"name\":\"${key_name}\",\"scopes\": [\"READ\", \"RECEIVE\"]}}"

exec_graphql 'alice' 'api-key-create' "$variables"
key="$(graphql_output '.data.apiKeyCreate.apiKey')"
secret="$(graphql_output '.data.apiKeyCreate.apiKeySecret')"
cache_value "api-key-secret" "$secret"

readOnly=$(echo "$key" | jq -r '.readOnly')
[[ "${readOnly}" = "false" ]] || exit 1

key_id=$(echo "$key" | jq -r '.id')
cache_value "api-key-id" "$key_id"

exec_graphql 'api-key-secret' 'api-keys'
name="$(graphql_output '.data.me.apiKeys[-1].name')"
[[ "${name}" = "${key_name}" ]] || exit 1
}
1 change: 1 addition & 0 deletions bats/gql/api-key-create.gql
Original file line number Diff line number Diff line change
@@ -6,6 +6,7 @@ mutation apiKeyCreate($input: ApiKeyCreateInput!) {
createdAt
expiresAt
readOnly
scopes
}
apiKeySecret
}
1 change: 1 addition & 0 deletions bats/gql/api-keys.gql
Original file line number Diff line number Diff line change
@@ -10,6 +10,7 @@ query apiKeys {
createdAt
expiresAt
readOnly
scopes
}
}
}
6 changes: 1 addition & 5 deletions core/api-keys/src/scope.rs
Original file line number Diff line number Diff line change
@@ -32,14 +32,10 @@ impl std::str::FromStr for Scope {
}
}

pub fn read_only_scope() -> String {
READ_SCOPE.to_string()
}

pub fn is_read_only(scope: &Vec<Scope>) -> bool {
scope.len() == 1 && scope[0] == Scope::Read
}

pub fn can_write(scope: &String) -> bool {
scope.as_str().split(' ').any(|s| s == WRITE_SCOPE)
scope.as_str().split(' ').any(|s| s == WRITE_SCOPE) || scope.is_empty()
}
10 changes: 5 additions & 5 deletions core/notifications/src/graphql/schema.rs
Original file line number Diff line number Diff line change
@@ -5,7 +5,7 @@ use crate::{app::NotificationsApp, primitives::*};

pub struct AuthSubject {
pub id: String,
pub read_only: bool,
pub can_write: bool,
}

pub struct Query;
@@ -78,7 +78,7 @@ impl Mutation {
input: UserDisableNotificationChannelInput,
) -> async_graphql::Result<UserUpdateNotificationSettingsPayload> {
let subject = ctx.data::<AuthSubject>()?;
if subject.read_only {
if !subject.can_write {
return Err("Permission denied".into());
}
let app = ctx.data_unchecked::<NotificationsApp>();
@@ -96,7 +96,7 @@ impl Mutation {
input: UserEnableNotificationChannelInput,
) -> async_graphql::Result<UserUpdateNotificationSettingsPayload> {
let subject = ctx.data::<AuthSubject>()?;
if subject.read_only {
if !subject.can_write {
return Err("Permission denied".into());
}
let app = ctx.data_unchecked::<NotificationsApp>();
@@ -116,7 +116,7 @@ impl Mutation {
input: UserDisableNotificationCategoryInput,
) -> async_graphql::Result<UserUpdateNotificationSettingsPayload> {
let subject = ctx.data::<AuthSubject>()?;
if subject.read_only {
if !subject.can_write {
return Err("Permission denied".into());
}
let app = ctx.data_unchecked::<NotificationsApp>();
@@ -140,7 +140,7 @@ impl Mutation {
input: UserEnableNotificationCategoryInput,
) -> async_graphql::Result<UserUpdateNotificationSettingsPayload> {
let subject = ctx.data::<AuthSubject>()?;
if subject.read_only {
if !subject.can_write {
return Err("Permission denied".into());
}
let app = ctx.data_unchecked::<NotificationsApp>();
18 changes: 5 additions & 13 deletions core/notifications/src/graphql/server/mod.rs
Original file line number Diff line number Diff line change
@@ -55,11 +55,11 @@ pub async fn graphql_handler(
req: GraphQLRequest,
) -> GraphQLResponse {
let req = req.into_inner();
let read_only = is_read_only(&jwt_claims.scope);
let can_write = can_write(&jwt_claims.scope);
schema
.execute(req.data(graphql::AuthSubject {
id: jwt_claims.sub,
read_only,
can_write,
}))
.await
.into()
@@ -70,17 +70,9 @@ async fn playground() -> impl axum::response::IntoResponse {
async_graphql::http::GraphQLPlaygroundConfig::new("/graphql"),
))
}
pub const READ_SCOPE: &str = "read";
pub const WRITE_SCOPE: &str = "write";

pub fn read_only_scope() -> String {
READ_SCOPE.to_string()
}

pub fn read_write_scope() -> String {
format!("{READ_SCOPE} {WRITE_SCOPE}")
}
pub const WRITE_SCOPE: &str = "write";

pub fn is_read_only(scope: &String) -> bool {
!(scope.as_str().split(' ').any(|s| s == WRITE_SCOPE) || scope.is_empty())
pub fn can_write(scope: &String) -> bool {
scope.as_str().split(' ').any(|s| s == WRITE_SCOPE) || scope.is_empty()
}

0 comments on commit 1de1a0a

Please sign in to comment.