]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
rgw: extend rgw::auth::Completer to handle commiting modifications to req_state.
authorRadoslaw Zarzynski <rzarzynski@mirantis.com>
Wed, 19 Apr 2017 17:38:25 +0000 (19:38 +0200)
committerRadoslaw Zarzynski <rzarzynski@mirantis.com>
Wed, 7 Jun 2017 10:43:17 +0000 (12:43 +0200)
Signed-off-by: Radoslaw Zarzynski <rzarzynski@mirantis.com>
src/rgw/rgw_auth.h
src/rgw/rgw_common.h
src/rgw/rgw_rest_s3.cc
src/rgw/rgw_rest_swift.cc

index 819a338038546d288d983b1445c4aff4fc19286c..e38baf31dc00e45acca083e736512b4505fa2b7d 100644 (file)
@@ -103,8 +103,8 @@ public:
   virtual void load_acct_info(RGWUserInfo& user_info) const = 0; /* out */
 
   /* Apply any changes to request state. This method will be most useful for
-   * TempURL of Swift API or AWSv4. */
-  virtual void modify_request_state(req_state * s) const {}      /* in/out */
+   * TempURL of Swift API. */
+  virtual void modify_request_state(req_state* s) const {}      /* in/out */
 };
 
 
@@ -126,7 +126,10 @@ public:
  *  E. execute-commit - commit the modifications from point C. */
 class Completer {
 public:
-  typedef std::unique_ptr<Completer> cmplptr_t;
+  /* It's expected that Completers would tend to implement many interfaces
+   * and be used not only in req_state::auth::completer. Ref counting their
+   * instances woild be helpful. */
+  typedef std::shared_ptr<Completer> cmplptr_t;
 
   virtual ~Completer() = default;
 
@@ -134,6 +137,10 @@ public:
    * the completion succeeded. On error throws rgw::auth::Exception storing
    * the reason. */
   virtual bool complete() = 0;
+
+  /* Apply any changes to request state. The initial use case was injecting
+   * the AWSv4 filter over rgw::io::RestfulClient in req_state. */
+  virtual void modify_request_state(req_state* s) = 0;     /* in/out */
 };
 
 
index a0de9b33a2c96d86ea578b3cde12abd8cce206c9..c36f377bd51b3a48a823eed31fce439aae8b0c83 100644 (file)
@@ -1776,7 +1776,7 @@ struct req_state {
      * through a well-defined interface. For more details, see rgw_auth.h. */
     std::unique_ptr<rgw::auth::Identity> identity;
 
-    std::unique_ptr<rgw::auth::Completer> completer;
+    std::shared_ptr<rgw::auth::Completer> completer;
 
     /* A container for credentials of the S3's browser upload. It's necessary
      * because: 1) the ::authenticate() method of auth engines and strategies
index e1fc2a4d6f89f76c07ebb2146e3ff05ff3f9cd16..c7d0a624360670eaa852ed947958c72373f945da 100644 (file)
@@ -1780,11 +1780,21 @@ int RGWPostObj_ObjStore_S3::get_policy()
 
         try {
           auto applier = result.get_applier();
+          auto completer = result.get_completer();
 
           applier->load_acct_info(*s->user);
           s->perm_mask = applier->get_perm_mask();
+
+          /* This is the signle place where we pass req_state as a pointer
+           * to non-const and thus its modification is allowed. In the time
+           * of writing only RGWTempURLEngine needed that feature. */
           applier->modify_request_state(s);
+          if (completer) {
+            completer->modify_request_state(s);
+          }
+
           s->auth.identity = std::move(applier);
+          s->auth.completer = std::move(completer);
 
           s->owner.set_id(s->user->user_id);
           s->owner.set_name(s->user->display_name);
@@ -3715,13 +3725,21 @@ int RGW_Auth_S3::authorize_v2(RGWRados* const store,
     }
     try {
       auto applier = result.get_applier();
+      auto completer = result.get_completer();
 
       applier->load_acct_info(*s->user);
       s->perm_mask = applier->get_perm_mask();
+
+      /* This is the signle place where we pass req_state as a pointer
+       * to non-const and thus its modification is allowed. In the time
+       * of writing only RGWTempURLEngine needed that feature. */
       applier->modify_request_state(s);
+      if (completer) {
+        completer->modify_request_state(s);
+      }
 
       s->auth.identity = std::move(applier);
-      s->auth.completer = result.get_completer();
+      s->auth.completer = std::move(completer);
 
       /* Populate the owner info. */
       s->owner.set_id(s->user->user_id);
index f745e8d4913e02fd4a3b799ce59567eef7c25463..9c7720be8bc768e946ef9be3bcefe27fc719db89 100644 (file)
@@ -2489,6 +2489,7 @@ int RGWHandler_REST_SWIFT::authorize()
 
     try {
       rgw::auth::IdentityApplier::aplptr_t applier = result.get_applier();
+      rgw::auth::Completer::cmplptr_t completer = result.get_completer();
 
       /* Account used by a given RGWOp is decoupled from identity employed
        * in the authorization phase (RGWOp::verify_permissions). */
@@ -2499,9 +2500,12 @@ int RGWHandler_REST_SWIFT::authorize()
        * to non-const and thus its modification is allowed. In the time
        * of writing only RGWTempURLEngine needed that feature. */
       applier->modify_request_state(s);
+      if (completer) {
+        completer->modify_request_state(s);
+      }
 
       s->auth.identity = std::move(applier);
-      s->auth.completer = std::move(result.get_completer());
+      s->auth.completer = std::move(completer);
 
       return 0;
     } catch (int err) {