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

database class : editing security settings #13

Open
seductiveapps opened this issue Aug 9, 2018 · 8 comments
Open

database class : editing security settings #13

seductiveapps opened this issue Aug 9, 2018 · 8 comments

Comments

@seductiveapps
Copy link

i'm going to use CouchDB 2.2.0, Fauxton (/_utils) and the chrome debugger to build functionality into the php-couchdb database class that allows you to set security settings on databases, over the next few days/weeks.

the thing is, i read about how unit tests are required for a merge, and i could use some tips on how to quickly write the proper unit tests, and how to submit the changes..

actually, i'd rather not spend days reading manuals about this and that to become an expert on your particular source-code version control and unit testing code stacks..

can i simply submit the changed php-couchdb code to someone by email or adding them into this issue report even, along with example code that would get put into my https://gitlab.com/seductiveapps/seductiveapps/blob/master/seductiveapps/siteData/reInit.php ?
pretty please? :)

@seductiveapps
Copy link
Author

someone did the homework already : https://medium.com/@eiri/couchdb-authorization-in-nutshell-5ae697fe9a

all i have to do is build it into php-couchdb, and verify that it all works of course.
luckily my CMS is in it's toddler stage, so i don't mind running the tests over and over again :)

@seductiveapps
Copy link
Author

i'm stuck :(

public function getAdmins() {
    $endpoint = "/_node/couchdb@127.0.0.1/_config/admins";
    $verb = "GET";
    
    $response = $this->client->request($verb, $endpoint);
    return $response->getBody();        
}

returns

object(GuzzleHttp\Psr7\Stream)#211 (7) {
["stream":"GuzzleHttp\Psr7\Stream":private]=>
resource(36) of type (stream)
["size":"GuzzleHttp\Psr7\Stream":private]=>
NULL
["seekable":"GuzzleHttp\Psr7\Stream":private]=>
bool(true)
["readable":"GuzzleHttp\Psr7\Stream":private]=>
bool(true)
["writable":"GuzzleHttp\Psr7\Stream":private]=>
bool(true)
["uri":"GuzzleHttp\Psr7\Stream":private]=>
string(10) "php://temp"
["customMetadata":"GuzzleHttp\Psr7\Stream":private]=>
array(0) {
}
}

and the call to $client->getAllDbs() works just fine,
so does commandline :
rene@hummingbird:~/data1/htdocs/localhost$ curl -X GET http://admin:validpass@127.0.0.1:5984/_node/couchdb@127.0.0.1/_config/admins
{"admin":"-pbkdf2-038c8f1ce50359e72e90ee81810efd5a9ad06f6b,76a581df5845bd309e1ceffbf3fc9701,10"}

i'm no expert on GuzzleHTTP.. anyone got an idea why i can't get to the JSON listed as output for the curl commandline command?

@akrabat
Copy link

akrabat commented Aug 24, 2018

Cast the returned value from getAdmins() to a string and then json_decode it.

@seductiveapps
Copy link
Author

seductiveapps commented Sep 14, 2018

cool! sorry i didn't get back to you earlier, i was busy with other code tasks.

i'll get onto implementing low-level and basic functionality to assign permissions to specific users on databases, hopefully to be included in future versions of your library.

i'll try to follow your code conventions where-ever possible, and will provide an example usage script as well.

i have some other tasks on my desk as well, but i'll update this thread with a link to my copy of this library (i host it at github.com and will fork it into php-couchdb-sa for the necessary flexibility in developing these extensions), as soon as i have something worth-while. that could take a few weeks, but no more than 2 months i think.

@seductiveapps
Copy link
Author

seductiveapps commented Sep 19, 2018

i've run into another snag..

thread for php-couchdb upgrade : #13
source-codes of my fork of couchdb : https://gitlab.com/seductiveapps/seductiveapps/tree/master/seductiveapps/lib/vendor/ibm-watson-data-lab/php-couchdb
source-code for the script with which i use php-couchdb to (re-)initialize my couchdb from PHP (which allows me to do it from anywhere, and that's handy sometimes) : https://gitlab.com/seductiveapps/seductiveapps/blob/master/seductiveapps/siteData/reInit.php (starts at about line 190)

the two articles i found on couchdb permissions management :
(server-wide admins) : https://medium.com/@eiri/couchdb-authorization-in-nutshell-5ae697fe9a
(database permissions) : https://medium.com/@eiri/couchdb-authorization-in-a-database-58c8ee633c96

now, from the articles by @eiri, i can get and set the server-wide admins, i can enter users into the _users couchdb database, but i can't link these users to become the sole admin of a database in couchdb.

that error that is mentioned in the database permissions article,
i can't overcome it as described in the article...
here's the log:

CouchDB
adding a couchdb admin user "rene" :
string(84) "-pbkdf2-6d09918465d152e239bc57148d4817f0920a0f6b,ae5c5e8f805aae5bf48ff2d5e15bb845,10"
requesting a list of couchdb admin users:
array(2) {
["rene"]=>
string(84) "-pbkdf2-9998f2b619af596e3184ea6766363bcbcb9ea6a7,a5f756a7a92ae6b232838af87f2607e5,10"
["admin"]=>
string(84) "-pbkdf2-f309a6606c72f3a7977f427444bc0567379bcd3e,7a26b7ca5de19992686fdb9b2bd61e9f,10"
}
deleting any old databases entirely so they can be re-initialized
deleting db sa_tree
deleting db sa_tree__administrator
creating couchdb+seductiveapps user "Administrator"
creating couchdb+seductiveapps user "Guest"
creating and populating couchdb database sa_tree
creating and populating couchdb database sa_tree__administrator

Fatal error: Uncaught GuzzleHttp\Exception\ServerException: Server error: PUT http://admin:****@localhost:5984/sa_tree__administrator/_security resulted in a 500 Internal Server Error response:
{"error":"error","reason":"no_majority"}

in /home/rene/data1/htdocs/localhost/seductiveapps/lib/vendor/guzzlehttp/guzzle/src/Exception/RequestException.php:113
Stack trace:
#0 /home/rene/data1/htdocs/localhost/seductiveapps/lib/vendor/guzzlehttp/guzzle/src/Middleware.php(66): GuzzleHttp\Exception\RequestException::create(Object(GuzzleHttp\Psr7\Request), Object(GuzzleHttp\Psr7\Response))
#1 /home/rene/data1/htdocs/localhost/seductiveapps/lib/vendor/guzzlehttp/promises/src/Promise.php(203): GuzzleHttp\Middleware::GuzzleHttp{closure}(Object(GuzzleHttp\Psr7\Response))
#2 /home/rene/data1/htdocs/localhost/seductiveapps/lib/vendor/guzzlehttp/promises/src/Promise.php(156): GuzzleHttp\Promise\Promise::callHandler(1, Object(GuzzleHttp\Psr7\Response), Array)
#3 /home/rene/data1/htdocs/localhost/seductiveapps/lib/vendor/guzzlehttp/p in /home/rene/data1/htdocs/localhost/seductiveapps/lib/vendor/guzzlehttp/guzzle/src/Exception/RequestException.php on line 113

in the article, it's mentioned that this error message ("no_majority") is wrong (somebody ought to fix that imho),
but that one can set these _security settings by using the credentials of a couchdb admin.

that appears not to be the case, on my test system that is the latest ubuntu.com with the latest couchdb (installed per instructions found on couchdb.apache.org)

as you can see, it's already using a couchdb admin's credentials to do all of these calls.

i've spied on Fauxton (localhost:5984/_utils), and even using less JSON ([2] instead of [1]) like Fauxton does, gets me the same results in PHP.

[1] $json = '{ "admins" : { "names" : [], "roles" : [] }, "members" : { "names" : ["Administrator"], "roles" : [] } }';
[2] $json = '{ "members" : { "names" : ["Administrator"] } }';

this could be caused by couchdb, or by the PHP stack i use to get to couchdb.
so i'm filing it both with the couchdb mailinglist and that thread for the upgrade of php-couchdb (linked at the start of this thread),
so that hopefully someone can figure out what is causing this.
personally, i've run out of things to try. :(

@seductiveapps
Copy link
Author

did work from the command-line :
rene@crow:~$ curl -X PUT $db/sa_tree__administrator/_security -d @-
{
"admins": {
"names": [],
"roles": []
},
"members": {
"names": ["Administrator"],
"roles": []
}
}
{"ok":true}

i don't really have the time to dig into this right now, guzzle's code conventions are a bit cryptic to me.

@seductiveapps
Copy link
Author

fixed it :)

i was using the wrong parameter into one of the components used by php-couchdb.
very happy i was able to solve this one in just a few minutes of course.

i've uploaded my improved sources to gitlab. links are listed earlier in this thread.

@seductiveapps
Copy link
Author

UPDATE : CouchDB has been upgraded to version 3.0.0 now, and with that comes 1 vital change that all users of php-couchdb who desire real user management at their couchdb layer..

it's that adding security settings is now compulsory if you want to access a database at all as 'a normal user'.

i've found that the easiest way for me to add this into php-couchdb is for me to edit ibm-watson-data-lab/php-couchdb/src/PHPCouchDB/Server.php and change the function useDb a little..

before $exist = false, add :
if (isset($options['_security'])) { $security = $options['_security']; } else { $security = false; }
after if ($create_response->getStatusCode() == 201) {, add :
if ($security) $sec_response = $this->client->request('PUT', '/'.$db_name.'/_security', Array('json'=>$security));

now you can do, in your client code aimed into php-couchdb, the following :
` $security = Array(
'members'=>Array(
'users'=>Array('_admin',$_REQUEST['saRegistration_loginname'])
),
'admins'=>Array(
'users'=>Array('_admin',$_REQUEST['saRegistration_loginname'])
)
);

try {
$client = couchdb_client('_users'); 
$db = $client->useDb(["name" => '_users', 'create_if_not_exists' => true, '_security' => $security]);
    $db->create([
        'id' => 'org.couchdb.user:'.$_REQUEST['saRegistration_loginname'], 
        'name' => $_REQUEST['saRegistration_loginname'], 
        'password' => $_REQUEST['saRegistration_password_1'], 
        'realname' => $_REQUEST['saRegistration_realname'], 
        'email' => $_REQUEST['saRegistration_email'], 
        'registeringIP' => $_SERVER['REMOTE_ADDR'],
        'roles' => [ "guests" ], 
        'type' => "user"
    ]);
} catch (Exception $e) { 
    echo $e->getMessage();
}
try {
    $db = $client->useDb(["name" => $serverHTTPhost.'___sa_url_themes__user__'.$un, 'create_if_not_exists' => true, '_security' => $security]);
} catch (Exception $e) { 
    echo $e->getMessage();
}

`

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants