Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added Server.php hooks for creating and updating CouchDB users #12

Open
wants to merge 9 commits into
base: master
Choose a base branch
from
Open
110 changes: 103 additions & 7 deletions src/PHPCouchDB/Server.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,9 @@ class Server
*
* See also: \PHPCouchDB\Server:createFromURL()
*
* @param array $options Supply either a string "url" parameter OR a
* \GuzzleHttp\ClientInterface "client" parameter if more configuration
* is required
* @param array $options Supply either a string "url" parameter OR a
* \GuzzleHttp\ClientInterface "client" parameter if more configuration
* is required
* @throws \PHPCouchDB\Exception\ServerException if there's a problem
* with parsing arguments or connecting to the database
*/
Expand All @@ -43,13 +43,16 @@ public function __construct(array $options)
}

if (isset($options[self::OPTION_CLIENT])
&& $options[self::OPTION_CLIENT] instanceof \GuzzleHttp\ClientInterface) {
&& $options[self::OPTION_CLIENT] instanceof \GuzzleHttp\ClientInterface
) {
$client = $options[self::OPTION_CLIENT];
} elseif (isset($options[self::OPTION_URL])) {
// set a descriptive user agent
$user_agent = \GuzzleHttp\default_user_agent();
$client = new \GuzzleHttp\Client(["base_uri" => $options[self::OPTION_URL],
"headers" => ["User-Agent" => "PHPCouchDB/" . VERSION . " " . $user_agent]]);
$client = new \GuzzleHttp\Client(
["base_uri" => $options[self::OPTION_URL],
"headers" => ["User-Agent" => "PHPCouchDB/" . VERSION . " " . $user_agent]]
);
} else {
throw new Exception\ServerException(
'Failed to parse $options, array should contain either a url or a client'
Expand Down Expand Up @@ -113,7 +116,7 @@ public function getAllDbs() : array
/**
* Create and return a Database object to work with
*
* @param $options Supply the "name" (required) and an optional boolean
* @param $options Supply the "name" (required) and an optional boolean
* "create_if_not_exists" value (default is false)
* @return \CouchDB\Database represents the named database
* @throws \PHPCouchDB\Exception\ServerException if there's a problem
Expand Down Expand Up @@ -164,6 +167,99 @@ public function useDb($options) : Database
'Database doesn\'t exist, include "create_if_not_exists" parameter to create it'
);
}
/**
* Create a database user and return the revision of the user record (for later updating)
*
* @param $username the new username
* @param $password the password to setup for the user
* @param optional $roles if you want to specify the roles on the server for the user. defaults to []
* @return string revision string
* @throws \PHPCouchDB\Exception\ServerException if there's a problem
*/
public function createUser($username, $password, $roles = [])
{
$doc = [
'name' => $username,
'password' => $password,
'roles' => $roles,
'type' => 'user',
];
try {
$response = $this->client->request("PUT", "/_users/org.couchdb.user:" . $username, ['json' => $doc]);
if ($response->getStatusCode() == 201 && $response_data = json_decode($response->getBody(), true)) {
return $response_data['_rev'];
} else {
throw new Exception\ServerException(
'Problem creating user'
);
}
} catch (\GuzzleHttp\Exception\ClientException $e) {
return false;
}
}

/**
* Update a database user and return the revision of the user record (for further updating)
*
* @param $username the new username
* @param $password the new password
* @param optional $rev the revision of the current record (saves a query if you can specify this)
* @param optional $roles if you want to specify the roles on the server for the user. defaults to []
* @return string revision string
* @throws \PHPCouchDB\Exception\ServerException if there's a problem
*/
public function updateUser($username, $password, $rev = false, $roles = [])
{
$doc = [
'password' => $password,
'type' => 'user',
'name' => $username,
'roles' => $roles,
];
if (!$rev) {
try {
$response = $this->client->request("GET", "/_users/org.couchdb.user:" . $username);
if ($response->getStatusCode() == 200 && $response_data = json_decode($response->getBody(), true)) {
$rev = $response_data['_rev'];
} else {
if ($response->getStatusCode() == 404) {
throw new Exception\ServerException(
"Your connection doesn't have privileges to confirm the user, or the user does not exist"
);
}
throw new Exception\ServerException("Something went wrong: " . $response->getStatusCode());
}
} catch (\GuzzleHttp\Exception\ClientException $e) {
throw new Exception\ServerException(
'Could not retrieve the username provided'
);
}
}
try {
$response = $this->client->request(
"PUT",
"/_users/org.couchdb.user:" . $username,
[
'json' => $doc,
'headers' => [
'If-Match' => $rev
],
]
);
if ($response->getStatusCode() == 201 && $response_data = json_decode($response->getBody(), true)) {
return $response_data['_rev'];
} else {
if ($response->getStatusCode() == 409) {
throw new Exception\ServerException("Bad permissions");
}
throw new Exception\ServerException("Something went wrong: " . $response->getStatusCode());
}
} catch (\GuzzleHttp\Exception\ClientException $e) {
throw new Exception\ServerException(
"Failing Updating User: " . $e->getMessage() . "REV: $rev"
);
}
}

/**
* If you need to make a request that isn't supported by this library,
Expand Down