Skip to content
This repository has been archived by the owner on Aug 16, 2023. It is now read-only.

Commit

Permalink
[ULMS-1885] Check event data size before creation
Browse files Browse the repository at this point in the history
Signed-off-by: Mikhail Grachev <work@mgrachev.com>

# Conflicts:
#	chart/templates/configmap.yaml
#	chart/values.yaml
  • Loading branch information
mgrachev committed Jun 14, 2022
1 parent 8d4f693 commit fac83a9
Show file tree
Hide file tree
Showing 9 changed files with 124 additions and 6 deletions.
26 changes: 26 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
name: Release
on:
push:
tags:
- '*.*.*'

jobs:
release:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
with:
ref: ${{ github.event.inputs.version }}
fetch-depth: 0
- uses: satackey/action-docker-layer-caching@46d2c640b1d8ef50d185452ad6fb324e6bd1d052
continue-on-error: true
- name: Build and push docker image
run: |
curl -fsSLo skaffold "https://storage.googleapis.com/skaffold/releases/v1.24.1/skaffold-$(uname | tr '[:upper:]' '[:lower:]')-amd64"
chmod +x skaffold
echo ${DOCKER_PASSWORD} | docker login -u ${DOCKER_USERNAME} --password-stdin
./skaffold build --file-output=$HOME/tags.json
env:
GITHUB_TOKEN: ${{ secrets._GITHUB_TOKEN }}
DOCKER_PASSWORD: ${{ secrets.DOCKER_PASSWORD }}
DOCKER_USERNAME: ${{ secrets.DOCKER_USERNAME }}
3 changes: 3 additions & 0 deletions App.toml.sample
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@ id = "event.dev.svc.example.org"
agent_label = "alpha"
broker_id = "mqtt-gateway.dev.svc.example.org"

[constraint]
payload_size = 102400 # 100KB

[id_token]
algorithm = "ES256"
key = "data/keys/svc.private_key.p8.der.sample"
Expand Down
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
authors = ["Timofey Martynov <t.martinov@netology-group.ru>"]
edition = "2018"
edition = "2021"
name = "event"
version = "0.2.52"

Expand Down
2 changes: 1 addition & 1 deletion docker/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
## -----------------------------------------------------------------------------
## Build
## -----------------------------------------------------------------------------
FROM rust:1.55.0-slim-buster as build-stage
FROM rust:1.59.0-slim-buster as build-stage

RUN apt update && apt install -y --no-install-recommends \
pkg-config \
Expand Down
2 changes: 1 addition & 1 deletion docker/migration.dockerfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
FROM rust:1.55.0-slim-buster
FROM rust:1.59.0-slim-buster

RUN apt update && apt install -y --no-install-recommends \
pkg-config \
Expand Down
56 changes: 56 additions & 0 deletions src/app/endpoint/event.rs
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,11 @@ impl RequestHandler for CreateHandler {
removed,
..
} = payload;

if data.to_string().len() >= context.config().constraint.payload_size {
return Err(anyhow!("Payload size exceeded")).error(AppErrorKind::PayloadSizeExceeded);
}

let event = if payload.is_persistent {
// Insert event into the DB.
let mut query = db::event::InsertQuery::new(
Expand Down Expand Up @@ -520,6 +525,57 @@ mod tests {
assert_eq!(event.data(), &json!({ "text": "hello" }));
}

#[tokio::test]
async fn exceed_payload_size() {
let db = TestDb::new().await;
let agent = TestAgent::new("web", "user123", USR_AUDIENCE);

let room = {
// Create room and put the agent online.
let mut conn = db.get_conn().await;
let room = shared_helpers::insert_room(&mut conn).await;
shared_helpers::insert_agent(&mut conn, agent.agent_id(), room.id()).await;
room
};

// Allow agent to create events of type `message` in the room.
let mut authz = TestAuthz::new();
let room_id = room.id().to_string();
let account_id = agent.account_id().to_string();

let object = vec![
"rooms",
&room_id,
"pinned",
"message",
"authors",
&account_id,
];

authz.allow(agent.account_id(), object, "create");

// Make event.create request.
let mut context = TestContext::new_with_payload_size(db, authz, 10);

let payload = CreateRequest {
room_id: room.id(),
payload: CreatePayload {
kind: String::from("message"),
set: Some(String::from("messages")),
label: Some(String::from("message-1")),
attribute: Some(String::from("pinned")),
data: json!({ "text": "hello" }),
is_claim: false,
is_persistent: true,
removed: false,
},
};

handle_request::<CreateHandler>(&mut context, &agent, payload)
.await
.expect_err("Event creation succeeded");
}

#[tokio::test]
async fn create_locked_event_as_user() {
let db = TestDb::new().await;
Expand Down
7 changes: 7 additions & 0 deletions src/app/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ pub enum ErrorKind {
TransientEventCreationFailed,
UnknownMethod,
WhiteboardAccessUpdateNotChecked,
PayloadSizeExceeded,
}

impl ErrorKind {
Expand Down Expand Up @@ -234,6 +235,12 @@ impl From<ErrorKind> for ErrorKindProperties {
title: "Whiteboard access change in room with universal whiteboard access (which doesnt make sense)",
is_notify_sentry: false,
},
ErrorKind::PayloadSizeExceeded => ErrorKindProperties {
status: ResponseStatus::UNPROCESSABLE_ENTITY,
kind: "payload_size_exceeded",
title: "Payload size exceeded",
is_notify_sentry: false,
},
}
}
}
Expand Down
6 changes: 6 additions & 0 deletions src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ pub struct Config {
pub vacuum: VacuumConfig,
#[serde(default)]
pub http_broker_client: Option<HttpBrokerClientConfig>,
pub constraint: Constraint,
}

impl Config {
Expand All @@ -39,6 +40,11 @@ impl Config {
}
}

#[derive(Clone, Debug, Deserialize)]
pub struct Constraint {
pub payload_size: usize,
}

#[derive(Clone, Debug, Deserialize)]
pub struct MetricsConfig {
pub http: MetricsHttpConfig,
Expand Down
26 changes: 23 additions & 3 deletions src/test_helpers/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ use super::SVC_AUDIENCE;

///////////////////////////////////////////////////////////////////////////////

fn build_config() -> Config {
fn build_config(payload_size: Option<usize>) -> Config {
let id = format!("event.{}", SVC_AUDIENCE);
let broker_id = format!("mqtt-gateway.{}", SVC_AUDIENCE);

Expand All @@ -34,6 +34,9 @@ fn build_config() -> Config {
"key": "data/keys/svc.private_key.p8.der.sample",
},
"http_addr": "0.0.0.0:8080",
"constraint": {
"payload_size": payload_size.unwrap_or(102400),
},
"authn": {},
"authz": {},
"mqtt": {
Expand All @@ -60,7 +63,24 @@ pub(crate) struct TestContext {

impl TestContext {
pub(crate) fn new(db: TestDb, authz: TestAuthz) -> Self {
let config = build_config();
let config = build_config(None);
let agent_id = AgentId::new(&config.agent_label, config.id.clone());

let metrics = Arc::new(Metrics::new(&Registry::new()).unwrap());
Self {
config,
authz: Authz::new(authz.into(), metrics.clone()),
db,
agent_id,
metrics,
start_timestamp: Utc::now(),
s3_client: None,
broker_client: Arc::new(MockBrokerClient::new()),
}
}

pub(crate) fn new_with_payload_size(db: TestDb, authz: TestAuthz, payload_size: usize) -> Self {
let config = build_config(Some(payload_size));
let agent_id = AgentId::new(&config.agent_label, config.id.clone());

let metrics = Arc::new(Metrics::new(&Registry::new()).unwrap());
Expand All @@ -77,7 +97,7 @@ impl TestContext {
}

pub(crate) fn new_with_ban(db: TestDb, authz: DbBanTestAuthz) -> Self {
let config = build_config();
let config = build_config(None);
let agent_id = AgentId::new(&config.agent_label, config.id.clone());

let metrics = Arc::new(Metrics::new(&Registry::new()).unwrap());
Expand Down

0 comments on commit fac83a9

Please sign in to comment.