Skip to content

Commit 0fd84bc

Browse files
committed
[_688] impl raw _server_version
1 parent e561032 commit 0fd84bc

File tree

4 files changed

+78
-27
lines changed

4 files changed

+78
-27
lines changed

irods/connection.py

Lines changed: 20 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -82,30 +82,26 @@ def __init__(self, pool, account):
8282
self._server_version = self._connect()
8383
self._disconnected = False
8484

85-
scheme = self.account._original_authentication_scheme
86-
87-
# These variables are just useful diagnostics. The login_XYZ() methods should fail by
88-
# raising exceptions if they encounter authentication errors.
89-
auth_module = auth_type = ""
90-
91-
if self.server_version >= (4, 3, 0):
92-
auth_module = None
93-
# use client side "plugin" module: irods.auth.<scheme>
94-
irods.auth.load_plugins(subset=[scheme])
95-
auth_module = getattr(irods.auth, scheme, None)
96-
if auth_module:
97-
auth_module.login(self)
98-
auth_type = auth_module.__name__
99-
else:
100-
# use legacy (iRODS pre-4.3 style) authentication
101-
auth_type = scheme
102-
if scheme == NATIVE_AUTH_SCHEME:
103-
self._login_native()
104-
elif scheme == GSI_AUTH_SCHEME:
105-
self.client_ctx = None
106-
self._login_gsi()
107-
elif scheme == PAM_AUTH_SCHEME:
108-
self._login_pam()
85+
if self.pool and not self.pool._need_auth:
86+
return
87+
88+
try:
89+
if not connect: return
90+
91+
scheme = self.account._original_authentication_scheme
92+
93+
# These variables are just useful diagnostics. The login_XYZ() methods should fail by
94+
# raising exceptions if they encounter authentication errors.
95+
auth_module = auth_type = ''
96+
97+
if self.server_version >= (4,3,0):
98+
auth_module = None
99+
# use client side "plugin" module: irods.auth.<scheme>
100+
irods.auth.load_plugins(subset=[scheme])
101+
auth_module = getattr(irods.auth, scheme, None)
102+
if auth_module:
103+
auth_module.login(self)
104+
auth_type = auth_module.__name__
109105
else:
110106
auth_type = None
111107

irods/pool.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ def __init__(
5757
or application_name
5858
or DEFAULT_APPLICATION_NAME
5959
)
60+
self._need_auth = True
6061

6162
if connection_refresh_time > 0:
6263
self.refresh_connection = True

irods/session.py

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import ast
22
import atexit
3+
import contextlib
34
import copy
45
import errno
56
import json
@@ -69,8 +70,29 @@ class NonAnonymousLoginWithoutPassword(RuntimeError):
6970
pass
7071

7172

73+
@contextlib.contextmanager
74+
def attr_changed(obj, attrname, value):
75+
old = getattr(obj, attrname, None)
76+
try:
77+
setattr(obj, attrname, value)
78+
yield
79+
finally:
80+
setattr(obj, attrname, old)
81+
82+
83+
def _raw_server_version( session ):
84+
import irods.connection
85+
s = session.clone()
86+
with attr_changed(s.pool, '_need_auth', False):
87+
conn = irods.connection.Connection(s.pool, s.pool.account)
88+
return conn.server_version
89+
90+
7291
class iRODSSession:
7392

93+
def raw_server_version(self):
94+
return _raw_server_version(self)
95+
7496
def library_features(self):
7597
irods_version_needed = (4, 3, 1)
7698
if self.server_version < irods_version_needed:
@@ -354,11 +376,15 @@ def port(self):
354376
return self.pool.account.port
355377

356378
@property
357-
def server_version(self):
379+
def server_version(self): return self._server_version()
380+
381+
RAW_SERVER_VERSION = staticmethod(lambda s:s.raw_server_version())
382+
383+
def _server_version(self, f = None):
358384
reported_vsn = os.environ.get("PYTHON_IRODSCLIENT_REPORTED_SERVER_VERSION", "")
359385
if reported_vsn:
360386
return tuple(ast.literal_eval(reported_vsn))
361-
return self.__server_version()
387+
return self.__server_version() if f is None else f(self)
362388

363389
def __server_version(self):
364390
try:

irods/test/connection_test.py

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,16 @@
11
#! /usr/bin/env python
22

3+
import numbers
34
import os
45
import sys
56
import tempfile
67
import unittest
7-
from irods.exception import NetworkException
88
from irods import MAXIMUM_CONNECTION_TIMEOUT
9+
from irods.exception import (
10+
NetworkException,
11+
CAT_INVALID_AUTHENTICATION
12+
)
13+
import irods.session
914
import irods.test.helpers as helpers
1015
from irods.test.helpers import (
1116
server_side_sleep,
@@ -34,6 +39,29 @@ def test_connection_destructor(self):
3439
self.assertTrue(conn._disconnected)
3540
conn.release(destroy=True)
3641

42+
def test_server_version_without_authentication__issue_688 (self):
43+
sess = self.sess
44+
45+
# Make a session object that cannot authenticate.
46+
unauthenticated_session = irods.session.iRODSSession(
47+
host = sess.host,
48+
port = sess.port,
49+
user = sess.username,
50+
zone = sess.zone,
51+
# No password.
52+
)
53+
54+
# Test raw_server_version method returns a value.
55+
version_tup = unauthenticated_session.raw_server_version()
56+
57+
# Test returned value is non-empty "version" tuple, i.e. holds only integer values.
58+
self.assertTrue(len(version_tup) > 0)
59+
self.assertFalse(any(not isinstance(_, numbers.Integral) for _ in version_tup))
60+
61+
# Test that the older server_version property fails for the unauthorized session object.
62+
with self.assertRaises(CAT_INVALID_AUTHENTICATION):
63+
unauthenticated_session.server_version
64+
3765
def test_failed_connection(self):
3866
# Make sure no connections are cached in self.sess.pool.idle to be grabbed by get_connection().
3967
# (Necessary after #418 fix; make_session() can probe server_version, which then leaves an idle conn.)

0 commit comments

Comments
 (0)