diff --git a/examples/pycaosdb.ini b/examples/pycaosdb.ini index 625a3878341265637e6669291ba9d3c517906534..b5d7defc9d9125d300a12c4b1cb0b1015c073b73 100644 --- a/examples/pycaosdb.ini +++ b/examples/pycaosdb.ini @@ -4,34 +4,61 @@ # - the location given in the env variable PYCAOSDBINI [Connection] -url=https://demo.indiscale.com/ - -## For local installations, enter your server address and SSL certificate here. +# URL of the CaosDB server +# url=https://demo.indiscale.com/ +# For local installations this typically is # url=https://localhost:10443/ -# cacert=/path/to/caosdb.ca.pem - -## If this option is set, the SSL certificate will be ignored. Use with care! -# ssl_insecure=1 -username=admin +# User name used for authentication with the server +# username=admin -## The password input method can be chosen with the `password_method` setting, -## which by default is set to `plain`. -## -## DEFAULT: the password method is `plain`, with this method the password must -## be saved as plain text. +# The password input method defines how the password is supplied that is used +# for authentication with the server. +# +# DEFAULT: `input` +# The username is optional in this case. The password is entered directly by the user. +# password_method=input +# +# OR: `plain` +# This implies that the password must # be saved as plain text in a +# configuration under the 'password' key. # password_method=plain # password=caosdb +# +# OR `pass` +# The password is retrieved from the "pass" password manager +# This password manager uses identifiers to distinguish passwords. Supply this +# identifier under the key 'password_identifier'. +# password_method=pass +# password_identifier=caosdb_password +# +# OR: `keyring` +# Using the system keyring/wallet (macOS, GNOME, KDE, Windows) +# requires installation of the keyring python package (pip install keyring). +# password_method=keyring -## OR: `input`: username is optional, password is entered directly by the user. -## The default password for the demo server is `caosdb`. -password_method=input +# Using an authentication token to connect with the server. This setting is +# not recommended for users. +# auth_token=TOKEN -## OR: `pass`: password is retrieved from the "pass" password manager -# password_method=pass -# password_identifier=... +# If the server's SSL certificate cannot be validated by your installed +# certificates (default or installed by your admins), you may also need to +# supply the matching key (pem file): +# cacert=/path/to/caosdb.ca.pem -## OR: `keyring`: using the system keyring/wallet (macOS, GNOME, KDE, Windows) -## requires installation of the keyring python package: -## pip install keyring -# password_method=keyring +# If this option is set, the SSL certificate of the server will not be +# validated. This has the potential of a man-in-the-middle attack. Use with care! +# ssl_insecure=True + +# You may define the ssl version to be used. It has to be the name of the +# corresponding attribute in the Python ssl module. +# ssl_version=PROTOCOL_TLS + +# You can define a socket proxy to be used. +# This is for the case that the server sits behind a firewall which is being +# tunnelled with a socket proxy (SOCKS4 or SOCKS5) (e.g. via ssh's -D option or +# a dedicated proxy server). +# socket_proxy=localhost:12345 + +# This option is used internally and for testing. Do not override. +# implementation=_DefaultCaosDBServerConnection diff --git a/src/caosdb/connection/connection.py b/src/caosdb/connection/connection.py index 65c8413c251ad42f44b77e37ac34a26b1c329c0d..703897d62a40a820a6ff578869a862f6c7c4c019 100644 --- a/src/caosdb/connection/connection.py +++ b/src/caosdb/connection/connection.py @@ -246,7 +246,7 @@ def _make_conf(*conf): _DEFAULT_CONF = { - "password_method": "plain", + "password_method": "input", "implementation": _DefaultCaosDBServerConnection, "timeout": 210, "cacert": resource_filename("caosdb", 'cert/indiscale.ca.crt') diff --git a/src/doc/configuration.md b/src/doc/configuration.md index bf900f0cd6259fa35e46e86e8457c8c42874852a..4acfb323212f704b49f2eefcfab14e6f84c44d7a 100644 --- a/src/doc/configuration.md +++ b/src/doc/configuration.md @@ -1,8 +1,5 @@ # Configuration of pycaosdb # - -The behavior of pycaosdb is defined via the [configuration](https://caosdb.gitlab.io/caosdb-pylib/_apidoc/caosdb.html#module-caosdb.configuration) module, initial values are taken from -the configuration files. - +The behavior of pycaosdb is defined via a configuration that is provided using configuration files. Pycaosdb tries to read from the inifile specified in the environment variable `PYCAOSDBINI` or alternatively in `~/.pycaosdb.ini` upon import. After that, the ini file `pycaosdb.ini` in the current working directory will be read additionally, if it exists. @@ -14,9 +11,9 @@ can be changed by setting `password_method`: * with `password_method=input` password (and possibly user) will be queried on demand (**default**) * use the password manager [pass](https://www.passwordstore.org) by using `pass` as value, see also the [ArchWiki - entry](https://wiki.archlinux.org/index.php/Pass#Basic_usage). This also requires ```password_identifier``` which refers to the identifier within pass + entry](https://wiki.archlinux.org/index.php/Pass#Basic_usage). This also requires `password_identifier` which refers to the identifier within pass for the desired password. -* install the python package [keyring](https://pypi.org/project/keyring), to use the system keychain/wallet (macOS, GNOME, KDE, +* install the python package [keyring](https://pypi.org/project/keyring), to use the system keyring/wallet (macOS, GNOME, KDE, Windows). The password will be queried on first usage. * with `password_method=plain` (**strongly discouraged**) @@ -50,4 +47,8 @@ cacert=/path/to/caosdb.ca.pem `debug=0` ensures that debug information is **not** printed to the terminal every time you interact with CaosDB which makes the experience much less verbose. Set it to 1 or 2 in case you want to help debugging (which I hope will not be necessary for this tutorial) or if you want to learn more about -the internals of the procotol +the internals of the protocol. + +A complete list of options can be found in the +[pycaosdb.ini file](https://gitlab.com/caosdb/caosdb-pylib/-/blob/master/examples/pycaosdb.ini) in +the examples folder of the source code. diff --git a/tox.ini b/tox.ini index f9776382db0770e3efe1b2711f50bb5b3adde1ec..94c2dc8affb280d3e7f6cff4536636432c9f7749 100644 --- a/tox.ini +++ b/tox.ini @@ -1,5 +1,5 @@ [tox] -envlist=py36, py37, py38 +envlist=py36, py37, py38, py39 skip_missing_interpreters = true [testenv] diff --git a/unittests/test_authentication_plain.py b/unittests/test_authentication_plain.py index 26c57e953f28a2a0ab80e35026c27ff74f18d370..10cbc418df8bd81c81568a4df0cf1e8a4ac498f8 100644 --- a/unittests/test_authentication_plain.py +++ b/unittests/test_authentication_plain.py @@ -27,11 +27,18 @@ Unit tests for the modul caosdb.connection.authentication.plain. """ from __future__ import unicode_literals -from pytest import raises + from caosdb.connection.authentication.plain import PlainTextCredentialsProvider +from pytest import raises def test_subclass_configure(): + # TODO I do not see the meaning of this test. + # It only tests, that the call of the super version of configure sets the + # password property. And that due to the subclassing no longer a password + # argument can be provided. + # Suggestion: Either remove this test or state in what context this test + # is meanigful. """Test the correct passing of the password argument.""" class SubClassOf(PlainTextCredentialsProvider): """A simple subclass of PlainTextCredentialsProvider.""" @@ -51,8 +58,8 @@ def test_subclass_configure(): with raises(TypeError) as exc_info: instance.configure(password="OH NO!") - assert exc_info.value.args[0] == ("configure() got multiple values for " - "keyword argument 'password'") + assert exc_info.value.args[0].endswith("configure() got multiple values for " + "keyword argument 'password'") def test_plain_has_logger(): diff --git a/unittests/test_concrete_property.py b/unittests/test_concrete_property.py index b806098732c8a77a4913bbda0f8b2b8ebdc4a68c..0e5c28534c7ac404b829df575225f42e908adb01 100644 --- a/unittests/test_concrete_property.py +++ b/unittests/test_concrete_property.py @@ -24,17 +24,19 @@ """Tests for the _ConcreteProperty class.""" -# pylint: disable=missing-docstring -from nose.tools import (assert_is_not_none as there, assert_true as tru, - assert_equal as eq) -from caosdb.common.models import _ConcreteProperty from caosdb import configure_connection +from caosdb.common.models import _ConcreteProperty from caosdb.connection.mockup import MockUpServerConnection +# pylint: disable=missing-docstring +from nose.tools import assert_equal as eq +from nose.tools import assert_is_not_none as there +from nose.tools import assert_true as tru def setup_module(): there(_ConcreteProperty) configure_connection(url="unittests", username="testuser", + password_method="plain", password="testpassword", timeout=200, implementation=MockUpServerConnection) diff --git a/unittests/test_connection.py b/unittests/test_connection.py index 5c1518c65b51087ace514ca26fa77eff53130c73..1dfd1fce730d4d4ba627eb4c27830b0c5156fb29 100644 --- a/unittests/test_connection.py +++ b/unittests/test_connection.py @@ -23,23 +23,27 @@ # """Test caosdb.connection.""" # pylint: disable=missing-docstring -from __future__ import unicode_literals, print_function -from builtins import bytes, str # pylint: disable=redefined-builtin +from __future__ import print_function, unicode_literals + import re -from pytest import raises -from nose.tools import (assert_equal as eq, assert_raises as raiz, assert_true - as tru, assert_is_not_none as there, assert_false as - falz) -from caosdb.exceptions import ConfigurationException, LoginFailedException -from caosdb.connection.utils import urlencode, make_uri_path, quote -from caosdb.connection.connection import ( - configure_connection, CaosDBServerConnection, - _DefaultCaosDBServerConnection) -from caosdb.connection.mockup import (MockUpServerConnection, MockUpResponse, - _request_log_message) -from caosdb.configuration import get_config, _reset_config -from caosdb.connection.authentication.interface import CredentialsAuthenticator +from builtins import bytes, str # pylint: disable=redefined-builtin + from caosdb import execute_query +from caosdb.configuration import _reset_config, get_config +from caosdb.connection.authentication.interface import CredentialsAuthenticator +from caosdb.connection.connection import (CaosDBServerConnection, + _DefaultCaosDBServerConnection, + configure_connection) +from caosdb.connection.mockup import (MockUpResponse, MockUpServerConnection, + _request_log_message) +from caosdb.connection.utils import make_uri_path, quote, urlencode +from caosdb.exceptions import ConfigurationException, LoginFailedException +from nose.tools import assert_equal as eq +from nose.tools import assert_false as falz +from nose.tools import assert_is_not_none as there +from nose.tools import assert_raises as raiz +from nose.tools import assert_true as tru +from pytest import raises def setup_module(): @@ -96,6 +100,7 @@ def test_configure_connection(): get_config().add_section("Connection") get_config().set("Connection", "url", "https://host.de") get_config().set("Connection", "username", "test_username") + get_config().set("Connection", "password_method", "plain") get_config().set("Connection", "password", "test_password") get_config().set("Connection", "timeout", "200") @@ -152,6 +157,7 @@ def test_init_response(): response = MockUpResponse( status=200, headers={"sessionToken": "SessionToken"}, body="Body") there(response) + return response @@ -175,6 +181,7 @@ def test_getter_session_token(): def test_init_connection(): connection = MockUpServerConnection() there(connection) + return connection @@ -184,6 +191,7 @@ def test_resources_list(): assert len(connection.resources) == 1 connection.resources.append(lambda **kwargs: test_init_response()) assert len(connection.resources) == 2 + return connection @@ -214,6 +222,7 @@ def setup_two_resources(): connection = test_init_connection() connection.resources.extend([r1, r2, r3]) + return connection diff --git a/unittests/test_entity.py b/unittests/test_entity.py index d877e1ab7267977a7e73d65033d6f02c16ea5521..e98dfbef5b6b5e5f691e8aecc2fa7d4a86991452 100644 --- a/unittests/test_entity.py +++ b/unittests/test_entity.py @@ -35,6 +35,7 @@ class TestEntity(unittest.TestCase): def setUp(self): self.assertIsNotNone(Entity) configure_connection(url="unittests", username="testuser", + password_method="plain", password="testpassword", timeout=200, implementation=MockUpServerConnection) diff --git a/unittests/test_file.py b/unittests/test_file.py index 957c578062b25c74547b599a25802938b057a2e0..3c80af7f362a7cdabe0a9ebc89cd2986d04fe242 100644 --- a/unittests/test_file.py +++ b/unittests/test_file.py @@ -22,16 +22,18 @@ # ** end header # """Tests for the File class.""" -# pylint: disable=missing-docstring -from nose.tools import (assert_is_not_none as there, assert_true as tru, - assert_equal as eq) -from caosdb import Record, File, configure_connection +from caosdb import File, Record, configure_connection from caosdb.connection.mockup import MockUpServerConnection +# pylint: disable=missing-docstring +from nose.tools import assert_equal as eq +from nose.tools import assert_is_not_none as there +from nose.tools import assert_true as tru def setup_module(): there(File) configure_connection(url="unittests", username="testuser", + password_method="plain", password="testpassword", timeout=200, implementation=MockUpServerConnection) diff --git a/unittests/test_record_type.py b/unittests/test_record_type.py index c105220c53579537994648b2f9bae5b4d378be13..f31c56decfc394211940296babc83200a470cc8a 100644 --- a/unittests/test_record_type.py +++ b/unittests/test_record_type.py @@ -22,16 +22,18 @@ # ** end header # """Tests for the RecordType class.""" -# pylint: disable=missing-docstring -from nose.tools import (assert_is_not_none as there, assert_true as tru, - assert_equal as eq) from caosdb import Entity, RecordType, configure_connection from caosdb.connection.mockup import MockUpServerConnection +# pylint: disable=missing-docstring +from nose.tools import assert_equal as eq +from nose.tools import assert_is_not_none as there +from nose.tools import assert_true as tru def setup_module(): there(RecordType) configure_connection(url="unittests", username="testuser", + password_method="plain", password="testpassword", timeout=200, implementation=MockUpServerConnection)