]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
rgw: RGWOp is responsible now for the authentication process.
authorRadoslaw Zarzynski <rzarzynski@mirantis.com>
Sat, 4 Feb 2017 14:49:26 +0000 (15:49 +0100)
committerRadoslaw Zarzynski <rzarzynski@mirantis.com>
Fri, 24 Mar 2017 15:55:43 +0000 (16:55 +0100)
Signed-off-by: Radoslaw Zarzynski <rzarzynski@mirantis.com>
src/rgw/rgw_op.h
src/rgw/rgw_process.cc

index 4d7c5af0b15e8565b81bf99a7dc98972ee7f026c..4eff628b0926cc2ffc64bda627ad825246aa2e1a 100644 (file)
@@ -45,7 +45,42 @@ using namespace std;
 using ceph::crypto::SHA1;
 
 struct req_state;
-class RGWHandler;
+class RGWOp;
+
+class RGWHandler {
+protected:
+  RGWRados* store;
+  struct req_state* s;
+
+  int do_init_permissions();
+  int do_read_permissions(RGWOp* op, bool only_bucket);
+
+public:
+  RGWHandler()
+    : store(nullptr),
+      s(nullptr) {
+  }
+  virtual ~RGWHandler();
+
+  virtual int init(RGWRados* store,
+                   struct req_state* _s,
+                   rgw::io::BasicClient* cio);
+
+  virtual int init_permissions(RGWOp*) {
+    return 0;
+  }
+
+  virtual int retarget(RGWOp* op, RGWOp** new_op) {
+    *new_op = op;
+    return 0;
+  }
+
+  virtual int read_permissions(RGWOp* op) = 0;
+  virtual int authorize() = 0;
+  virtual int postauth_init() = 0;
+  virtual int error_handler(int err_no, std::string* error_content);
+};
+
 
 /**
  * Provide the base class for all ops.
@@ -65,10 +100,15 @@ protected:
 
   virtual int init_quota();
 public:
-RGWOp() : s(nullptr), dialect_handler(nullptr), store(nullptr),
-    cors_exist(false), op_ret(0) {}
+  RGWOp()
+    : s(nullptr),
+      dialect_handler(nullptr),
+      store(nullptr),
+      cors_exist(false),
+      op_ret(0) {
+  }
 
-  virtual ~RGWOp() {}
+  virtual ~RGWOp() = default;
 
   int get_ret() const { return op_ret; }
 
@@ -90,6 +130,20 @@ RGWOp() : s(nullptr), dialect_handler(nullptr), store(nullptr),
 
   virtual int verify_params() { return 0; }
   virtual bool prefetch_data() { return false; }
+
+  /* Authenticate requester -- verify its identity.
+   *
+   * NOTE: typically the procedure is common across all operations of the same
+   * dialect (S3, Swift API). However, there are significant exceptions in
+   * both APIs: browser uploads, /info and OPTIONS handlers. All of them use
+   * different, specific authentication schema driving the need for per-op
+   * authentication. The alternative is to duplicate parts of the method-
+   * dispatch logic in RGWHandler::authorize() and pollute it with a lot
+   * of special cases. */
+  virtual int verify_requester() {
+    /* TODO(rzarzynski): rename RGWHandler::authorize to generic_authenticate. */
+    return dialect_handler->authorize();
+  }
   virtual int verify_permission() = 0;
   virtual int verify_op_mask();
   virtual void pre_exec() {}
@@ -1564,35 +1618,6 @@ public:
   uint32_t op_mask() override { return RGW_OP_TYPE_READ; }
 };
 
-class RGWHandler {
-protected:
-  RGWRados *store;
-  struct req_state *s;
-
-  int do_init_permissions();
-  int do_read_permissions(RGWOp *op, bool only_bucket);
-
-public:
-  RGWHandler() : store(NULL), s(NULL) {}
-  virtual ~RGWHandler();
-
-  virtual int init(RGWRados* store, struct req_state* _s, rgw::io::BasicClient* cio);
-
-  virtual int init_permissions(RGWOp *op) {
-    return 0;
-  }
-
-  virtual int retarget(RGWOp *op, RGWOp **new_op) {
-    *new_op = op;
-    return 0;
-  }
-
-  virtual int read_permissions(RGWOp *op) = 0;
-  virtual int authorize() = 0;
-  virtual int postauth_init() = 0;
-  virtual int error_handler(int err_no, string *error_content);
-};
-
 extern int rgw_build_bucket_policies(RGWRados* store, struct req_state* s);
 extern int rgw_build_object_policies(RGWRados *store, struct req_state *s,
                                    bool prefetch_data);
index ebc9276d82f4c287f61988cebf6b31434de850f0..efe247ed47280f76d68ecfbc40557e2404962e78 100644 (file)
@@ -168,8 +168,8 @@ int process_request(RGWRados* const store,
 
   s->op_type = op->get_type();
 
-  req->log(s, "authorizing");
-  ret = handler->authorize();
+  req->log(s, "verifying requester");
+  ret = op->verify_requester();
   if (ret < 0) {
     dout(10) << "failed to authorize request" << dendl;
     abort_early(s, NULL, ret, handler);