Skip to content

Commit

Permalink
Merge branch 'main' into task/WP-80-execution-system
Browse files Browse the repository at this point in the history
  • Loading branch information
rstijerina committed Apr 17, 2024
2 parents c31bc64 + 461e53c commit 32a87c9
Show file tree
Hide file tree
Showing 10 changed files with 166 additions and 11 deletions.
14 changes: 7 additions & 7 deletions client/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion client/package.json
Expand Up @@ -100,7 +100,7 @@
"stylelint-config-standard": "^25.0.0",
"timekeeper": "^2.3.1",
"typescript": "^4.4.3",
"vite": "^2.9.17",
"vite": "^2.9.18",
"weak-key": "^1.0.1"
}
}
@@ -0,0 +1,21 @@
# Generated by Django 4.2.10 on 2024-03-19 16:38

from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion


class Migration(migrations.Migration):

dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
('portal_licenses', '0001_initial'),
]

operations = [
migrations.AlterField(
model_name='matlablicense',
name='user',
field=models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, related_name='%(class)s', to=settings.AUTH_USER_MODEL),
),
]
@@ -0,0 +1,36 @@
# Generated by Django 4.2.10 on 2024-03-19 16:38

from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion


class Migration(migrations.Migration):

dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
('projects', '0002_auto_20210312_1743'),
]

operations = [
migrations.AlterField(
model_name='abstractprojectmetadata',
name='co_pis',
field=models.ManyToManyField(blank=True, related_name='rel_co_pi_%(class)s', related_query_name='co_pi_%(class)s', to=settings.AUTH_USER_MODEL),
),
migrations.AlterField(
model_name='abstractprojectmetadata',
name='owner',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='rel_owner_%(class)s', related_query_name='owner_%(class)s', to=settings.AUTH_USER_MODEL),
),
migrations.AlterField(
model_name='abstractprojectmetadata',
name='pi',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='rel_pi_%(class)s', related_query_name='pi_%(class)s', to=settings.AUTH_USER_MODEL),
),
migrations.AlterField(
model_name='abstractprojectmetadata',
name='team_members',
field=models.ManyToManyField(blank=True, related_name='rel_member_%(class)s', related_query_name='member_%(class)s', to=settings.AUTH_USER_MODEL),
),
]
12 changes: 11 additions & 1 deletion server/portal/apps/tickets/rtUtil.py
Expand Up @@ -60,11 +60,21 @@ def replyToTicket(self, ticket_id, reply_text, files=[]):
def hasAccess(self, ticket_id, user=None):
if user and ticket_id:
ticket = self.tracker.get_ticket(ticket_id)
if user in ticket.get('Requestors', '') or user in ticket.get('Cc', ''):
if DjangoRt.contains_user(ticket.get('Requestors', ''), user) or DjangoRt.contains_user(ticket.get('Cc', ''), user):
return True

return False

def getAttachment(self, ticket_id, attachment_id):
ticketAttachment = self.tracker.get_attachment(ticket_id, attachment_id)
return ticketAttachment

@staticmethod
def contains_user(ticket_field_data, user):
user_lower = user.lower()

if isinstance(ticket_field_data, str):
return user_lower in ticket_field_data.lower()
elif isinstance(ticket_field_data, list):
return user_lower in map(str.lower, ticket_field_data)
return user_lower in ticket_field_data
59 changes: 59 additions & 0 deletions server/portal/apps/tickets/unit_test.py
Expand Up @@ -2,6 +2,7 @@
from django.http import HttpResponse
from django.http import HttpRequest
from portal.apps.tickets.utils import get_recaptcha_verification
from portal.apps.tickets import rtUtil


@pytest.fixture(autouse=True)
Expand Down Expand Up @@ -46,3 +47,61 @@ def test_get_recaptcha_verification(mocker, requests_mock, regular_user):
request.POST['recaptchaResponse'] = 'string'
result = get_recaptcha_verification(request)
assert result['success'] == recaptchaSuccess['success']


class RtUtilTestable(rtUtil.DjangoRt):
'''
Tester for rtUtil.DjangoRt.
'''

def __init__(self, tracker):
# Set the attributes directly
self.rtHost = 'mock_host'
self.rtUn = 'mock_rt_user'
self.rtPw = 'mock_pw'
self.rtQueue = ''
self.tracker = tracker


@pytest.fixture
def rt_ticket(request):
return request.param


@pytest.fixture
def mock_tracker(mocker, rt_ticket):
mock_tracker = mocker.MagicMock()
mock_tracker.get_ticket.return_value = rt_ticket
yield mock_tracker


@pytest.mark.parametrize('rt_ticket', [
{'id': 1, 'Requestors': ["UserName1@Example.COM", "Username2@Example.com"], 'Cc': []},
{'id': 1, 'Requestors': "UserName1@Example.COM,Username2@Example.com", 'Cc': []},
{'id': 1, 'Requestors': ["username1@example.com", "username2@example.com"], 'Cc': []}], indirect=True)
def test_rt_hasaccess_requestors_or_cc(mock_tracker):
rtTester = RtUtilTestable(mock_tracker)
assert rtTester.hasAccess(1, 'Username1@Example.com') is True
assert rtTester.hasAccess(1, 'Username2@Example.com') is True


@pytest.mark.parametrize('rt_ticket', [
{'id': 1, 'Requestors': ["Foo@example.com"], 'Cc': ["UserName1@Example.COM", "username2@example.com"]},
{'id': 1, 'Requestors': ["Foo@example.com"], 'Cc': "UserName1@Example.COM,username2@example.com"},
{'id': 1, 'Requestors': ["Foo@example.com"], 'Cc': ["username1@example.com", "username2@example.com"]},
{'id': 1, 'Cc': ["username1@example.com", "username2@example.com"]},
{'id': 1, 'Requestors': [], 'Cc': ["username1@example.com", "username2@example.com"]}], indirect=True)
def test_rt_hasaccess_cc(mock_tracker):
rtTester = RtUtilTestable(mock_tracker)
assert rtTester.hasAccess(1, 'Username1@Example.com') is True
assert rtTester.hasAccess(1, 'Username2@Example.com') is True


@pytest.mark.parametrize('rt_ticket', [
{'id': 1, 'Requestors': ["foo@example.com"], 'Cc': ["baz@example.com"]},
{'id': 1, 'Requestors': ["FOO@example.com"], 'Cc': ["BAZ@example.com"]},
{'id': 1},
{'id': 1, 'Requestors': [], 'Cc': []}], indirect=True)
def test_rt_hasnoaccess(mock_tracker):
rtTester = RtUtilTestable(mock_tracker)
assert rtTester.hasAccess(1, 'Username1@Example.com') is False
5 changes: 5 additions & 0 deletions server/portal/apps/users/tas_to_tacc_resources.json
@@ -1,4 +1,9 @@
{
"Stampede3": {
"name": "Stampede3",
"host": "stampede3.tacc.utexas.edu",
"type": "HPC"
},
"Stampede4": {
"name": "Stampede2",
"host": "stampede2.tacc.utexas.edu",
Expand Down
@@ -0,0 +1,19 @@
# Generated by Django 4.2.10 on 2024-03-19 16:38

from django.db import migrations, models
import django.utils.timezone


class Migration(migrations.Migration):

dependencies = [
('webhooks', '0001_squashed_0003_alter_externalcall_callback_data'),
]

operations = [
migrations.AlterField(
model_name='externalcall',
name='time',
field=models.DateTimeField(default=django.utils.timezone.now),
),
]
7 changes: 6 additions & 1 deletion server/portal/settings/settings.py
Expand Up @@ -483,7 +483,7 @@
CELERY_TASK_DEFAULT_ROUTING_KEY = 'default'

"""
SETTINGS: TACC EXECUTION SYSTEMS
SETTINGS: TACC EXECUTION SYSTEMS.
"""
TACC_EXEC_SYSTEMS = {
'corral': {
Expand All @@ -496,6 +496,11 @@
'scratch_dir': '/scratch/{}',
'home_dir': '/home1/{}'
},
'stampede3': {
'work_dir': '/work2/{}',
'scratch_dir': '/scratch/{}',
'home_dir': '/home1/{}'
},
'frontera': {
'work_dir': '/work2/{}',
'scratch_dir': '/scratch1/{}',
Expand Down
2 changes: 1 addition & 1 deletion server/portal/settings/settings_default.py
Expand Up @@ -20,7 +20,7 @@
_LOGIN_REDIRECT_URL = '/remote/login/'
_LOGOUT_REDIRECT_URL = '/cms/logout/'

_SYSTEM_MONITOR_DISPLAY_LIST = ['Stampede2', 'Lonestar6', 'Frontera']
_SYSTEM_MONITOR_DISPLAY_LIST = ['Stampede3', 'Lonestar6', 'Frontera']

########################
# DJANGO SETTINGS LOCAL
Expand Down

0 comments on commit 32a87c9

Please sign in to comment.