Unverified Commit fba2f986 authored by Nugine's avatar Nugine Committed by GitHub
Browse files

feat(s3s): split access control from auth (#183)

* refactor(s3s/auth): move credentials

* refactor(s3s/ops): add CallContext

* refactor(s3s): split access from auth

* feat(s3s/access): check op input
parent fa09f771
Loading
Loading
Loading
Loading

codegen/src/access.rs

0 → 100644
+56 −0
Original line number Diff line number Diff line
use crate::ops::Operations;

use codegen_writer::g;
use codegen_writer::glines;
use heck::ToSnakeCase;

pub fn codegen(ops: &Operations) {
    glines![
        "//! Auto generated by `codegen/src/access.rs`"
        "use super::S3AccessContext;"
        ""
        "use crate::dto::*;"
        "use crate::error::S3Result;"
        "use crate::request::S3Request;"
        ""
        "#[async_trait::async_trait]"
        "pub trait S3Access: Send + Sync + 'static {"
        ""
    ];

    glines![
        "/// Checks whether the current request has accesses to the resources."
        "///"
        "/// This method is called before deserializing the operation input."
        "///"
        "/// By default, this method rejects all anonymous requests"
        "/// and returns [`AccessDenied`](crate::S3ErrorCode::AccessDenied) error."
        "///"
        "/// An access control provider can override this method to implement custom logic."
        "///"
        "/// Common fields in the context:"
        "/// + [`cx.credentials()`](S3AccessContext::credentials)"
        "/// + [`cx.s3_path()`](S3AccessContext::s3_path)"
        "/// + [`cx.s3_op().name()`](crate::S3Operation::name)"
        "/// + [`cx.extensions_mut()`](S3AccessContext::extensions_mut)"
        "async fn check(&self, cx: &mut S3AccessContext<'_>) -> S3Result<()> {"
        "    super::default_check(cx)"
        "}"
    ];

    for op in ops.values() {
        let method_name = op.name.to_snake_case();
        let input = &op.input;

        g!("/// Checks whether the {} request has accesses to the resources.", op.name);
        g!("/// ");
        g!("/// This method returns `Ok(())` by default.");
        g!("async fn {method_name}(&self, _req: &mut S3Request<{input}>) -> S3Result<()> {{");
        g!("Ok(())");
        g!("}}");
        g!();
    }

    g!("}}");
    g!();
}
+7 −0
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@
mod rust;
mod smithy;

mod access;
mod dto;
mod error;
mod headers;
@@ -79,6 +80,12 @@ fn main() {
        codegen_writer::scoped(gen, || ops::codegen(&ops, &rust_types));
    }

    {
        let path = "crates/s3s/src/access/generated.rs";
        let gen = Codegen::create_file(path).unwrap();
        codegen_writer::scoped(gen, || access::codegen(&ops));
    }

    {
        let path = "crates/s3s-aws/src/conv/generated.rs";
        let gen = Codegen::create_file(path).unwrap();
+8 −4
Original line number Diff line number Diff line
@@ -142,10 +142,9 @@ pub fn codegen(ops: &Operations, rust_types: &RustTypes) {
        "use crate::http;"
        "use crate::error::*;"
        "use crate::path::S3Path;"
        "use crate::s3_trait::S3;"
        "use crate::ops::CallContext;"
        ""
        "use std::borrow::Cow;"
        "use std::sync::Arc;"
        ""
    ];

@@ -645,12 +644,17 @@ fn codegen_op_http_call(op: &Operation) {
    g!("}}");
    g!();

    g!("async fn call(&self, s3: &Arc<dyn S3>, req: &mut http::Request) -> S3Result<http::Response> {{");
    g!("async fn call(&self, ccx: &CallContext<'_>, req: &mut http::Request) -> S3Result<http::Response> {{");

    let method = op.name.to_snake_case();

    g!("let input = Self::deserialize_http(req)?;");
    g!("let s3_req = super::build_s3_request(input, req);");
    g!("let mut s3_req = super::build_s3_request(input, req);");
    g!("let s3 = ccx.s3;");

    g!("if let Some(access) = ccx.access {{");
    g!("    access.{method}(&mut s3_req).await?;");
    g!("}}");

    if op.name == "GetObject" {
        g!("let overrided_headers = super::get_object::extract_overrided_response_headers(&s3_req)?;");
+3 −4
Original line number Diff line number Diff line
use super::Credentials;

use crate::auth::Credentials;
use crate::path::S3Path;
use crate::S3Operation;

@@ -8,7 +7,7 @@ use hyper::HeaderMap;
use hyper::Method;
use hyper::Uri;

pub struct S3AuthContext<'a> {
pub struct S3AccessContext<'a> {
    pub(crate) credentials: Option<&'a Credentials>,
    pub(crate) s3_path: &'a S3Path,
    pub(crate) s3_op: &'a S3Operation,
@@ -20,7 +19,7 @@ pub struct S3AuthContext<'a> {
    pub(crate) extensions: &'a mut Extensions,
}

impl S3AuthContext<'_> {
impl S3AccessContext<'_> {
    /// Returns the credentials of current request.
    ///
    /// `None` means anonymous request.
+737 −0

File added.

Preview size limit exceeded, changes collapsed.

Loading