Skip to content
This repository was archived by the owner on Oct 1, 2022. It is now read-only.

Commit c877a8b

Browse files
committed
Add DISABLE_USER_MGMT config value to allow opt-out of ServiceX user management system
1 parent b8e8da7 commit c877a8b

File tree

6 files changed

+32
-16
lines changed

6 files changed

+32
-16
lines changed

README.rst

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,16 @@ services:
1515

1616
User Management
1717
---------------
18-
If ``ENABLE_AUTH`` is set to True, an identity management system will be
19-
enabled. Users will need to create accounts in order to make requests.
18+
If ``ENABLE_AUTH`` is set to True and `DISABLE_USER_MGMT` is False,
19+
an identity management system will be enabled.
20+
Users will need to create accounts in order to make requests.
2021
The system consists of two components: authentication (verification of each
2122
user's identity) and authorization (control of access to API resources).
2223

24+
If ``ENABLE_AUTH`` and ``DISABLE_USER_MGMT`` are both set to True, then you
25+
will need to generate your own JWT refresh tokens externally using
26+
``JWT_SECRET_KEY``, and provide them to end users.
27+
2328
Authentication
2429
**************
2530
Authentication is currently implemented via `Globus <https://www.globus.org/>`_,

app.conf.template

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,11 @@ DOCS_BASE_URL = 'https://servicex.readthedocs.io/en/latest/'
1010
# Enable JWT auth on public endpoints
1111
ENABLE_AUTH=False
1212

13+
# Disable built-in ServiceX user management system (OAuth via Globus)
14+
# If set to True while ENABLE_AUTH is also True, then you must generate your
15+
# own JWT refresh tokens with identity claims using the JWT_SECRET_KEY
16+
DISABLE_USER_MGMT = False
17+
1318
# Globus configuration - obtained at https://auth.globus.org/v2/web/developers
1419
GLOBUS_CLIENT_ID='globus-client-id'
1520
GLOBUS_CLIENT_SECRET='globus-client-secret'

servicex/resources/servicex_resource.py

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -43,14 +43,15 @@ def _generate_advertised_endpoint(cls, endpoint):
4343
@staticmethod
4444
def get_requesting_user() -> Optional[UserModel]:
4545
"""
46-
:return: User who submitted request for resource.
47-
If auth is enabled, this cannot be None for JWT-protected resources
48-
which are decorated with @auth_required or @admin_required.
46+
:return: ServiceX user who submitted request for resource.
47+
Returns None if auth or user management is disabled.
4948
"""
50-
user = None
51-
if current_app.config.get('ENABLE_AUTH'):
52-
user = UserModel.find_by_sub(get_jwt_identity())
53-
return user
49+
config = current_app.config
50+
if not config.get('ENABLE_AUTH') or config.get('DISABLE_USER_MGMT'):
51+
return None
52+
sub = get_jwt_identity()
53+
if sub is not None:
54+
return UserModel.find_by_sub(sub)
5455

5556
@classmethod
5657
def _get_app_version(cls):

servicex/resources/users/token_refresh.py

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
2727
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2828

29+
from flask import current_app
2930
from flask_restful import Resource
3031
from flask_jwt_extended import (create_access_token, get_raw_jwt, decode_token,
3132
jwt_refresh_token_required, get_jwt_identity)
@@ -35,11 +36,12 @@
3536
class TokenRefresh(Resource):
3637
@jwt_refresh_token_required
3738
def post(self):
38-
user = UserModel.find_by_sub(get_jwt_identity())
39-
claims = get_raw_jwt()
40-
decoded = decode_token(user.refresh_token)
41-
if not claims['jti'] == decoded['jti']:
42-
return {'message': 'Invalid or outdated refresh token'}, 401
39+
if not current_app.config.get('DISABLE_USER_MGMT'):
40+
user = UserModel.find_by_sub(get_jwt_identity())
41+
claims = get_raw_jwt()
42+
decoded = decode_token(user.refresh_token)
43+
if not claims['jti'] == decoded['jti']:
44+
return {'message': 'Invalid or outdated refresh token'}, 401
4345
current_user = get_jwt_identity()
4446
access_token = create_access_token(identity=current_user)
4547
return {'access_token': access_token}

servicex/templates/base.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@
3939
{% endif %}
4040
</div>
4141
<!-- Navbar Right Side -->
42-
{% if config['ENABLE_AUTH'] %}
42+
{% if config['ENABLE_AUTH'] and not config['DISABLE_USER_MGMT'] %}
4343
<div class="navbar-nav">
4444
{% if not session['is_authenticated'] %}
4545
<a href="{{ url_for('sign_in') }}" class="nav-item nav-link">Sign In</a>

tests/resource_test_base.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,10 @@ def mock_requesting_user(self, mocker):
145145
mock_user.admin = False
146146
mock_user.pending = False
147147
mocker.patch(
148-
'servicex.resources.servicex_resource.UserModel.find_by_sub',
148+
'servicex.decorators.UserModel.find_by_sub', return_value=mock_user
149+
)
150+
mocker.patch(
151+
'servicex.resources.servicex_resource.ServiceXResource.get_requesting_user',
149152
return_value=mock_user)
150153
return mock_user
151154

0 commit comments

Comments
 (0)