diff --git a/Couchbase/ClusterOptions.php b/Couchbase/ClusterOptions.php index 29303420..0075ca2f 100644 --- a/Couchbase/ClusterOptions.php +++ b/Couchbase/ClusterOptions.php @@ -588,6 +588,8 @@ public function authenticatorHash(): string return hash("sha256", sprintf("--%s--%s--", $exported['username'], $exported['password'])); } elseif ($exported['type'] == 'certificate') { return hash("sha256", sprintf("--%s--%s--", $exported['certificatePath'], $exported['keyPath'])); + } elseif ($exported['type'] == 'jwt') { + return hash("sha256", sprintf("--%s--", $exported['token'])); } else { throw new InvalidArgumentException("unknown type of the authenticator: " . $exported['type']); } diff --git a/Couchbase/JwtAuthenticator.php b/Couchbase/JwtAuthenticator.php new file mode 100644 index 00000000..a5a59686 --- /dev/null +++ b/Couchbase/JwtAuthenticator.php @@ -0,0 +1,39 @@ +token = $token; + } + + public function export(): array + { + return [ + 'type' => 'jwt', + 'token' => $this->token, + ]; + } +} diff --git a/src/deps/couchbase-cxx-client b/src/deps/couchbase-cxx-client index a13bafb9..ffd23c50 160000 --- a/src/deps/couchbase-cxx-client +++ b/src/deps/couchbase-cxx-client @@ -1 +1 @@ -Subproject commit a13bafb98931c9a3aff2722eafbb5379267dedf0 +Subproject commit ffd23c50d8b05412890d9dd710bbfa67efdd70c8 diff --git a/src/wrapper/connection_handle.cxx b/src/wrapper/connection_handle.cxx index 18ee1888..eb7fcb8d 100644 --- a/src/wrapper/connection_handle.cxx +++ b/src/wrapper/connection_handle.cxx @@ -795,6 +795,21 @@ connection_handle::authenticator_set(const zval* auth) -> core_error_info } return {}; } + if (zend_binary_strcmp(Z_STRVAL_P(auth_type), Z_STRLEN_P(auth_type), ZEND_STRL("jwt")) == 0) { + const zval* token = zend_symtable_str_find(Z_ARRVAL_P(auth), ZEND_STRL("token")); + if (token == nullptr || Z_TYPE_P(token) != IS_STRING) { + return { errc::common::invalid_argument, + ERROR_LOCATION, + "expected jwt to be a string in the authenticator" }; + } + couchbase::jwt_authenticator jwt_auth{ Z_STRVAL_P(token) }; + + auto ctx = impl_->public_api().set_authenticator(jwt_auth); + if (ctx.ec()) { + return { ctx.ec(), ERROR_LOCATION, "unable to set authenticator", build_error_context(ctx) }; + } + return {}; + } return { errc::common::invalid_argument, ERROR_LOCATION, fmt::format("unknown type of the authenticator: {}", @@ -6439,6 +6454,26 @@ construct_cluster_options(zval* options) }, }; } + if (zend_binary_strcmp(Z_STRVAL_P(auth_type), Z_STRLEN_P(auth_type), ZEND_STRL("jwt")) == + 0) { + const zval* token = zend_symtable_str_find(Z_ARRVAL_P(auth), ZEND_STRL("token")); + if (token == nullptr || Z_TYPE_P(token) != IS_STRING) { + return { + { errc::common::invalid_argument, + ERROR_LOCATION, + "expected jwt token to be a string in the authenticator" }, + {}, + }; + } + return { + {}, + cluster_options{ + jwt_authenticator{ + Z_STRVAL_P(token), + }, + }, + }; + } return { { errc::common::invalid_argument, ERROR_LOCATION,