From 1953fa4fa9510154b26dc861934ad91ff9bba875 Mon Sep 17 00:00:00 2001 From: Roger Steve Ruiz Date: Mon, 19 Mar 2018 17:00:05 -0400 Subject: [PATCH 01/59] Lint production settings file --- tock/tock/settings/production.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tock/tock/settings/production.py b/tock/tock/settings/production.py index 22d76432e..b0ed70952 100644 --- a/tock/tock/settings/production.py +++ b/tock/tock/settings/production.py @@ -11,7 +11,7 @@ ALLOWED_HOSTS = ['*'] # proxied -#FORCE_SCRIPT_NAME = '/tock' +# FORCE_SCRIPT_NAME = '/tock' STATIC_ROOT = '/app/tock/tock/static/' STATIC_URL = '/tock/static/' @@ -41,6 +41,6 @@ try: - from .local_settings import * # noqa + from .local_settings import * # noqa except ImportError: - pass + pass From f6519b736d70de21c3ad6f0ec0247599a0818e0a Mon Sep 17 00:00:00 2001 From: Roger Steve Ruiz Date: Mon, 19 Mar 2018 17:00:59 -0400 Subject: [PATCH 02/59] Update logging configuration --- tock/tock/remote_user_auth.py | 2 +- tock/tock/settings/production.py | 36 +++++++++++++++++++++++++++++++- tock/tock/utils.py | 2 +- tock/tock/views.py | 2 +- 4 files changed, 38 insertions(+), 4 deletions(-) diff --git a/tock/tock/remote_user_auth.py b/tock/tock/remote_user_auth.py index f81e34a54..87a3577a7 100644 --- a/tock/tock/remote_user_auth.py +++ b/tock/tock/remote_user_auth.py @@ -8,7 +8,7 @@ from employees.models import UserData -logger = logging.getLogger(__name__) +logger = logging.getLogger('tock-auth') def email_to_username(email): diff --git a/tock/tock/settings/production.py b/tock/tock/settings/production.py index b0ed70952..ac99c46a7 100644 --- a/tock/tock/settings/production.py +++ b/tock/tock/settings/production.py @@ -26,16 +26,50 @@ LOGGING = { 'version': 1, 'disable_existing_loggers': False, + 'formatters': { + 'verbose': { + 'format': "[%(asctime)s] %(levelname)s [%(name)s:%(lineno)s] " + "%(message)s", + 'datefmt': "%d/%b/%Y %H:%M:%S", + }, + 'simple': { + 'format': "%(levelname)s %(message)s", + }, + }, 'handlers': { + 'file': { + 'level': 'DEBUG', + 'class': 'logging.FileHandler', + 'filename': os.path.join(BASE_DIR, 'logs/tock.log'), + 'formatter': 'verbose', + }, 'console': { + 'level': 'INFO', 'class': 'logging.StreamHandler', + 'formatter': 'verbose', }, }, 'loggers': { 'django': { - 'handlers': ['console'], + 'handlers': ['console', 'file'], + 'propagate': True, 'level': os.getenv('DJANGO_LOG_LEVEL', 'DEBUG'), }, + 'uaa_client': { + 'handlers': ['console', 'file'], + 'propagate': True, + 'level': 'INFO', + }, + 'tock-auth': { + 'handlers': ['console', 'file'], + 'propagate': True, + 'level': 'INFO', + }, + 'tock': { + 'handlers': ['console', 'file'], + 'propagate': True, + 'level': 'INFO', + }, }, } diff --git a/tock/tock/utils.py b/tock/tock/utils.py index 9c3bd3696..fbcfb8f5c 100644 --- a/tock/tock/utils.py +++ b/tock/tock/utils.py @@ -11,7 +11,7 @@ from tock.settings import base -logger = logging.getLogger(__name__) +logger = logging.getLogger('tock-auth') class PermissionMixin(LoginRequiredMixin, object): diff --git a/tock/tock/views.py b/tock/tock/views.py index c4afef3a7..59f47e8ff 100644 --- a/tock/tock/views.py +++ b/tock/tock/views.py @@ -3,7 +3,7 @@ from django.shortcuts import render import django.contrib.auth -logger = logging.getLogger(__name__) +logger = logging.getLogger('tock') def csrf_failure(request, reason=""): From 194b1546770d3e1328b941f17d914483a5afe96e Mon Sep 17 00:00:00 2001 From: Roger Steve Ruiz Date: Tue, 20 Mar 2018 13:13:07 -0400 Subject: [PATCH 03/59] Create logs directory for log file handling --- tock/tock/logs/.gitkeep | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 tock/tock/logs/.gitkeep diff --git a/tock/tock/logs/.gitkeep b/tock/tock/logs/.gitkeep new file mode 100644 index 000000000..e69de29bb From 12c2bd6def739f4560df2a4d6970aec44bda35e6 Mon Sep 17 00:00:00 2001 From: Roger Steve Ruiz Date: Tue, 20 Mar 2018 16:22:51 -0400 Subject: [PATCH 04/59] Record and log deployments --- bin/run.sh | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/bin/run.sh b/bin/run.sh index 03f7ca0a2..3aa8cc7f8 100755 --- a/bin/run.sh +++ b/bin/run.sh @@ -17,5 +17,32 @@ else fi fi + +if [[ -f VERSION ]] +then + VERSION=$(cat VERSION) +else + VERSION="Manual Deployment" +fi + +NEW_RELIC_API_KEY=$( + echo "${VCAP_SERVICES}" | \ + jq '.[] | map(select(.name == "tock-credentials-logging")) | .[].credentials.NEW_RELIC_API_KEY' -r +) + +# Append New Relic API key to New Relic INI file for `newrelic-admin` tool +cat <> "${NEW_RELIC_CONFIG_FILE}" + +# Adding license key from script $(basename "${0}") +api_key=${NEW_RELIC_API_KEY} +EOF + +DEPLOYMENT_DESCRIPTION="Recording deployment of ${VERSION}." + +echo "${DEPLOYMENT_DESCRIPTION}" + +# Record deployment using the New Relic Python Admin CLI +newrelic-admin record-deploy "${NEW_RELIC_CONFIG_FILE}" "${DEPLOYMENT_DESCRIPTION}" + python manage.py collectstatic --settings=tock.settings.production --noinput gunicorn -t 120 -k gevent -w 2 tock.wsgi:application From 80c50d23802d1dcd6e5b817cdf7b72d5af7c2115 Mon Sep 17 00:00:00 2001 From: Roger Steve Ruiz Date: Tue, 20 Mar 2018 16:23:09 -0400 Subject: [PATCH 05/59] Have Django templates log on INFO only --- tock/tock/settings/production.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tock/tock/settings/production.py b/tock/tock/settings/production.py index ac99c46a7..c229ee225 100644 --- a/tock/tock/settings/production.py +++ b/tock/tock/settings/production.py @@ -55,6 +55,11 @@ 'propagate': True, 'level': os.getenv('DJANGO_LOG_LEVEL', 'DEBUG'), }, + 'django.template': { + 'handlers': ['console', 'file'], + 'propagate': True, + 'level': 'INFO', + }, 'uaa_client': { 'handlers': ['console', 'file'], 'propagate': True, From 33ffc5cb918229639b1345fcbe68237cf8c3e796 Mon Sep 17 00:00:00 2001 From: Roger Steve Ruiz Date: Wed, 21 Mar 2018 10:22:45 -0400 Subject: [PATCH 06/59] Add an explicit BASE_DIR rather an implicit --- tock/tock/settings/production.py | 1 + 1 file changed, 1 insertion(+) diff --git a/tock/tock/settings/production.py b/tock/tock/settings/production.py index c229ee225..8314442a2 100644 --- a/tock/tock/settings/production.py +++ b/tock/tock/settings/production.py @@ -6,6 +6,7 @@ # spell out explicit variable dependencies from .base import DATABASES +BASE_DIR = os.path.dirname(os.path.dirname(__file__)) USE_X_FORWARDED_HOST = True From 22040053309a7016efe1d8a8bf75da788611d7f4 Mon Sep 17 00:00:00 2001 From: Roger Steve Ruiz Date: Wed, 21 Mar 2018 14:43:28 -0400 Subject: [PATCH 07/59] Add signals for user_log* events --- tock/tock/signals.py | 22 ++++++++++++++++++++++ tock/tock/views.py | 2 ++ 2 files changed, 24 insertions(+) create mode 100644 tock/tock/signals.py diff --git a/tock/tock/signals.py b/tock/tock/signals.py new file mode 100644 index 000000000..c445f1fdf --- /dev/null +++ b/tock/tock/signals.py @@ -0,0 +1,22 @@ +import logging + +from django.contrib.auth.signals import user_logged_in, user_logged_out, \ + user_login_failed +from django.dispatch import receiver + +logger = logging.getLogger('tock-auth') + + +@receiver(user_logged_in) +def login_logger(sender, request, user, **kwargs): + logger.info(f'Successful login event for {user.username}.') + + +@receiver(user_logged_out) +def logout_logger(sender, request, user, **kwargs): + logger.info(f'Successful logout event for {user.username}.') + + +@receiver(user_logged_fail) +def failed_login_logger(sender, credentials, request, **kwargs): + logger.info(f'Unsuccessful login attempt by {credentials}.') diff --git a/tock/tock/views.py b/tock/tock/views.py index 59f47e8ff..9107bfe77 100644 --- a/tock/tock/views.py +++ b/tock/tock/views.py @@ -3,6 +3,8 @@ from django.shortcuts import render import django.contrib.auth +from . import signals # noqa + logger = logging.getLogger('tock') From 8b4258e446087e4601aea671fa160b6649207b96 Mon Sep 17 00:00:00 2001 From: Roger Steve Ruiz Date: Thu, 22 Mar 2018 07:56:49 -0400 Subject: [PATCH 08/59] Fix name of signal --- tock/tock/signals.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tock/tock/signals.py b/tock/tock/signals.py index c445f1fdf..f8683a171 100644 --- a/tock/tock/signals.py +++ b/tock/tock/signals.py @@ -17,6 +17,6 @@ def logout_logger(sender, request, user, **kwargs): logger.info(f'Successful logout event for {user.username}.') -@receiver(user_logged_fail) +@receiver(user_login_failed) def failed_login_logger(sender, credentials, request, **kwargs): logger.info(f'Unsuccessful login attempt by {credentials}.') From b1c1627a059e2c179ebc0ae61bf690e228b94f17 Mon Sep 17 00:00:00 2001 From: Roger Steve Ruiz Date: Thu, 22 Mar 2018 09:44:14 -0400 Subject: [PATCH 09/59] Add logging to Employees models --- tock/employees/signals.py | 23 +++++++++++++++++++++++ tock/employees/views.py | 2 +- tock/tock/settings/production.py | 5 +++++ 3 files changed, 29 insertions(+), 1 deletion(-) create mode 100644 tock/employees/signals.py diff --git a/tock/employees/signals.py b/tock/employees/signals.py new file mode 100644 index 000000000..6f39e93b9 --- /dev/null +++ b/tock/employees/signals.py @@ -0,0 +1,23 @@ +import logging + +from django.db.models.signals import pre_save +from django.dispatch import receiver + +from .models import EmployeeGrade, UserData + +logger = logging.getLogger('tock-employees') + + +@receiver(pre_save, sender=EmployeeGrade) +def employee_grade_creation(sender, instance=None, **kwargs): + if instance is not None and instance.pk is None: + logger.info( + f'Creating EmployeeGrade for {instance.employee.username}.' + ) + +@receiver(pre_save, sender=UserData) +def user_data_creation(sender, instance=None, **kwargs): + if instance is not None and instance.pk is None: + logger.info( + f'Creating UserData for {instance.user.username}.' + ) diff --git a/tock/employees/views.py b/tock/employees/views.py index e30bd8589..305f167c6 100644 --- a/tock/employees/views.py +++ b/tock/employees/views.py @@ -11,7 +11,7 @@ from .forms import UserForm from .models import UserData - +from . import signals def parse_date(date): if date == 'NA': diff --git a/tock/tock/settings/production.py b/tock/tock/settings/production.py index 8314442a2..a1b40b159 100644 --- a/tock/tock/settings/production.py +++ b/tock/tock/settings/production.py @@ -71,6 +71,11 @@ 'propagate': True, 'level': 'INFO', }, + 'tock-employees': { + 'handlers': ['console', 'file'], + 'propagate': True, + 'level': 'INFO', + }, 'tock': { 'handlers': ['console', 'file'], 'propagate': True, From a696d826462a1204fc626ff84ab706a110710d5e Mon Sep 17 00:00:00 2001 From: Roger Steve Ruiz Date: Thu, 22 Mar 2018 09:44:50 -0400 Subject: [PATCH 10/59] Rename Tock signals logging --- tock/tock/signals.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tock/tock/signals.py b/tock/tock/signals.py index f8683a171..bd03af4f7 100644 --- a/tock/tock/signals.py +++ b/tock/tock/signals.py @@ -4,7 +4,7 @@ user_login_failed from django.dispatch import receiver -logger = logging.getLogger('tock-auth') +logger = logging.getLogger('tock') @receiver(user_logged_in) From 21d6bcbeaa593ccae1b0227d367da55816ae3b35 Mon Sep 17 00:00:00 2001 From: Roger Steve Ruiz Date: Thu, 22 Mar 2018 09:45:19 -0400 Subject: [PATCH 11/59] Add logging for Hours Models --- tock/hours/models.py | 3 ++ tock/hours/signals.py | 67 ++++++++++++++++++++++++++++++++ tock/hours/views.py | 2 + tock/tock/settings/production.py | 5 +++ 4 files changed, 77 insertions(+) create mode 100644 tock/hours/signals.py diff --git a/tock/hours/models.py b/tock/hours/models.py index 1e25e9716..6d3b1d9fd 100644 --- a/tock/hours/models.py +++ b/tock/hours/models.py @@ -299,6 +299,9 @@ def hours(self): def notes_list(self): return self.notes.split('\n') + def __str__(self): + return f'{self.timecard} {self.project}' + def save(self, *args, **kwargs): """Custom save() method to append employee grade info and the submitted status of the related timecard.""" diff --git a/tock/hours/signals.py b/tock/hours/signals.py new file mode 100644 index 000000000..38b7e1f47 --- /dev/null +++ b/tock/hours/signals.py @@ -0,0 +1,67 @@ +import logging + +from django.db.models.signals import pre_save, post_save +from django.dispatch import receiver + +from .models import ( + HolidayPrefills, ReportingPeriod, Targets, Timecard, TimecardNote, + TimecardObject, TimecardPrefillData +) + +logger = logging.getLogger('tock-hours') + + +@receiver(pre_save, sender=HolidayPrefills) +def holiday_prefills_creation(sender, instance=None, **kwargs): + if instance is not None and instance.pk is None: + logger.info( + f'Creating HolidayPrefills for {instance}.' + ) + + +@receiver(pre_save, sender=ReportingPeriod) +def reporting_period_creation(sender, instance=None, **kwargs): + if instance is not None and instance.pk is None: + logger.info( + f'Creating ReportingPeriod for {instance}.' + ) + + +@receiver(pre_save, sender=Targets) +def targets_creation(sender, instance=None, **kwargs): + if instance is not None and instance.pk is None: + logger.info( + f'Creating Targets for {instance}.' + ) + + +@receiver(pre_save, sender=Timecard) +def timecard_creation(sender, instance=None, **kwargs): + if instance is not None and instance.pk is None: + logger.info( + f'Creating Timecard for {instance}.' + ) + + +@receiver(pre_save, sender=TimecardNote) +def timecard_note_creation(sender, instance=None, **kwargs): + if instance is not None and instance.pk is None: + logger.info( + f'Creating TimecardNote for {instance}.' + ) + + +@receiver(pre_save, sender=TimecardObject) +def timecard_object_creation(sender, instance=None, **kwargs): + if instance is not None and instance.pk is None: + logger.info( + f'Creating TimecardObject for {instance}.' + ) + + +@receiver(pre_save, sender=TimecardPrefillData) +def timecard_prefill_data_creation(sender, instance=None, **kwargs): + if instance is not None and instance.pk is None: + logger.info( + f'Creating TimecardPrefillData for {instance}.' + ) diff --git a/tock/hours/views.py b/tock/hours/views.py index b116418f2..99b062993 100644 --- a/tock/hours/views.py +++ b/tock/hours/views.py @@ -47,6 +47,8 @@ ) from utilization.utils import calculate_utilization, get_fy_first_day +from . import signals + class DashboardReportsList(PermissionMixin, ListView): template_name = 'hours/dashboard_list.html' diff --git a/tock/tock/settings/production.py b/tock/tock/settings/production.py index a1b40b159..54c3df7af 100644 --- a/tock/tock/settings/production.py +++ b/tock/tock/settings/production.py @@ -76,6 +76,11 @@ 'propagate': True, 'level': 'INFO', }, + 'tock-hours': { + 'handlers': ['console', 'file'], + 'propagate': True, + 'level': 'INFO', + }, 'tock': { 'handlers': ['console', 'file'], 'propagate': True, From 8b917862bb5608d0d41979b69b88c30ee88977af Mon Sep 17 00:00:00 2001 From: Roger Steve Ruiz Date: Thu, 22 Mar 2018 10:23:02 -0400 Subject: [PATCH 12/59] Refactor where signals are initialized --- tock/employees/apps.py | 7 +++++++ tock/employees/models.py | 1 + tock/employees/views.py | 1 - tock/hours/apps.py | 7 +++++++ tock/hours/signals.py | 2 +- tock/hours/views.py | 2 -- tock/tock/apps.py | 7 +++++++ tock/tock/settings/base.py | 6 +++--- tock/tock/views.py | 2 -- 9 files changed, 26 insertions(+), 9 deletions(-) create mode 100644 tock/employees/apps.py create mode 100644 tock/hours/apps.py create mode 100644 tock/tock/apps.py diff --git a/tock/employees/apps.py b/tock/employees/apps.py new file mode 100644 index 000000000..fc53c0664 --- /dev/null +++ b/tock/employees/apps.py @@ -0,0 +1,7 @@ +from django.apps import AppConfig + +class EmployeesAppConfig(AppConfig): + name = "employees" + + def ready(self): + from . import signals # noqa diff --git a/tock/employees/models.py b/tock/employees/models.py index 4c05a3ab1..8770f0430 100644 --- a/tock/employees/models.py +++ b/tock/employees/models.py @@ -7,6 +7,7 @@ from organizations.models import Organization from projects.models import ProfitLossAccount + class EmployeeGrade(models.Model): GRADE_CHOICES = ( (1, '1'), diff --git a/tock/employees/views.py b/tock/employees/views.py index 305f167c6..28637ec9c 100644 --- a/tock/employees/views.py +++ b/tock/employees/views.py @@ -11,7 +11,6 @@ from .forms import UserForm from .models import UserData -from . import signals def parse_date(date): if date == 'NA': diff --git a/tock/hours/apps.py b/tock/hours/apps.py new file mode 100644 index 000000000..3f205cf77 --- /dev/null +++ b/tock/hours/apps.py @@ -0,0 +1,7 @@ +from django.apps import AppConfig + +class HoursAppConfig(AppConfig): + name = "hours" + + def ready(self): + from . import signals # noqa diff --git a/tock/hours/signals.py b/tock/hours/signals.py index 38b7e1f47..aeca4e2e9 100644 --- a/tock/hours/signals.py +++ b/tock/hours/signals.py @@ -1,6 +1,6 @@ import logging -from django.db.models.signals import pre_save, post_save +from django.db.models.signals import pre_save from django.dispatch import receiver from .models import ( diff --git a/tock/hours/views.py b/tock/hours/views.py index 99b062993..b116418f2 100644 --- a/tock/hours/views.py +++ b/tock/hours/views.py @@ -47,8 +47,6 @@ ) from utilization.utils import calculate_utilization, get_fy_first_day -from . import signals - class DashboardReportsList(PermissionMixin, ListView): template_name = 'hours/dashboard_list.html' diff --git a/tock/tock/apps.py b/tock/tock/apps.py new file mode 100644 index 000000000..6a9ee7750 --- /dev/null +++ b/tock/tock/apps.py @@ -0,0 +1,7 @@ +from django.apps import AppConfig + +class TockAppConfig(AppConfig): + name = "tock" + + def ready(self): + from . import signals # noqa diff --git a/tock/tock/settings/base.py b/tock/tock/settings/base.py index 2cd53c217..252ea80bd 100644 --- a/tock/tock/settings/base.py +++ b/tock/tock/settings/base.py @@ -34,10 +34,10 @@ 'django.contrib.sessions', 'django.contrib.messages', 'uaa_client', - 'tock', + 'tock.apps.TockAppConfig', 'projects', - 'hours', - 'employees', + 'hours.apps.HoursAppConfig', + 'employees.apps.EmployeesAppConfig', 'organizations', 'api', 'utilization', diff --git a/tock/tock/views.py b/tock/tock/views.py index 9107bfe77..59f47e8ff 100644 --- a/tock/tock/views.py +++ b/tock/tock/views.py @@ -3,8 +3,6 @@ from django.shortcuts import render import django.contrib.auth -from . import signals # noqa - logger = logging.getLogger('tock') From 39ef95d5a69dda9560630750ff6319e41a79d26e Mon Sep 17 00:00:00 2001 From: Roger Steve Ruiz Date: Thu, 22 Mar 2018 14:26:54 -0400 Subject: [PATCH 13/59] Refactor signal connections to use setup_signals() --- tock/employees/apps.py | 3 ++- tock/employees/signals.py | 19 ++++++++++--- tock/hours/apps.py | 3 ++- tock/hours/signals.py | 56 ++++++++++++++++++++++++++++++--------- tock/tock/apps.py | 3 ++- tock/tock/signals.py | 26 ++++++++++++------ 6 files changed, 82 insertions(+), 28 deletions(-) diff --git a/tock/employees/apps.py b/tock/employees/apps.py index fc53c0664..a36dec821 100644 --- a/tock/employees/apps.py +++ b/tock/employees/apps.py @@ -1,7 +1,8 @@ from django.apps import AppConfig +from .signals import setup_signals class EmployeesAppConfig(AppConfig): name = "employees" def ready(self): - from . import signals # noqa + setup_signals() diff --git a/tock/employees/signals.py b/tock/employees/signals.py index 6f39e93b9..a674b52f5 100644 --- a/tock/employees/signals.py +++ b/tock/employees/signals.py @@ -3,21 +3,32 @@ from django.db.models.signals import pre_save from django.dispatch import receiver -from .models import EmployeeGrade, UserData - logger = logging.getLogger('tock-employees') -@receiver(pre_save, sender=EmployeeGrade) def employee_grade_creation(sender, instance=None, **kwargs): if instance is not None and instance.pk is None: logger.info( f'Creating EmployeeGrade for {instance.employee.username}.' ) -@receiver(pre_save, sender=UserData) def user_data_creation(sender, instance=None, **kwargs): if instance is not None and instance.pk is None: logger.info( f'Creating UserData for {instance.user.username}.' ) + + +def setup_signals(): + from .models import EmployeeGrade, UserData + + pre_save.connect( + employee_grade_creation, + sender=EmployeeGrade, + dispatch_uid="employees_employee_grade_creation" + ) + pre_save.connect( + user_data_creation, + sender=UserData, + dispatch_uid="employees_user_data_creation" + ) diff --git a/tock/hours/apps.py b/tock/hours/apps.py index 3f205cf77..2b9bd05aa 100644 --- a/tock/hours/apps.py +++ b/tock/hours/apps.py @@ -1,7 +1,8 @@ from django.apps import AppConfig +from .signals import setup_signals class HoursAppConfig(AppConfig): name = "hours" def ready(self): - from . import signals # noqa + setup_signals() diff --git a/tock/hours/signals.py b/tock/hours/signals.py index aeca4e2e9..96eb14cb3 100644 --- a/tock/hours/signals.py +++ b/tock/hours/signals.py @@ -1,17 +1,10 @@ import logging from django.db.models.signals import pre_save -from django.dispatch import receiver - -from .models import ( - HolidayPrefills, ReportingPeriod, Targets, Timecard, TimecardNote, - TimecardObject, TimecardPrefillData -) logger = logging.getLogger('tock-hours') -@receiver(pre_save, sender=HolidayPrefills) def holiday_prefills_creation(sender, instance=None, **kwargs): if instance is not None and instance.pk is None: logger.info( @@ -19,7 +12,6 @@ def holiday_prefills_creation(sender, instance=None, **kwargs): ) -@receiver(pre_save, sender=ReportingPeriod) def reporting_period_creation(sender, instance=None, **kwargs): if instance is not None and instance.pk is None: logger.info( @@ -27,7 +19,6 @@ def reporting_period_creation(sender, instance=None, **kwargs): ) -@receiver(pre_save, sender=Targets) def targets_creation(sender, instance=None, **kwargs): if instance is not None and instance.pk is None: logger.info( @@ -35,7 +26,6 @@ def targets_creation(sender, instance=None, **kwargs): ) -@receiver(pre_save, sender=Timecard) def timecard_creation(sender, instance=None, **kwargs): if instance is not None and instance.pk is None: logger.info( @@ -43,7 +33,6 @@ def timecard_creation(sender, instance=None, **kwargs): ) -@receiver(pre_save, sender=TimecardNote) def timecard_note_creation(sender, instance=None, **kwargs): if instance is not None and instance.pk is None: logger.info( @@ -51,7 +40,6 @@ def timecard_note_creation(sender, instance=None, **kwargs): ) -@receiver(pre_save, sender=TimecardObject) def timecard_object_creation(sender, instance=None, **kwargs): if instance is not None and instance.pk is None: logger.info( @@ -59,9 +47,51 @@ def timecard_object_creation(sender, instance=None, **kwargs): ) -@receiver(pre_save, sender=TimecardPrefillData) def timecard_prefill_data_creation(sender, instance=None, **kwargs): if instance is not None and instance.pk is None: logger.info( f'Creating TimecardPrefillData for {instance}.' ) + + +def setup_signals(): + from .models import ( + HolidayPrefills, ReportingPeriod, Targets, Timecard, TimecardNote, + TimecardObject, TimecardPrefillData + ) + + pre_save.connect( + holiday_prefills_creation, + sender=HolidayPrefills, + dispatch_uid="hours_holiday_prefills_creation" + ) + pre_save.connect( + reporting_period_creation, + sender=ReportingPeriod, + dispatch_uid="hours_reporting_period_creation" + ) + pre_save.connect( + targets_creation, + sender=Targets, + dispatch_uid="hours_targets_creation" + ) + pre_save.connect( + timecard_creation, + sender=Timecard, + dispatch_uid="hours_timecard_creation" + ) + pre_save.connect( + timecard_note_creation, + sender=TimecardNote, + dispatch_uid="hours_timecard_note_creation" + ) + pre_save.connect( + timecard_object_creation, + sender=TimecardObject, + dispatch_uid="hours_timecard_object_creation" + ) + pre_save.connect( + timecard_prefill_data_creation, + sender=TimecardPrefillData, + dispatch_uid="hours_timecard_prefill_data_creation" + ) diff --git a/tock/tock/apps.py b/tock/tock/apps.py index 6a9ee7750..2f83c7883 100644 --- a/tock/tock/apps.py +++ b/tock/tock/apps.py @@ -1,7 +1,8 @@ from django.apps import AppConfig +from .signals import setup_signals class TockAppConfig(AppConfig): name = "tock" def ready(self): - from . import signals # noqa + setup_signals() diff --git a/tock/tock/signals.py b/tock/tock/signals.py index bd03af4f7..6b951e374 100644 --- a/tock/tock/signals.py +++ b/tock/tock/signals.py @@ -2,21 +2,31 @@ from django.contrib.auth.signals import user_logged_in, user_logged_out, \ user_login_failed -from django.dispatch import receiver logger = logging.getLogger('tock') -@receiver(user_logged_in) -def login_logger(sender, request, user, **kwargs): +def successful_login(sender, request, user, **kwargs): logger.info(f'Successful login event for {user.username}.') -@receiver(user_logged_out) -def logout_logger(sender, request, user, **kwargs): +def successful_logout(sender, request, user, **kwargs): logger.info(f'Successful logout event for {user.username}.') - -@receiver(user_login_failed) -def failed_login_logger(sender, credentials, request, **kwargs): +def failed_login(sender, credentials, request, **kwargs): logger.info(f'Unsuccessful login attempt by {credentials}.') + + +def setup_signals(): + user_logged_in.connect( + successful_login, + dispatch_uid="tock_successful_login" + ) + user_logged_out.connect( + successful_logout, + dispatch_uid="tock_successful_logout" + ) + user_login_failed.connect( + failed_login, + dispatch_uid="tock_failed_login" + ) From 4dbdaf0db4cfae5bbda3a533ef5b989d7ce9055f Mon Sep 17 00:00:00 2001 From: Roger Steve Ruiz Date: Thu, 22 Mar 2018 17:02:02 -0400 Subject: [PATCH 14/59] Add logging to the rest of the Tock-family apps --- tock/api/apps.py | 4 ++ tock/api/signals.py | 1 + tock/organizations/apps.py | 9 +++++ tock/organizations/signals.py | 22 +++++++++++ tock/projects/apps.py | 8 ++++ tock/projects/signals.py | 65 ++++++++++++++++++++++++++++++++ tock/tock/settings/base.py | 8 ++-- tock/tock/settings/production.py | 10 +++++ tock/utilization/apps.py | 4 ++ tock/utilization/signals.py | 1 + 10 files changed, 128 insertions(+), 4 deletions(-) create mode 100644 tock/api/apps.py create mode 100644 tock/api/signals.py create mode 100644 tock/organizations/apps.py create mode 100644 tock/organizations/signals.py create mode 100644 tock/projects/apps.py create mode 100644 tock/projects/signals.py create mode 100644 tock/utilization/apps.py create mode 100644 tock/utilization/signals.py diff --git a/tock/api/apps.py b/tock/api/apps.py new file mode 100644 index 000000000..3204d8c68 --- /dev/null +++ b/tock/api/apps.py @@ -0,0 +1,4 @@ +from django.apps import AppConfig + +class ApiAppConfig(AppConfig): + name = "api" diff --git a/tock/api/signals.py b/tock/api/signals.py new file mode 100644 index 000000000..6fa24b3b0 --- /dev/null +++ b/tock/api/signals.py @@ -0,0 +1 @@ +# Create your signal connections here. diff --git a/tock/organizations/apps.py b/tock/organizations/apps.py new file mode 100644 index 000000000..09f197107 --- /dev/null +++ b/tock/organizations/apps.py @@ -0,0 +1,9 @@ +from django.apps import AppConfig +from .signals import setup_signals + +class OrganizationsAppConfig(AppConfig): + name = "organizations" + + def ready(self): + setup_signals() + diff --git a/tock/organizations/signals.py b/tock/organizations/signals.py new file mode 100644 index 000000000..0770295dc --- /dev/null +++ b/tock/organizations/signals.py @@ -0,0 +1,22 @@ +import logging + +from django.db.models.signals import pre_save + +logger = logging.getLogger('tock-organizations') + + +def organization_creation(sender, instance=None, **kwargs): + if instance is not None and instance.pk is None: + logger.info( + f'Creating Organization for {instance}.' + ) + + +def setup_signals(): + from .models import Organization + + pre_save.connect( + organization_creation, + sender=Organization, + dispatch_uid="organizations_organization_creation" + ) diff --git a/tock/projects/apps.py b/tock/projects/apps.py new file mode 100644 index 000000000..ee5f76bcb --- /dev/null +++ b/tock/projects/apps.py @@ -0,0 +1,8 @@ +from django.apps import AppConfig +from .signals import setup_signals + +class ProjectsAppConfig(AppConfig): + name = "projects" + + def ready(self): + setup_signals() diff --git a/tock/projects/signals.py b/tock/projects/signals.py new file mode 100644 index 000000000..14698ecf9 --- /dev/null +++ b/tock/projects/signals.py @@ -0,0 +1,65 @@ +import logging + +from django.db.models.signals import pre_save + +logger = logging.getLogger('tock-projects') + + +def agency_creation(sender, instance=None, **kwargs): + if instance is not None and instance.pk is None: + logger.info( + f'Creating Agency for {instance}.' + ) + +def accounting_code_creation(sender, instance=None, **kwargs): + if instance is not None and instance.pk is None: + logger.info( + f'Creating AccountingCode for {instance}.' + ) + + +def project_alert_creation(sender, instance=None, **kwargs): + if instance is not None and instance.pk is None: + logger.info( + f'Creating ProjectAlert for {instance}.' + ) + + +def profit_loss_account_creation(sender, instance=None, **kwargs): + if instance is not None and instance.pk is None: + logger.info( + f'Creating ProfitLossAccount for {instance}.' + ) + + +def project_creation(sender, instance=None, **kwargs): + if instance is not None and instance.pk is None: + logger.info( + f'Creating Project for {instance}.' + ) + +def setup_signals(): + from .models import ( + Agency, AccountingCode, ProjectAlert, ProfitLossAccount, Project + ) + + pre_save.connect( + agency_creation, + sender=Agency, + dispatch_uid="project_agency_creation" + ) + pre_save.connect( + accounting_code_creation, + sender=AccountingCode, + dispatch_uid="project_accounting_code_creation" + ) + pre_save.connect( + project_alert_creation, + sender=ProjectAlert, + dispatch_uid="project_project_alert_creation" + ) + pre_save.connect( + project_creation, + sender=Project, + dispatch_uid="project_project_creation" + ) diff --git a/tock/tock/settings/base.py b/tock/tock/settings/base.py index 252ea80bd..d53381ef3 100644 --- a/tock/tock/settings/base.py +++ b/tock/tock/settings/base.py @@ -35,12 +35,12 @@ 'django.contrib.messages', 'uaa_client', 'tock.apps.TockAppConfig', - 'projects', + 'projects.apps.ProjectsAppConfig', 'hours.apps.HoursAppConfig', 'employees.apps.EmployeesAppConfig', - 'organizations', - 'api', - 'utilization', + 'organizations.apps.OrganizationsAppConfig', + 'api.apps.ApiAppConfig', + 'utilization.apps.UtilizationAppConfig', 'rest_framework.authtoken', ) diff --git a/tock/tock/settings/production.py b/tock/tock/settings/production.py index 54c3df7af..b483cc85a 100644 --- a/tock/tock/settings/production.py +++ b/tock/tock/settings/production.py @@ -81,6 +81,16 @@ 'propagate': True, 'level': 'INFO', }, + 'tock-organizations': { + 'handlers': ['console', 'file'], + 'propagate': True, + 'level': 'INFO', + }, + 'tock-projects': { + 'handlers': ['console', 'file'], + 'propagate': True, + 'level': 'INFO', + }, 'tock': { 'handlers': ['console', 'file'], 'propagate': True, diff --git a/tock/utilization/apps.py b/tock/utilization/apps.py new file mode 100644 index 000000000..737b8e949 --- /dev/null +++ b/tock/utilization/apps.py @@ -0,0 +1,4 @@ +from django.apps import AppConfig + +class UtilizationAppConfig(AppConfig): + name = "utilization" diff --git a/tock/utilization/signals.py b/tock/utilization/signals.py new file mode 100644 index 000000000..6fa24b3b0 --- /dev/null +++ b/tock/utilization/signals.py @@ -0,0 +1 @@ +# Create your signal connections here. From 02b10c990e015c3d2dc9ea75ba404d209e43cd9a Mon Sep 17 00:00:00 2001 From: Roger Steve Ruiz Date: Thu, 22 Mar 2018 17:31:38 -0400 Subject: [PATCH 15/59] Add admin logging to main Tock app signals --- tock/tock/signals.py | 61 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 61 insertions(+) diff --git a/tock/tock/signals.py b/tock/tock/signals.py index 6b951e374..cc5202c93 100644 --- a/tock/tock/signals.py +++ b/tock/tock/signals.py @@ -2,6 +2,7 @@ from django.contrib.auth.signals import user_logged_in, user_logged_out, \ user_login_failed +from django.db.models.signals import pre_save, post_save, m2m_changed logger = logging.getLogger('tock') @@ -13,11 +14,51 @@ def successful_login(sender, request, user, **kwargs): def successful_logout(sender, request, user, **kwargs): logger.info(f'Successful logout event for {user.username}.') + def failed_login(sender, credentials, request, **kwargs): logger.info(f'Unsuccessful login attempt by {credentials}.') +def adminlog_post_save(sender, instance, **kwargs): + from django.contrib.admin.models import ADDITION, CHANGE, DELETION + if instance.action_flag == ADDITION: + logger.info( + f'{instance.user} created {instance.content_type} {instance.object_repr}.' + ) + elif instance.action_flag == CHANGE: + logger.info( + f'{instance.user} changed {instance.content_type} {instance.object_repr}: ' + f'{instance.change_message}.' + ) + elif instance.action_flag == DELETION: + logger.info( + f'{instance.user} deleted {instance.content_type} {instance.object_repr}.' + ) + +def log_m2m_change(sender, instance, action, reverse, model, pk_set, **kwargs): + model_name = model._meta.verbose_name_plural + instance_model = instance._meta.verbose_name + if action == 'post_add': + objects_added = list(model.objects.filter(pk__in=pk_set)) + logger.info( + f'{model_name} given to {instance_model} {instance}: {objects_added}.' + ) + elif action == 'post_remove': + objects_added = list(model.objects.filter(pk__in=pk_set)) + logger.info( + f'{model_name} removed from {instance_model} {instance}: {objects_added}.' + ) + logger.info("%s removed from %s '%s': %s", model_name, instance_model, + instance, objects_added) + elif action == 'post_clear': + logger.info( + f'All {model_name} removed from {instance_model} {instance}.' + ) + def setup_signals(): + from django.contrib.auth.models import User, Group + from django.contrib.admin.models import LogEntry + user_logged_in.connect( successful_login, dispatch_uid="tock_successful_login" @@ -30,3 +71,23 @@ def setup_signals(): failed_login, dispatch_uid="tock_failed_login" ) + post_save.connect( + adminlog_post_save, + sender=LogEntry, + dispatch_uid="tock_adminlog_post_save" + ) + m2m_changed.connect( + log_m2m_change, + sender=User.groups.through, + dispatch_uid="tock_log_m2m_changed_user_groups" + ) + m2m_changed.connect( + log_m2m_change, + sender=User.user_permissions.through, + dispatch_uid="tock_log_m2m_changed_user_permissions" + ) + m2m_changed.connect( + log_m2m_change, + sender=Group.permissions.through, + dispatch_uid="tock_log_m2m_changed_groups_permissions" + ) From 8e7a981fa84b794dc627750b6cb746d69e146c2f Mon Sep 17 00:00:00 2001 From: Roger Steve Ruiz Date: Thu, 22 Mar 2018 17:54:14 -0400 Subject: [PATCH 16/59] Clear up linting errors --- tock/employees/signals.py | 1 - tock/organizations/apps.py | 1 - tock/projects/signals.py | 5 +++++ tock/tock/signals.py | 2 +- 4 files changed, 6 insertions(+), 3 deletions(-) diff --git a/tock/employees/signals.py b/tock/employees/signals.py index a674b52f5..58b543534 100644 --- a/tock/employees/signals.py +++ b/tock/employees/signals.py @@ -1,7 +1,6 @@ import logging from django.db.models.signals import pre_save -from django.dispatch import receiver logger = logging.getLogger('tock-employees') diff --git a/tock/organizations/apps.py b/tock/organizations/apps.py index 09f197107..d72d410a2 100644 --- a/tock/organizations/apps.py +++ b/tock/organizations/apps.py @@ -6,4 +6,3 @@ class OrganizationsAppConfig(AppConfig): def ready(self): setup_signals() - diff --git a/tock/projects/signals.py b/tock/projects/signals.py index 14698ecf9..df74ed73f 100644 --- a/tock/projects/signals.py +++ b/tock/projects/signals.py @@ -58,6 +58,11 @@ def setup_signals(): sender=ProjectAlert, dispatch_uid="project_project_alert_creation" ) + pre_save.connect( + profit_loss_account_creation, + sender=ProfitLossAccount, + dispatch_uid="project_profit_loss_account_creation" + ) pre_save.connect( project_creation, sender=Project, diff --git a/tock/tock/signals.py b/tock/tock/signals.py index cc5202c93..b0fd03786 100644 --- a/tock/tock/signals.py +++ b/tock/tock/signals.py @@ -2,7 +2,7 @@ from django.contrib.auth.signals import user_logged_in, user_logged_out, \ user_login_failed -from django.db.models.signals import pre_save, post_save, m2m_changed +from django.db.models.signals import post_save, m2m_changed logger = logging.getLogger('tock') From 66892ccb9fab129528e85a58ef835b19a43e6925 Mon Sep 17 00:00:00 2001 From: Roger Steve Ruiz Date: Fri, 23 Mar 2018 16:46:11 -0400 Subject: [PATCH 17/59] Clearer logs for RemoteUserAuth --- tock/tock/remote_user_auth.py | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/tock/tock/remote_user_auth.py b/tock/tock/remote_user_auth.py index 87a3577a7..e84913de3 100644 --- a/tock/tock/remote_user_auth.py +++ b/tock/tock/remote_user_auth.py @@ -33,9 +33,8 @@ def verify_userdata(user): try: user = UserData.objects.get(user=user) except UserData.DoesNotExist: - logger.info( - 'Adding UserData for User [%s]' % - user.username + logger.warn( + f'Creating UserData for {user.username}.' ) UserData.objects.create( user=user, @@ -50,8 +49,7 @@ def get_user_by_email(cls, email): user = super().get_user_by_email(email) if user is not None: logger.info( - 'Verifying that User [%s] has UserData' % - user.username + f'Verifying UserData for {user.username}' ) verify_userdata(user) return user @@ -62,14 +60,12 @@ def create_user_with_email(cls, email): try: logger.info( - "Attempting to get user [%s] that exists already." % - username + f'Fetching User for {username}' ) user = User.objects.get(username=username) except User.DoesNotExist: - logger.info( - "Creating a new user [%s]" % - username + logger.warn( + f'Creating User for {username}' ) user = User.objects.create_user(username, email) user.first_name = str(username).split('.')[0].title() From c545b41830d4b08945544c835227a78c060bc3fc Mon Sep 17 00:00:00 2001 From: Roger Steve Ruiz Date: Fri, 23 Mar 2018 16:49:23 -0400 Subject: [PATCH 18/59] Better logging for PermissionMixin --- tock/tock/utils.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/tock/tock/utils.py b/tock/tock/utils.py index fbcfb8f5c..ea3f580db 100644 --- a/tock/tock/utils.py +++ b/tock/tock/utils.py @@ -30,9 +30,11 @@ def wrapped(request, *args, **kwargs): for permission_class in getattr(cls, 'permission_classes', ()): if not permission_class().has_permission(request, self): if isinstance(permission_class(), IsAuthenticated): - logger.info("User isn't logged in, redirecting...") + logger.info('User not authenticated, redirecting to UAA.') return redirect('/auth/login') - logger.info("User isn't allowed, redirecting...") + logger.warn( + f'User not authorized {request.user.username}, redirecting to 404.' + ) raise PermissionDenied return view(request, args, **kwargs) return wrapped From 8ac652f4c3bae594000aee500b2626b2274c361a Mon Sep 17 00:00:00 2001 From: Roger Steve Ruiz Date: Mon, 26 Mar 2018 14:40:10 -0400 Subject: [PATCH 19/59] Update prefix for admin and account logs --- tock/tock/signals.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/tock/tock/signals.py b/tock/tock/signals.py index b0fd03786..4e4ef7ea5 100644 --- a/tock/tock/signals.py +++ b/tock/tock/signals.py @@ -23,16 +23,16 @@ def adminlog_post_save(sender, instance, **kwargs): from django.contrib.admin.models import ADDITION, CHANGE, DELETION if instance.action_flag == ADDITION: logger.info( - f'{instance.user} created {instance.content_type} {instance.object_repr}.' + f'[admin-log] {instance.user} created {instance.content_type} {instance.object_repr} @ {instance.get_admin_url()}.' ) elif instance.action_flag == CHANGE: logger.info( - f'{instance.user} changed {instance.content_type} {instance.object_repr}: ' - f'{instance.change_message}.' + f'[admin-log] {instance.user} changed {instance.content_type} {instance.object_repr}: ' + f'{instance.change_message} @ {instance.get_admin_url()}.' ) elif instance.action_flag == DELETION: logger.info( - f'{instance.user} deleted {instance.content_type} {instance.object_repr}.' + f'[admin-log] {instance.user} deleted {instance.content_type} {instance.object_repr} @ {instance.get_admin_url()}.' ) def log_m2m_change(sender, instance, action, reverse, model, pk_set, **kwargs): @@ -41,18 +41,18 @@ def log_m2m_change(sender, instance, action, reverse, model, pk_set, **kwargs): if action == 'post_add': objects_added = list(model.objects.filter(pk__in=pk_set)) logger.info( - f'{model_name} given to {instance_model} {instance}: {objects_added}.' + f'[account-management] {model_name} given to {instance_model} {instance}: {objects_added}.' ) elif action == 'post_remove': objects_added = list(model.objects.filter(pk__in=pk_set)) logger.info( - f'{model_name} removed from {instance_model} {instance}: {objects_added}.' + f'[account-management] {model_name} removed from {instance_model} {instance}: {objects_added}.' ) logger.info("%s removed from %s '%s': %s", model_name, instance_model, instance, objects_added) elif action == 'post_clear': logger.info( - f'All {model_name} removed from {instance_model} {instance}.' + f'[account-management] All {model_name} removed from {instance_model} {instance}.' ) def setup_signals(): From 2171a029d57a0bda0203734bc12360a72a05048f Mon Sep 17 00:00:00 2001 From: Roger Steve Ruiz Date: Tue, 27 Mar 2018 17:01:28 -0400 Subject: [PATCH 20/59] Remove about yaml RIP :skull: --- about.yml | 80 ------------------------------------------------------- 1 file changed, 80 deletions(-) delete mode 100644 about.yml diff --git a/about.yml b/about.yml deleted file mode 100644 index fc5fa3c80..000000000 --- a/about.yml +++ /dev/null @@ -1,80 +0,0 @@ ---- -name: tock -full_name: Tock - -description: | - 18F uses Tock to track our time, so that we can bill clients accurately and meet our legal and regulatory obligations. - -impact: | - We built a web app that allows 18F employees to log the hours they spend on various projects. - We use this information for client billing and for internal analytics on what our team is working on. - -owner_type: project - -stage: live - -testable: true - -licenses: - tock: - name: Public Domain (CC0) - url: https://github.com/18F/tock/blob/master/LICENSE.md - -partners: -- 18F - -contact: -- url: https://github.com/18F/tock/issues - text: Tock Issue Tracker - -team: -- github: @joshuabailes - role: product owner - -- github: @abrouilette - role: project manager - -- github: @batemapf - role: developer - -- github: @annalee - role: tech lead - -- github: @maya - role: front-end design and development - -- github: @lauraponce - role: research - -type: app - -links: -- url: https://tock.18f.gov/ - text: Tock production site - -# What technologies are used in this project? -stack: -- Cloud.gov -- Cloud.gov authentication -- Docker -- Django - -# What are the services used to supply project status information? -# Items: -# - name: Name of the service -# category: Type of the service -# url: URL for detailed information -# badge: URL for the status badge -services: -- - -# Organizations or individuals who have adopted the project for their own use -# Items: -# - id: The name of the organization or individual -# url: A URL to the user's version of the project -users: -- - -# Tags that describe the project or aspects of the project -tags: -- From d3eaafafdc5580978e02b7edc4cb799240b4a131 Mon Sep 17 00:00:00 2001 From: Roger Steve Ruiz Date: Wed, 7 Mar 2018 16:33:15 -0500 Subject: [PATCH 21/59] Initial sketch for documentation; Pairing with @annalee --- docs/managing-uaa-clients.md | 68 ++++++++++++++++++++++++++ docs/releasing-tock.md | 66 +++++++++++++++++++++++++ docs/updating-user-provided-service.md | 29 +++++++++++ 3 files changed, 163 insertions(+) create mode 100644 docs/managing-uaa-clients.md create mode 100644 docs/releasing-tock.md create mode 100644 docs/updating-user-provided-service.md diff --git a/docs/managing-uaa-clients.md b/docs/managing-uaa-clients.md new file mode 100644 index 000000000..bcd2d0929 --- /dev/null +++ b/docs/managing-uaa-clients.md @@ -0,0 +1,68 @@ +# Creating UAA Clients for Tock + +Tock leverages [UAA authentication provided by cloud.gov][cg-uaa-auth] to +authenticate users. This document talks about how to create and rotate these UAA +clients using the [cf-cli][]. + + +[cf-cli]: https://cloudfoundry.org/ + + +Steps: + +- Creating the UAA client + - Setting the redirect URI +- Updating the user-provided service for Tock + +## Creating a UAA client + +Go read the [cloud.gov identity provider documentation][cg-uaa-auth] to learn +about creating the oAuth client. The Tock application only requires the `openid` +scope for the oAuth client. + +Tock uses the following naming convention for oAuth clients Service Instances +and Service Keys. + +
+Production oAuth client Service Name Example + +```shell +${APP_NAME}-${SERVICE_PLAN_NAME} +``` + +For instance, the Production oAuth client Service is called `tock-oauth-client`. + +
+ +
+ +
+Production oAuth client Service Key Example + +```shell +${APP_NAME}-${SERVICE_PLAN_NAME}-${YEARMONTHDAY} +``` + +For instance, the Production oAuth client Service Key is called `tock-oauth-client-20180307` because it was created on March 7th, 2018. + +
+ +[cg-uaa-auth]: https://cloud.gov/docs/services/cloud-gov-identity-provider/ + +### Setting the Redirect URI + +The redirect URI for Tock is whatever the URL is for the application with a path +of `/auth/callback` + +
+Production Redirect URI Example + +```shell +# ... + -c '{"redirect_uri": ["https://tock.18f.gov/auth/callback"]}' +``` + +Keep in mind that if you're deploying multiple Tock applications with different +URLs, you can add multiple `redirect_uri` URLs that end in `/auth/callback`. + +
diff --git a/docs/releasing-tock.md b/docs/releasing-tock.md new file mode 100644 index 000000000..a6eda7569 --- /dev/null +++ b/docs/releasing-tock.md @@ -0,0 +1,66 @@ +# Releasing Tock + +Releasing Tock onto Production happens whenever you create a Git tag and push it +up to the repository. The process is outlined below. + +## Creating a GitHub Release + + + +
+GitHub Release Template + +```markdown +### For Those About To Tock + +#### Liner Notes, XX/XX/XXXX + + +--- + +##### Stuff You Can See: + + + +- + +--- + +##### Admin-only Features: + + + +- + +--- + +##### Under The Hood: + + + +- + +--- + +##### Code Contributors for this release + +Team Tock would like to thank: + + + +- +``` + +
+ +## Create a Git Tag + + diff --git a/docs/updating-user-provided-service.md b/docs/updating-user-provided-service.md new file mode 100644 index 000000000..d9d8f71ae --- /dev/null +++ b/docs/updating-user-provided-service.md @@ -0,0 +1,29 @@ +# Updating User-Provided Service for Tock + +Tock leverages [Cloud Foundry User-Provided Service][cf-ups] to store +environment variables used in the running application. These values need to be +provided to the [cf-cli][] as valid JSON. + +**Warning** You're dealing with sensitive information! None of the output of +these commands should be committed into a repository or shared in Slack. + +Steps: + +- Downloading User-Provided Service credentials +- Uploading User-Provided Service credentials + +## Downloading User-Provided Service credentials + +Run the following command: + +```sh +cf env tock | grep -A20 'user-provided": \[' | grep -A20 'credentials": {' +``` +With the output of this command, you will be capturing the JSON found inside of +`"credentials": { ... }`. + + +``` + +``` + From d8426f23ed9ca690a773836ca5f13c147702eb85 Mon Sep 17 00:00:00 2001 From: Roger Steve Ruiz Date: Thu, 15 Mar 2018 15:06:01 -0400 Subject: [PATCH 22/59] Add links back to main README in /docs --- docs/README.md | 14 ++++++++++++++ docs/deploy.md | 2 ++ docs/managing-uaa-clients.md | 2 ++ docs/releasing-tock.md | 2 ++ docs/updating-user-provided-service.md | 2 ++ 5 files changed, 22 insertions(+) create mode 100644 docs/README.md diff --git a/docs/README.md b/docs/README.md new file mode 100644 index 000000000..980ef208d --- /dev/null +++ b/docs/README.md @@ -0,0 +1,14 @@ +# Tock documentation + +Welcome to the Tock documentation. This documentation is written in +[GitHub-flavored markdown][gh-md] and is best read using the GitHub interface. + +## Table of Contents + +- [Deploying Tock](deploy.md) +- [Managing UAA Clients](managing-uaa-clients.md) +- [Releasing Tock](releasing-tock.md) +- [Updating User-Provided Service variables](updating-user-provided-service.md) +- [Getting Started with Local Tock Development](local-development.md) + +[gh-md]: https://guides.github.com/features/mastering-markdown/#GitHub-flavored-markdown diff --git a/docs/deploy.md b/docs/deploy.md index 042992690..f13ed231e 100644 --- a/docs/deploy.md +++ b/docs/deploy.md @@ -1,5 +1,7 @@ ## Deploying to Cloud Foundry +[:arrow_left: Back to Tock Documentation](README.md) + **This section is only of interest to 18F team members.** Download the Cloud Foundry CLI according to the [cloud.gov instructions][]. diff --git a/docs/managing-uaa-clients.md b/docs/managing-uaa-clients.md index bcd2d0929..699d8e1bf 100644 --- a/docs/managing-uaa-clients.md +++ b/docs/managing-uaa-clients.md @@ -1,5 +1,7 @@ # Creating UAA Clients for Tock +[:arrow_left: Back to Tock Documentation](README.md) + Tock leverages [UAA authentication provided by cloud.gov][cg-uaa-auth] to authenticate users. This document talks about how to create and rotate these UAA clients using the [cf-cli][]. diff --git a/docs/releasing-tock.md b/docs/releasing-tock.md index a6eda7569..2e27c4e1f 100644 --- a/docs/releasing-tock.md +++ b/docs/releasing-tock.md @@ -1,5 +1,7 @@ # Releasing Tock +[:arrow_left: Back to Tock Documentation](README.md) + Releasing Tock onto Production happens whenever you create a Git tag and push it up to the repository. The process is outlined below. diff --git a/docs/updating-user-provided-service.md b/docs/updating-user-provided-service.md index d9d8f71ae..ca0d20a96 100644 --- a/docs/updating-user-provided-service.md +++ b/docs/updating-user-provided-service.md @@ -1,5 +1,7 @@ # Updating User-Provided Service for Tock +[:arrow_left: Back to Tock Documentation](README.md) + Tock leverages [Cloud Foundry User-Provided Service][cf-ups] to store environment variables used in the running application. These values need to be provided to the [cf-cli][] as valid JSON. From 003b6a8486edce2987ce1553e71c136e72bd1cc0 Mon Sep 17 00:00:00 2001 From: Roger Steve Ruiz Date: Fri, 16 Mar 2018 10:26:36 -0400 Subject: [PATCH 23/59] Progress on ATO documentation --- docs/README.md | 9 +- docs/api.md | 17 +++ docs/authentication.md | 74 ++++++++++++ docs/{deploy.md => deployment-process.md} | 0 docs/local-development.md | 110 ++++++++++++++++++ docs/logging.md | 53 +++++++++ docs/managing-uaa-clients.md | 70 ----------- ...eleasing-tock.md => release-management.md} | 0 8 files changed, 259 insertions(+), 74 deletions(-) create mode 100644 docs/api.md create mode 100644 docs/authentication.md rename docs/{deploy.md => deployment-process.md} (100%) create mode 100644 docs/local-development.md create mode 100644 docs/logging.md delete mode 100644 docs/managing-uaa-clients.md rename docs/{releasing-tock.md => release-management.md} (100%) diff --git a/docs/README.md b/docs/README.md index 980ef208d..264766211 100644 --- a/docs/README.md +++ b/docs/README.md @@ -5,10 +5,11 @@ Welcome to the Tock documentation. This documentation is written in ## Table of Contents -- [Deploying Tock](deploy.md) -- [Managing UAA Clients](managing-uaa-clients.md) -- [Releasing Tock](releasing-tock.md) -- [Updating User-Provided Service variables](updating-user-provided-service.md) - [Getting Started with Local Tock Development](local-development.md) +- [Tock API](api.md) +- [Tock Authentication](authentication.md) +- [Tock Deployment Process](deployment-process.md) +- [Tock Release Management](release-management.md) +- [Tock Logging](logging.md) [gh-md]: https://guides.github.com/features/mastering-markdown/#GitHub-flavored-markdown diff --git a/docs/api.md b/docs/api.md new file mode 100644 index 000000000..0ce9b92e2 --- /dev/null +++ b/docs/api.md @@ -0,0 +1,17 @@ +## Tock API + +[:arrow_left: Back to Tock Documentation](..) + +Tock has an API! You may issue GET requests to various [endpoints](https://github.com/18F/tock/tree/master/api-docs) via the /api/ path with results returned as JSON objects. We use Django REST framework's TokenAuthentication library which requires all requests to include a token value in your request header using the following format (a cURL command line based request is used for this example for getting project data from our Tock deployment): + +``` +$ curl https://tock.18f.gov/api/projects.json -H 'Authorization: Token randomalphanumericstringed854b18ba024327' +``` + +To obtain your own Tock API authorization token, please visit +[#tock-dev](https://gsa-tts.slack.com/messages/tock-dev/) on Slack and ping a +Tock Developer. + +To access similar data in CSV format from within Tock, please visit the +[/reports](https://tock.18f.gov/reports) page. + diff --git a/docs/authentication.md b/docs/authentication.md new file mode 100644 index 000000000..4f761025b --- /dev/null +++ b/docs/authentication.md @@ -0,0 +1,74 @@ +## Tock Authentication + +[:arrow_left: Back to Tock Documentation](..) + +18F's current deployment of Tock relies on +[cloud.gov's User Account and Authentication (UAA) server][UAA] for +authentication. + +During development, a ["fake" cloud.gov UAA server][fakeUAA] is used for +authentication. Here you can actually enter any email address; if the +address is `@gsa.gov`, then a non-staff account will automatically +be created for the user and you'll be logged-in, but otherwise access +will be denied. + +The easiest way to create an administrative user is to first use +`manage.py createsuperuser` to create a user, and then log in +with that user's email address. See the "Getting Started" section +for an example of this. + +[UAA]: https://cloud.gov/docs/apps/leveraging-authentication/ +[fakeUAA]: http://cg-django-uaa.readthedocs.io/en/latest/quickstart.html#using-the-fake-cloud-gov-server + +### Creating UAA Clients for Tock + +Tock leverages [UAA authentication provided by cloud.gov][cg-uaa-auth] to +authenticate users. This document talks about how to create and rotate these UAA +clients using the [cf-cli][]. The following documentation assumes you are +[comfortable using the cf-cli][cf-cli-docs]. + +[cf-cli]: https://github.com/cloudfoundry/cli +[cf-cli-docs]: https://docs.cloudfoundry.org/cf-cli/install-go-cli.html + +#### Creating a UAA client + +Go read the [cloud.gov identity provider documentation][cg-uaa-auth] to learn +about creating the oAuth client. The Tock application only requires the `openid` +scope for the oAuth client. + +Tock uses the following naming convention for oAuth clients Service Instances +and Service Keys. + +##### Production oAuth client Service Name Example + +```shell +${APP_NAME}-${SERVICE_PLAN_NAME} +``` + +For instance, the Production oAuth client Service is called `tock-oauth-client`. + +##### Production oAuth client Service Key Example + +```shell +${APP_NAME}-${SERVICE_PLAN_NAME}-${YEARMONTHDAY} +``` + +For instance, the Production oAuth client Service Key is called +`tock-oauth-client-20180307` because it was created on March 7th, 2018. + +[cg-uaa-auth]: https://cloud.gov/docs/services/cloud-gov-identity-provider/ + +#### Setting the Redirect URI + +The redirect URI for Tock is whatever the URL is for the application with a path +of `/auth/callback` + +##### Production Redirect URI Example + +```shell +# ... + -c '{"redirect_uri": ["https://tock.18f.gov/auth/callback"]}' +``` + +Keep in mind that if you're deploying multiple Tock applications with different +URLs, you can add multiple `redirect_uri` URLs that end in `/auth/callback`. diff --git a/docs/deploy.md b/docs/deployment-process.md similarity index 100% rename from docs/deploy.md rename to docs/deployment-process.md diff --git a/docs/local-development.md b/docs/local-development.md new file mode 100644 index 000000000..ec3575a45 --- /dev/null +++ b/docs/local-development.md @@ -0,0 +1,110 @@ +## Getting Started with Local Tock Development + +[:arrow_left: Back to Tock Documentation](README.md) + +1. Install [Docker][]. If you're on OS X, install Docker for Mac. If you're on Windows, install Docker for Windows. + +1. Move into the `tock` directory at the repository root: + + ``` + $ cd tock + ``` + +1. Run: + + ```shell + $ docker-compose build + $ docker-compose run app python manage.py migrate + $ docker-compose run app python manage.py loaddata test_data/data-update-deduped.json + $ docker-compose run app python manage.py createsuperuser --username admin@gsa.gov --email admin@gsa.gov --noinput + ``` + +1. Once the above commands are successful, run: + + ``` + docker-compose up + ``` + + This will start up all required servers in containers and output their + log information to stdout. + +1. Visit [http://localhost:8000/][] directly to access the site. + + When prompted for an email address, enter `admin@gsa.gov`. + +You can access the admin panel at `/admin`. + +### Running static analysis tools + +We run two linting tools in continuous integration, +[`flake8`](http://flake8.pycqa.org/en/latest/) for general linting of unused +variables, style, etc. and [`bandit`](https://pypi.python.org/pypi/bandit), a +security-focused linter. + +To run this locally, run: +```sh +docker-compose run app bandit -r . -x manage.py,docker_entrypoint.py +docker-compose run app flake8 +``` + +### Accessing the app container + +You'll likely want to run `manage.py` to do other things at some point. +To do this, it's probably easiest to run: + +``` +docker-compose run app bash +``` + +This will run an interactive bash session inside the main app container. +In this container, the `/tock` directory is mapped to the `tock` +directory of the repository on your host; you can run `manage.py` from there. + +#### Running `pdb` within the Docker container + +Once you have a running set containers, you should be able to attach to the +`tock_app` CONTAINER_ID using the following command. + +```sh +docker attach $(docker container ps | grep -E 'tock_app' | awk '{ print $1 }') +``` + +This will drop you into the `tock_app` container. Now you can use `pdb` in your +local code and have a Python Debugger. + +##### Exiting the debugger + +To properly exit the debugger, use the following keyboard commands within the +container: `Control + p, Control + q` one after another. + +If you mistakenly hit `Control + c` you will kill the `tock_app` container! In +that case, restart the `tock_app` container with a `docker-compose up` command. + +### Making CSS changes + +`docker-compose up` will also launch a [Node] machine that compiles the [Sass] +files in `tock/tock/static/sass` into corresponding CSS files in +`tock/tock/static/css/dist`. **The generated CSS files are not checked into +git, and should not be modified by hand.** + +You can also run the CSS build and watch scripts outside of the Docker +container. Just install [Node][] (e.g. with `brew install node` on OS X), then +install the dependencies with: + +```sh +npm install +``` + +Assuming that goes off without a hitch, you can then either build the CSS in +one go with: + +``` +npm run build-css +``` + +or start the watch process, which builds new CSS whenever the source Sass files +are changed: + +``` +npm run watch-css +``` diff --git a/docs/logging.md b/docs/logging.md new file mode 100644 index 000000000..ff2a92149 --- /dev/null +++ b/docs/logging.md @@ -0,0 +1,53 @@ +# Tock Logging + +[:arrow_left: Back to Tock Documentation](..) + +Tock leverages cloud.gov logging system which runs on the Elastic Logsearch +Kibana (ELK) software stack. Logs for the Tock system are available to +Tock Developers with cloud.gov access. For more information about cloud.gov's +logging system, [please read the documentation][cg-logs]. + +[cg-logs]: https://cloud.gov/docs/apps/logs/ + +## Kibana Queries + +The following logging events (LE) are documented below for developers to easily +access using [cloud.gov's logging system][cg-log-sys]. + +[cg-log-sys]: https://logs.fr.cloud.gov + +### Account Events + +#### Account Logon Events + +#### Account Management Events + +#### Authentication Checks + +#### Authorization Checks + +#### All Administrator Activity + +#### Permission Changes + +### Application Events + +#### Policy Change + +#### Privilege functions + +#### Process Tracking + +#### System events + +#### Object Access + +### Data Events + +#### Data Deletion + +#### Data Access + +#### Data Changes + + diff --git a/docs/managing-uaa-clients.md b/docs/managing-uaa-clients.md deleted file mode 100644 index 699d8e1bf..000000000 --- a/docs/managing-uaa-clients.md +++ /dev/null @@ -1,70 +0,0 @@ -# Creating UAA Clients for Tock - -[:arrow_left: Back to Tock Documentation](README.md) - -Tock leverages [UAA authentication provided by cloud.gov][cg-uaa-auth] to -authenticate users. This document talks about how to create and rotate these UAA -clients using the [cf-cli][]. - - -[cf-cli]: https://cloudfoundry.org/ - - -Steps: - -- Creating the UAA client - - Setting the redirect URI -- Updating the user-provided service for Tock - -## Creating a UAA client - -Go read the [cloud.gov identity provider documentation][cg-uaa-auth] to learn -about creating the oAuth client. The Tock application only requires the `openid` -scope for the oAuth client. - -Tock uses the following naming convention for oAuth clients Service Instances -and Service Keys. - -
-Production oAuth client Service Name Example - -```shell -${APP_NAME}-${SERVICE_PLAN_NAME} -``` - -For instance, the Production oAuth client Service is called `tock-oauth-client`. - -
- -
- -
-Production oAuth client Service Key Example - -```shell -${APP_NAME}-${SERVICE_PLAN_NAME}-${YEARMONTHDAY} -``` - -For instance, the Production oAuth client Service Key is called `tock-oauth-client-20180307` because it was created on March 7th, 2018. - -
- -[cg-uaa-auth]: https://cloud.gov/docs/services/cloud-gov-identity-provider/ - -### Setting the Redirect URI - -The redirect URI for Tock is whatever the URL is for the application with a path -of `/auth/callback` - -
-Production Redirect URI Example - -```shell -# ... - -c '{"redirect_uri": ["https://tock.18f.gov/auth/callback"]}' -``` - -Keep in mind that if you're deploying multiple Tock applications with different -URLs, you can add multiple `redirect_uri` URLs that end in `/auth/callback`. - -
diff --git a/docs/releasing-tock.md b/docs/release-management.md similarity index 100% rename from docs/releasing-tock.md rename to docs/release-management.md From 34e2418c280647c7320c9e02878024d5178149d5 Mon Sep 17 00:00:00 2001 From: Roger Steve Ruiz Date: Mon, 19 Mar 2018 13:52:18 -0400 Subject: [PATCH 24/59] Make it a table for readability --- docs/logging.md | 59 ++++++++++++++++++++----------------------------- 1 file changed, 24 insertions(+), 35 deletions(-) diff --git a/docs/logging.md b/docs/logging.md index ff2a92149..28b2b3fa8 100644 --- a/docs/logging.md +++ b/docs/logging.md @@ -16,38 +16,27 @@ access using [cloud.gov's logging system][cg-log-sys]. [cg-log-sys]: https://logs.fr.cloud.gov -### Account Events - -#### Account Logon Events - -#### Account Management Events - -#### Authentication Checks - -#### Authorization Checks - -#### All Administrator Activity - -#### Permission Changes - -### Application Events - -#### Policy Change - -#### Privilege functions - -#### Process Tracking - -#### System events - -#### Object Access - -### Data Events - -#### Data Deletion - -#### Data Access - -#### Data Changes - - +| Description | Kibana Query | +| -------------------------- | ------------------------------------------------- | +| Deployments | `@cf.app:"tock" AND @cf.message:"Recorded deployment"` | +| Authorization checks | `@cf.app:"tock" AND @cf.message:"Authorization check"` | +| Authentication checks | `@cf.app:"tock" AND @cf.message:"Authentication check"` | +| Successful login events | `@cf.app:"tock" AND @cf.message:"Successful login"` | +| Unsuccessful login events | `@cf.app:"tock" AND @cf.message:"Unsuccessful login"` | +| Object access * | `@cf.app:"tock" AND gsa18f_procurements` | +| Account management events | `@cf.app:"tock" AND ((versions AND User) OR user_roles)` | +| All administrator activity | `@cf.app:"tock" AND admin` | +| Data deletions ** | `@cf.app:"tock" AND DELETE` | +| Data access ** | `@cf.app:"tock" AND SELECT` | +| Data changes ** | `@cf.app:"tock" AND (UPDATE OR INSERT)` | +| Permission Changes | `@cf.app:"tock" AND user_roles AND INSERT` | + +\* For "object access" search by database table name. + +\** For these queries, consider including a table name like `@cf.app:"tock" AND SELECT AND proposals` + + +Some table names: +- `` + +https://docs.djangoproject.com/en/dev/ref/contrib/auth/#module-django.contrib.auth.signals From e6d00511fff94acaf41c5a8904041aa8e97af2d1 Mon Sep 17 00:00:00 2001 From: Roger Steve Ruiz Date: Mon, 19 Mar 2018 16:46:45 -0400 Subject: [PATCH 25/59] Fix links back to readme section --- docs/api.md | 3 ++- docs/authentication.md | 3 ++- docs/deployment-process.md | 3 ++- docs/local-development.md | 3 ++- docs/logging.md | 3 ++- docs/updating-user-provided-service.md | 3 ++- 6 files changed, 12 insertions(+), 6 deletions(-) diff --git a/docs/api.md b/docs/api.md index 0ce9b92e2..e3a7838ba 100644 --- a/docs/api.md +++ b/docs/api.md @@ -1,6 +1,7 @@ ## Tock API -[:arrow_left: Back to Tock Documentation](..) +[:arrow_left: Back to Tock +Documentation](https://github.com/18F/tock/tree/master/docs) Tock has an API! You may issue GET requests to various [endpoints](https://github.com/18F/tock/tree/master/api-docs) via the /api/ path with results returned as JSON objects. We use Django REST framework's TokenAuthentication library which requires all requests to include a token value in your request header using the following format (a cURL command line based request is used for this example for getting project data from our Tock deployment): diff --git a/docs/authentication.md b/docs/authentication.md index 4f761025b..aed76cc81 100644 --- a/docs/authentication.md +++ b/docs/authentication.md @@ -1,6 +1,7 @@ ## Tock Authentication -[:arrow_left: Back to Tock Documentation](..) +[:arrow_left: Back to Tock +Documentation](https://github.com/18F/tock/tree/master/docs) 18F's current deployment of Tock relies on [cloud.gov's User Account and Authentication (UAA) server][UAA] for diff --git a/docs/deployment-process.md b/docs/deployment-process.md index f13ed231e..e15ee7fad 100644 --- a/docs/deployment-process.md +++ b/docs/deployment-process.md @@ -1,6 +1,7 @@ ## Deploying to Cloud Foundry -[:arrow_left: Back to Tock Documentation](README.md) +[:arrow_left: Back to Tock +Documentation](https://github.com/18F/tock/tree/master/docs) **This section is only of interest to 18F team members.** diff --git a/docs/local-development.md b/docs/local-development.md index ec3575a45..d5c7f37b3 100644 --- a/docs/local-development.md +++ b/docs/local-development.md @@ -1,6 +1,7 @@ ## Getting Started with Local Tock Development -[:arrow_left: Back to Tock Documentation](README.md) +[:arrow_left: Back to Tock +Documentation](https://github.com/18F/tock/tree/master/docs) 1. Install [Docker][]. If you're on OS X, install Docker for Mac. If you're on Windows, install Docker for Windows. diff --git a/docs/logging.md b/docs/logging.md index 28b2b3fa8..cf49fe45b 100644 --- a/docs/logging.md +++ b/docs/logging.md @@ -1,6 +1,7 @@ # Tock Logging -[:arrow_left: Back to Tock Documentation](..) +[:arrow_left: Back to Tock +Documentation](https://github.com/18F/tock/tree/master/docs) Tock leverages cloud.gov logging system which runs on the Elastic Logsearch Kibana (ELK) software stack. Logs for the Tock system are available to diff --git a/docs/updating-user-provided-service.md b/docs/updating-user-provided-service.md index ca0d20a96..0e494d12e 100644 --- a/docs/updating-user-provided-service.md +++ b/docs/updating-user-provided-service.md @@ -1,6 +1,7 @@ # Updating User-Provided Service for Tock -[:arrow_left: Back to Tock Documentation](README.md) +[:arrow_left: Back to Tock +Documentation](https://github.com/18F/tock/tree/master/docs) Tock leverages [Cloud Foundry User-Provided Service][cf-ups] to store environment variables used in the running application. These values need to be From 7f7eb36716a0041e8e10621fdf9a6bb1a466cb12 Mon Sep 17 00:00:00 2001 From: Roger Steve Ruiz Date: Mon, 19 Mar 2018 16:47:35 -0400 Subject: [PATCH 26/59] Update docs with API usage --- docs/api.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/docs/api.md b/docs/api.md index e3a7838ba..79299da0e 100644 --- a/docs/api.md +++ b/docs/api.md @@ -16,3 +16,10 @@ Tock Developer. To access similar data in CSV format from within Tock, please visit the [/reports](https://tock.18f.gov/reports) page. +### Tock API usages + +The Tock API is used in various ways by Tock Administrators and Tock Users. +Below are some examples of Tock API usage. + +- [AngryTock Slack Bot](https://github.com/18F/angrytock) +- [Google App Script](https://github.com/18F/tock-gas-ts) From 27fdd4847afb6efde4ca311a0df155e403a1d55f Mon Sep 17 00:00:00 2001 From: Roger Steve Ruiz Date: Mon, 19 Mar 2018 16:47:54 -0400 Subject: [PATCH 27/59] Reformat table, again --- docs/logging.md | 29 ++++++++++++++--------------- 1 file changed, 14 insertions(+), 15 deletions(-) diff --git a/docs/logging.md b/docs/logging.md index cf49fe45b..8aee6c3a3 100644 --- a/docs/logging.md +++ b/docs/logging.md @@ -17,26 +17,25 @@ access using [cloud.gov's logging system][cg-log-sys]. [cg-log-sys]: https://logs.fr.cloud.gov -| Description | Kibana Query | -| -------------------------- | ------------------------------------------------- | -| Deployments | `@cf.app:"tock" AND @cf.message:"Recorded deployment"` | -| Authorization checks | `@cf.app:"tock" AND @cf.message:"Authorization check"` | -| Authentication checks | `@cf.app:"tock" AND @cf.message:"Authentication check"` | -| Successful login events | `@cf.app:"tock" AND @cf.message:"Successful login"` | -| Unsuccessful login events | `@cf.app:"tock" AND @cf.message:"Unsuccessful login"` | -| Object access * | `@cf.app:"tock" AND gsa18f_procurements` | -| Account management events | `@cf.app:"tock" AND ((versions AND User) OR user_roles)` | -| All administrator activity | `@cf.app:"tock" AND admin` | -| Data deletions ** | `@cf.app:"tock" AND DELETE` | -| Data access ** | `@cf.app:"tock" AND SELECT` | -| Data changes ** | `@cf.app:"tock" AND (UPDATE OR INSERT)` | -| Permission Changes | `@cf.app:"tock" AND user_roles AND INSERT` | +| Description | Kibana Query | +| -------------------------- | ---------------------------------------------------------- | +| Deployments | `@cf.app:"tock" AND @cf.message:"Recorded deployment"` | +| Authorization checks | `@cf.app:"tock" AND @cf.message:"Authorization check"` | +| Authentication checks | `@cf.app:"tock" AND @cf.message:"Authentication check"` | +| Successful login events | `@cf.app:"tock" AND @cf.message:"Successful login"` | +| Unsuccessful login events | `@cf.app:"tock" AND @cf.message:"Unsuccessful login"` | +| Object access * | `@cf.app:"tock" AND gsa18f_procurements` | +| Account management events | `@cf.app:"tock" AND ((versions AND User) OR user_roles)` | +| All administrator activity | `@cf.app:"tock" AND admin` | +| Data deletions ** | `@cf.app:"tock" AND DELETE` | +| Data access ** | `@cf.app:"tock" AND SELECT` | +| Data changes ** | `@cf.app:"tock" AND (UPDATE OR INSERT)` | +| Permission Changes | `@cf.app:"tock" AND user_roles AND INSERT` | \* For "object access" search by database table name. \** For these queries, consider including a table name like `@cf.app:"tock" AND SELECT AND proposals` - Some table names: - `` From d0495c22efc460c809c85c9b6c5f085b33746e2a Mon Sep 17 00:00:00 2001 From: Roger Steve Ruiz Date: Wed, 21 Mar 2018 14:42:48 -0400 Subject: [PATCH 28/59] Update back to docs link --- docs/release-management.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/release-management.md b/docs/release-management.md index 2e27c4e1f..a494fcdc7 100644 --- a/docs/release-management.md +++ b/docs/release-management.md @@ -1,6 +1,7 @@ # Releasing Tock -[:arrow_left: Back to Tock Documentation](README.md) +[:arrow_left: Back to Tock +Documentation](https://github.com/18F/tock/tree/master/docs) Releasing Tock onto Production happens whenever you create a Git tag and push it up to the repository. The process is outlined below. From 2516403e01966216eea7aa58c1f3538abaad11e8 Mon Sep 17 00:00:00 2001 From: Roger Steve Ruiz Date: Fri, 23 Mar 2018 10:35:40 -0400 Subject: [PATCH 29/59] Add start of onboarding/offboarding docs --- docs/README.md | 2 ++ docs/offboarding.md | 1 + docs/onboarding.md | 46 +++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 49 insertions(+) create mode 100644 docs/offboarding.md create mode 100644 docs/onboarding.md diff --git a/docs/README.md b/docs/README.md index 264766211..d9bb3aa13 100644 --- a/docs/README.md +++ b/docs/README.md @@ -11,5 +11,7 @@ Welcome to the Tock documentation. This documentation is written in - [Tock Deployment Process](deployment-process.md) - [Tock Release Management](release-management.md) - [Tock Logging](logging.md) +- [Tock Developer Onboarding](onboarding.md) +- [Tock Developer Offboarding](offboarding.md) [gh-md]: https://guides.github.com/features/mastering-markdown/#GitHub-flavored-markdown diff --git a/docs/offboarding.md b/docs/offboarding.md new file mode 100644 index 000000000..ec74d6f5c --- /dev/null +++ b/docs/offboarding.md @@ -0,0 +1 @@ +# Tock Offboarding diff --git a/docs/onboarding.md b/docs/onboarding.md new file mode 100644 index 000000000..7d2d24314 --- /dev/null +++ b/docs/onboarding.md @@ -0,0 +1,46 @@ +# Joining the Tock team + +## Onboarding + +When you join the Tock team, you may be expected to complete the following +onboarding checklist on with minimal guidance. The Tock Product Owner may +schedule check-in time with you to ensure that you're progressing and aren't +stuck. If there is another Tock developer already on the project, you will be +assigned them as a buddy to help you progress through onboarding. + +### Things we maintain + +- [Tock](tock-app), a Python Django framework web application comprised of multiple + sub-apps. + - tock + - employees + - projects + - hours + - organizations + - api + - utilization +- [AngryTock](tock-bot), a Golang Slack RTM-based bot +- [#tock-dev](tock-chat), a Slack channel where Tock users come for technical + support. + +[tock-app]: https://github.com/18F/tock +[tock-bot]: https://github.com/18F/angrytock +[tock-chat]: https://gsa-tts.slack.com/messages/C1JFYCX3P + +### Important terminology and context + +- [cloud.gov][docs-cg] - The PaaS that Tock uses to deploy all the apps +- [Postgres][docs-psql] - The database backend that the Tock application uses +- [Python][docs-python] - The language that the Tock app uses +- [Golang][docs-golang ]- The language that the AngryTock Slack bot uses +- [Django Web Framework][docs-django] - The application framework that the Tock application is + built with. +- [Slack Real-Time Messaging (RTM) API][docs-slack-rtm] - The Slack API that AngryTock uses to + communicate via Slack + +[docs-cg]: https://cloud.gov/docs/ +[docs-psql]: https://www.postgresql.org/docs/ +[docs-python]: https://docs.python.org/3/ +[docs-golang]: https://golang.org/doc/ +[docs-django]: https://docs.djangoproject.com/en/1.11/ +[docs-slack-rtm]: https://api.slack.com/rtm From 3254a97464098dfb4e8599cf96e6d467cacc1a9d Mon Sep 17 00:00:00 2001 From: Roger Steve Ruiz Date: Fri, 23 Mar 2018 12:16:27 -0400 Subject: [PATCH 30/59] Update logging documentation with work from #766 --- docs/logging.md | 42 +++++++++++++++++++++++++++++++++++++----- 1 file changed, 37 insertions(+), 5 deletions(-) diff --git a/docs/logging.md b/docs/logging.md index 8aee6c3a3..40d818c21 100644 --- a/docs/logging.md +++ b/docs/logging.md @@ -24,7 +24,7 @@ access using [cloud.gov's logging system][cg-log-sys]. | Authentication checks | `@cf.app:"tock" AND @cf.message:"Authentication check"` | | Successful login events | `@cf.app:"tock" AND @cf.message:"Successful login"` | | Unsuccessful login events | `@cf.app:"tock" AND @cf.message:"Unsuccessful login"` | -| Object access * | `@cf.app:"tock" AND gsa18f_procurements` | +| Object access * | `@cf.app:"tock" AND ` | | Account management events | `@cf.app:"tock" AND ((versions AND User) OR user_roles)` | | All administrator activity | `@cf.app:"tock" AND admin` | | Data deletions ** | `@cf.app:"tock" AND DELETE` | @@ -32,11 +32,43 @@ access using [cloud.gov's logging system][cg-log-sys]. | Data changes ** | `@cf.app:"tock" AND (UPDATE OR INSERT)` | | Permission Changes | `@cf.app:"tock" AND user_roles AND INSERT` | -\* For "object access" search by database table name. +\* For "object access" search by database table name or Model name -\** For these queries, consider including a table name like `@cf.app:"tock" AND SELECT AND proposals` +\** For these queries, consider including a table name like `@cf.app:"tock" AND SELECT AND employees_employeegrade` Some table names: -- `` +- `employees_employeegrade` +- `employees_userdata` +- `hours_holidayprefills` +- `hours_reportingperiod` +- `hours_reportingperiod_holiday_prefills` +- `hours_targets` +- `hours_timecard` +- `hours_timecardnote` +- `hours_timecardobject` +- `hours_timecardprefilldata` +- `organizations_organization` +- `projects_accountingcode` +- `projects_agency` +- `projects_profitlossaccount` +- `projects_project` +- `projects_project_alerts` +- `projects_projectalert` -https://docs.djangoproject.com/en/dev/ref/contrib/auth/#module-django.contrib.auth.signals +Some Model names: +- `EmployeeGrade` +- `UserData` +- `HolidayPrefills` +- `ReportingPeriod` +- `Targets` +- `Timecard` +- `TimecardNote` +- `TimecardObject` +- `TimecardPrefillData` +- `Organization` +- `AccountingCode` +- `Agency` +- `ProfitLossAccount` +- `Project` +- `ProjectAlerts` +- `ProjectAlert` From f03432eac1b83b085aa01426c9ad8463a6933092 Mon Sep 17 00:00:00 2001 From: Roger Steve Ruiz Date: Fri, 23 Mar 2018 12:36:31 -0400 Subject: [PATCH 31/59] Update onboarding docs --- docs/onboarding.md | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/docs/onboarding.md b/docs/onboarding.md index 7d2d24314..4beefa01c 100644 --- a/docs/onboarding.md +++ b/docs/onboarding.md @@ -8,7 +8,7 @@ schedule check-in time with you to ensure that you're progressing and aren't stuck. If there is another Tock developer already on the project, you will be assigned them as a buddy to help you progress through onboarding. -### Things we maintain +## Things we maintain - [Tock](tock-app), a Python Django framework web application comprised of multiple sub-apps. @@ -35,12 +35,24 @@ assigned them as a buddy to help you progress through onboarding. - [Golang][docs-golang ]- The language that the AngryTock Slack bot uses - [Django Web Framework][docs-django] - The application framework that the Tock application is built with. +- [Django Rest Framework][docs-django-rest] - The REST framework that the Tock + application is built with. - [Slack Real-Time Messaging (RTM) API][docs-slack-rtm] - The Slack API that AngryTock uses to communicate via Slack +- [cloud.gov identity provider][docs-cg-idp] - The identity provider that Tock + uses for user authentication. +- [cloud.gov service account][docs-cg-sa] - The service account that Tock uses + for deployments. +- [cloud.gov UAA authentication backend][docs-django-uaa] - The UAA client that + the Tock application uses to leverage the cloud.gov identity provider. [docs-cg]: https://cloud.gov/docs/ +[docs-cg-idp]: https://cloud.gov/docs/services/cloud-gov-identity-provider/ +[docs-cg-sa]: https://cloud.gov/docs/services/cloud-gov-service-account/ [docs-psql]: https://www.postgresql.org/docs/ [docs-python]: https://docs.python.org/3/ [docs-golang]: https://golang.org/doc/ [docs-django]: https://docs.djangoproject.com/en/1.11/ +[docs-django-rest]: http://www.django-rest-framework.org +[docs-django-uaa]: http://cg-django-uaa.readthedocs.io/en/latest/ [docs-slack-rtm]: https://api.slack.com/rtm From c11a7fc972d16dc36f7b9de68e7205333460d3b7 Mon Sep 17 00:00:00 2001 From: Roger Steve Ruiz Date: Fri, 23 Mar 2018 16:40:45 -0400 Subject: [PATCH 32/59] Final API edits --- docs/api.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/api.md b/docs/api.md index 79299da0e..734c74eb4 100644 --- a/docs/api.md +++ b/docs/api.md @@ -1,4 +1,4 @@ -## Tock API +# Tock API [:arrow_left: Back to Tock Documentation](https://github.com/18F/tock/tree/master/docs) @@ -16,7 +16,7 @@ Tock Developer. To access similar data in CSV format from within Tock, please visit the [/reports](https://tock.18f.gov/reports) page. -### Tock API usages +# Usages The Tock API is used in various ways by Tock Administrators and Tock Users. Below are some examples of Tock API usage. From 5c4917b37f8ed3c7d98ba5c4165027ca27236106 Mon Sep 17 00:00:00 2001 From: Roger Steve Ruiz Date: Fri, 23 Mar 2018 17:29:41 -0400 Subject: [PATCH 33/59] Update logging table --- docs/logging.md | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/docs/logging.md b/docs/logging.md index 40d818c21..13ac618df 100644 --- a/docs/logging.md +++ b/docs/logging.md @@ -17,20 +17,20 @@ access using [cloud.gov's logging system][cg-log-sys]. [cg-log-sys]: https://logs.fr.cloud.gov -| Description | Kibana Query | -| -------------------------- | ---------------------------------------------------------- | -| Deployments | `@cf.app:"tock" AND @cf.message:"Recorded deployment"` | -| Authorization checks | `@cf.app:"tock" AND @cf.message:"Authorization check"` | -| Authentication checks | `@cf.app:"tock" AND @cf.message:"Authentication check"` | -| Successful login events | `@cf.app:"tock" AND @cf.message:"Successful login"` | -| Unsuccessful login events | `@cf.app:"tock" AND @cf.message:"Unsuccessful login"` | -| Object access * | `@cf.app:"tock" AND ` | -| Account management events | `@cf.app:"tock" AND ((versions AND User) OR user_roles)` | -| All administrator activity | `@cf.app:"tock" AND admin` | -| Data deletions ** | `@cf.app:"tock" AND DELETE` | -| Data access ** | `@cf.app:"tock" AND SELECT` | -| Data changes ** | `@cf.app:"tock" AND (UPDATE OR INSERT)` | -| Permission Changes | `@cf.app:"tock" AND user_roles AND INSERT` | +| Description | Kibana Query | +| -------------------------- | -------------------------------------------------------------- | +| Deployments | `@cf.app:"tock" AND @message:"Recording deployment of"` | +| Authorization checks | `@cf.app:"tock" AND @message:"tock-auth"` | +| Authentication checks | `@cf.app:"tock" AND @message:"Authenticating user"` | +| Successful login events | `@cf.app:"tock" AND @message:"Successful login"` | +| Unsuccessful login events | `@cf.app:"tock" AND @message:"Unsuccessful login"` | +| Object access * | `@cf.app:"tock" AND ` | +| Account management events | `@cf.app:"tock" AND ((versions AND User) OR user_roles)` | +| All administrator activity | `@cf.app:"tock" AND admin` | +| Data deletions ** | `@cf.app:"tock" AND DELETE` | +| Data access ** | `@cf.app:"tock" AND SELECT` | +| Data changes ** | `@cf.app:"tock" AND (UPDATE OR INSERT)` | +| Permission Changes | `@cf.app:"tock" AND user_roles AND INSERT` | \* For "object access" search by database table name or Model name From a697076b897d304b93d3fa8e0a9d52702287f0df Mon Sep 17 00:00:00 2001 From: Roger Steve Ruiz Date: Mon, 26 Mar 2018 15:45:33 -0400 Subject: [PATCH 34/59] Documentation brought in alignment with #766 --- docs/logging.md | 52 +++++++++++++++++++++++-------------------------- 1 file changed, 24 insertions(+), 28 deletions(-) diff --git a/docs/logging.md b/docs/logging.md index 13ac618df..5d60e1766 100644 --- a/docs/logging.md +++ b/docs/logging.md @@ -24,37 +24,16 @@ access using [cloud.gov's logging system][cg-log-sys]. | Authentication checks | `@cf.app:"tock" AND @message:"Authenticating user"` | | Successful login events | `@cf.app:"tock" AND @message:"Successful login"` | | Unsuccessful login events | `@cf.app:"tock" AND @message:"Unsuccessful login"` | -| Object access * | `@cf.app:"tock" AND ` | -| Account management events | `@cf.app:"tock" AND ((versions AND User) OR user_roles)` | -| All administrator activity | `@cf.app:"tock" AND admin` | -| Data deletions ** | `@cf.app:"tock" AND DELETE` | -| Data access ** | `@cf.app:"tock" AND SELECT` | -| Data changes ** | `@cf.app:"tock" AND (UPDATE OR INSERT)` | -| Permission Changes | `@cf.app:"tock" AND user_roles AND INSERT` | +| Object access * | `@cf.app:"tock" AND TimecardObject` | +| Account management events | `@cf.app:"tock" AND @message:"account-management"` | +| All administrator activity | `@cf.app:"tock" AND @message:"admin-log"` | +| Data deletions | `@cf.app:"tock" AND (@message:"remove" OR @message:"delete")` | +| Data access | `@cf.app:"tock" AND @message:"/api/reporting_period"` | +| Data changes | `@cf.app:"tock" AND (@message:"create" OR @message:"change")` | +| Permission Changes | `@cf.app:"tock" AND @message:"account-management"` | \* For "object access" search by database table name or Model name -\** For these queries, consider including a table name like `@cf.app:"tock" AND SELECT AND employees_employeegrade` - -Some table names: -- `employees_employeegrade` -- `employees_userdata` -- `hours_holidayprefills` -- `hours_reportingperiod` -- `hours_reportingperiod_holiday_prefills` -- `hours_targets` -- `hours_timecard` -- `hours_timecardnote` -- `hours_timecardobject` -- `hours_timecardprefilldata` -- `organizations_organization` -- `projects_accountingcode` -- `projects_agency` -- `projects_profitlossaccount` -- `projects_project` -- `projects_project_alerts` -- `projects_projectalert` - Some Model names: - `EmployeeGrade` - `UserData` @@ -72,3 +51,20 @@ Some Model names: - `Project` - `ProjectAlerts` - `ProjectAlert` + +Some Data urls: +- `/reporting_period` +- `/reports` +- `/employees` +- `/utilization` +- `/projects` +- `/admin` +- `/auth` +- `/api` +- `/api/projects` +- `/api/users` +- `/api/reporting_period_audit` +- `/api/timecards` +- `/api/hours/by_quarter` +- `/api/hours/by_quarter_by_user` +- `/api/user_data` From c04b088944c5ea937b6a7c635695f19bff32941e Mon Sep 17 00:00:00 2001 From: Roger Steve Ruiz Date: Mon, 26 Mar 2018 16:06:32 -0400 Subject: [PATCH 35/59] Update logging messages with final draft --- docs/logging.md | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/docs/logging.md b/docs/logging.md index 5d60e1766..d0e712b78 100644 --- a/docs/logging.md +++ b/docs/logging.md @@ -24,15 +24,17 @@ access using [cloud.gov's logging system][cg-log-sys]. | Authentication checks | `@cf.app:"tock" AND @message:"Authenticating user"` | | Successful login events | `@cf.app:"tock" AND @message:"Successful login"` | | Unsuccessful login events | `@cf.app:"tock" AND @message:"Unsuccessful login"` | -| Object access * | `@cf.app:"tock" AND TimecardObject` | +| Object access * | `@cf.app:"tock" AND @message:"TimecardObject"` | | Account management events | `@cf.app:"tock" AND @message:"account-management"` | | All administrator activity | `@cf.app:"tock" AND @message:"admin-log"` | | Data deletions | `@cf.app:"tock" AND (@message:"remove" OR @message:"delete")` | -| Data access | `@cf.app:"tock" AND @message:"/api/reporting_period"` | -| Data changes | `@cf.app:"tock" AND (@message:"create" OR @message:"change")` | +| Data access ** | `@cf.app:"tock" AND @message:"/api/reporting_period"` | +| Data changes * | `@cf.app:"tock" AND (@message:"create" OR @message:"change")` | | Permission Changes | `@cf.app:"tock" AND @message:"account-management"` | -\* For "object access" search by database table name or Model name +\* For "object access" search by Model name, `AND @message:"EmployeeGrade"` + +\** For "data access" search by Data url Some Model names: - `EmployeeGrade` From b9276689c63024006b02d21fabfa64cc31b67c30 Mon Sep 17 00:00:00 2001 From: Roger Steve Ruiz Date: Tue, 27 Mar 2018 11:51:44 -0400 Subject: [PATCH 36/59] Move the Readme to the docs directory --- README.md | 153 ++------------------------------------ docs/local-development.md | 9 ++- 2 files changed, 14 insertions(+), 148 deletions(-) diff --git a/README.md b/README.md index 755f24bf1..f175cdd35 100644 --- a/README.md +++ b/README.md @@ -4,154 +4,15 @@ We use Tock to track our time. You can read more about Tock in this [blog post]( [![CircleCI](https://circleci.com/gh/18F/tock.svg?style=svg)](https://circleci.com/gh/18F/tock) -![Screenshot of Tock](https://github.com/18F/tock/blob/master/Screen%20Shot%202016-12-05%20at%2011.30.54%20AM.png) +![Screenshot of Tock](https://github.com/18F/tock/blob/master/Screen%20Shot%202016-12-05%20at%2011.30.54%20AM.png?raw=true) If your team uses Tock and Slack, you might also find the ["angrytock" reminder bot](https://github.com/18F/angrytock) helpful. -## Getting Started +## Documentation -1. Install [Docker][]. If you're on OS X, install Docker for Mac. If you're on Windows, install Docker for Windows. +Read the project documentation in [the `/docs` +directory][gh-docs]. Interested in the API docs? Read the API documentation in +[the `/api-docs` directory][gh-api-docs]. -1. Move into the `tock` directory at the repository root: - - ``` - $ cd tock - ``` - -1. Run: - - ```shell - $ docker-compose build - $ docker-compose run app python manage.py migrate - $ docker-compose run app python manage.py loaddata test_data/data-update-deduped.json - $ docker-compose run app \ - python manage.py \ - createsuperuser \ - --username admin.user \ - --email admin.user@gsa.gov \ - --noinput - ``` - -1. Once the above commands are successful, run: - - ``` - docker-compose up - ``` - - This will start up all required servers in containers and output their - log information to stdout. - -1. Visit [http://localhost:8000/][] directly to access the site. - - When prompted for an email address, enter `admin@gsa.gov`. - -You can access the admin panel at `/admin`. - -### Running static analysis tools - -We run two linting tools in continuous integration, -[`flake8`](http://flake8.pycqa.org/en/latest/) for general linting of unused -variables, style, etc. and [`bandit`](https://pypi.python.org/pypi/bandit), a -security-focused linter. - -To run this locally, run: -```sh -docker-compose run app bandit -r . -x manage.py,docker_entrypoint.py -docker-compose run app flake8 -``` - -### Accessing the app container - -You'll likely want to run `manage.py` to do other things at some point. -To do this, it's probably easiest to run: - -``` -docker-compose run app bash -``` - -This will run an interactive bash session inside the main app container. -In this container, the `/tock` directory is mapped to the `tock` -directory of the repository on your host; you can run `manage.py` from there. - -#### Running `pdb` within the Docker container - -Once you have a running set containers, you should be able to attach to the -`tock_app` CONTAINER_ID using the following command. - -```sh -docker attach $(docker container ps | grep -E 'tock_app' | awk '{ print $1 }') -``` - -This will drop you into the `tock_app` container. Now you can use `pdb` in your -local code and have a Python Debugger. - -##### Exiting the debugger - -To properly exit the debugger, use the following keyboard commands within the -container: `Control + p, Control + q` one after another. - -If you mistakenly hit `Control + c` you will kill the `tock_app` container! In -that case, restart the `tock_app` container with a `docker-compose up` command. - -### Making CSS changes - -`docker-compose up` will also launch a [Node] machine that compiles the [Sass] -files in `tock/tock/static/sass` into corresponding CSS files in -`tock/tock/static/css/dist`. **The generated CSS files are not checked into -git, and should not be modified by hand.** - -You can also run the CSS build and watch scripts outside of the Docker -container. Just install [Node][] (e.g. with `brew install node` on OS X), then -install the dependencies with: - -```sh -npm install -``` - -Assuming that goes off without a hitch, you can then either build the CSS in -one go with: - -``` -npm run build-css -``` - -or start the watch process, which builds new CSS whenever the source Sass files -are changed: - -``` -npm run watch-css -``` - -## API - -Tock has an API! You may issue GET requests to various [endpoints](https://github.com/18F/tock/tree/master/api-docs) via the /api/ path with results returned as JSON objects. We use Django REST framework's TokenAuthentication library which requires all requests to include a token value in your request header using the following format (a cURL command line based request is used for this example for getting project data from our Tock deployment): -``` -$ curl https://tock.18f.gov/api/projects.json -H 'Authorization: Token randomalphanumericstringed854b18ba024327' -``` -To obtain your own Tock API authorization token, please visit [#tock-dev](https://gsa-tts.slack.com/messages/tock-dev/) on Slack! - -To access similar data in CSV format from within Tock, please visit the [/reports](https://tock.18f.gov/reports) page. - -## Authentication - -18F's current deployment of Tock relies on -[cloud.gov's User Account and Authentication (UAA) server][UAA] for -authentication. - -During development, a ["fake" cloud.gov UAA server][fakeUAA] is used for -authentication. Here you can actually enter any email address; if the -address is `@gsa.gov`, then a non-staff account will automatically -be created for the user and you'll be logged-in, but otherwise access -will be denied. - -The easiest way to create an administrative user is to first use -`manage.py createsuperuser` to create a user, and then log in -with that user's email address. See the "Getting Started" section -for an example of this. - -[Docker]: https://www.docker.com/ -[http://localhost:8000/]: http://localhost:8000/ -[Sass]: http://sass-lang.com/ -[Node]: https://nodejs.org/en/ -[UAA]: https://cloud.gov/docs/apps/leveraging-authentication/ -[fakeUAA]: http://cg-django-uaa.readthedocs.io/en/latest/quickstart.html#using-the-fake-cloud-gov-server +[gh-docs]: https://github.com/18F/tock/tree/master/docs +[gh-api-docs]: https://github.com/18F/tock/tree/master/api-docs diff --git a/docs/local-development.md b/docs/local-development.md index d5c7f37b3..d48937760 100644 --- a/docs/local-development.md +++ b/docs/local-development.md @@ -17,7 +17,12 @@ Documentation](https://github.com/18F/tock/tree/master/docs) $ docker-compose build $ docker-compose run app python manage.py migrate $ docker-compose run app python manage.py loaddata test_data/data-update-deduped.json - $ docker-compose run app python manage.py createsuperuser --username admin@gsa.gov --email admin@gsa.gov --noinput + $ docker-compose run app \ + python manage.py \ + createsuperuser \ + --username admin.user \ + --email admin.user@gsa.gov \ + --noinput ``` 1. Once the above commands are successful, run: @@ -31,7 +36,7 @@ Documentation](https://github.com/18F/tock/tree/master/docs) 1. Visit [http://localhost:8000/][] directly to access the site. - When prompted for an email address, enter `admin@gsa.gov`. + When prompted for an email address, enter `admin.user@gsa.gov`. You can access the admin panel at `/admin`. From 77dcb9663c43bc45e457c78bcdc2246db2da54cd Mon Sep 17 00:00:00 2001 From: Roger Steve Ruiz Date: Tue, 27 Mar 2018 16:50:47 -0400 Subject: [PATCH 37/59] Add Gemnasium badge --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index f175cdd35..d04aa618b 100644 --- a/README.md +++ b/README.md @@ -3,6 +3,7 @@ We use Tock to track our time. You can read more about Tock in this [blog post](https://18f.gsa.gov/2015/05/21/tockingtime/) about its features and the [handbook page](https://handbook.18f.gov/tock/) for guidance and instructions. [![CircleCI](https://circleci.com/gh/18F/tock.svg?style=svg)](https://circleci.com/gh/18F/tock) +[![Dependency Status](https://gemnasium.com/badges/github.com/18F/tock.svg)](https://gemnasium.com/github.com/18F/tock) ![Screenshot of Tock](https://github.com/18F/tock/blob/master/Screen%20Shot%202016-12-05%20at%2011.30.54%20AM.png?raw=true) From 34b434f21e204b657faeb818e5d0704ee9e27285 Mon Sep 17 00:00:00 2001 From: Roger Steve Ruiz Date: Wed, 28 Mar 2018 10:47:34 -0400 Subject: [PATCH 38/59] Talking about env variables --- docs/deployment-process.md | 40 +++++++++++++++++++++++++++++++++++++- 1 file changed, 39 insertions(+), 1 deletion(-) diff --git a/docs/deployment-process.md b/docs/deployment-process.md index e15ee7fad..a6340d0e3 100644 --- a/docs/deployment-process.md +++ b/docs/deployment-process.md @@ -45,6 +45,28 @@ and installs only production dependencies. - tock.app.cloud.gov -> `staging` space, `tock-staging` app - tock.18f.gov -> `prod` space, `tock` app +#### Cloud Foundry environment variables + +Tock requires a few different environment variables in production. These are +both updated using the [User Provided Service](#user-provided-service) and +configured in the `manifest-*.yaml`. + +| type | name | description | +| ---- | -----| ----------- | +| **secret** | `DJANGO_SECRET_KEY` | Secret key used to maintain session state. Changing this value will invalidate all user sessions for Tock and log all users out.| +| **secret** | `NEW_RELIC_LICENSE_KEY` | The New Relic license key connected to the New Relic account for the application. | +| **secret** | `NEW_RELIC_API_KEY` | The New Relic API key connected to the New Relic account for the application. | +| **secret** | `UAA_CLIENT_ID` | The UAA Client ID from the cloud.gov identity provider service key. | +| **secret** | `UAA_CLIENT_SECRET` | The UAA Client Secret from the cloud.gov identity provider service key. | +| **public** | `NEW_RELIC_CONFIG_FILE` | New Relic configuration file used by the `newrelic-admin` commands and New Relic libraries. | +| **public** | `NEW_RELIC_APP_NAME` | Application name that appears in the New Relic interface. Changing this will change will cause New Relic data to be gathered under a different application name. | +| **public** | `NEW_RELIC_ENV` | Application environment which appears in the New Relic interface. | +| **public** | `NEW_RELIC_LOG` | Logging that New Relic should listen to: e.g. `stdout`. | + +Variables with the designation **secret** are stored in the `tock-credentials` +User-Provided Service (UPS). **Public** variables are stored in the +environment's `manifest-*.yml` file. + ### Services #### User Provided Service (UPS) @@ -91,12 +113,28 @@ cf create-service aws-rds shared-psql tock-database cf bind-service tock-database ``` +#### cloud.gov identity provider service + +Tock uses the cloud.gov identity provider service to provide authentication via +cloud.gov UAA application for it's users. + + +#### cloud.gov service account + +Tock uses the cloud.gov service account service to provide deployer accounts for +staging and production environments. + +### CircleCI continuous integration, delivery, and deployment + +Tock uses CircleCI to continuously integrate code, deliver the code to staging +servers, and deploy the latest release to production servers. + ### New Relic environment variables Basic New Relic configuration is done in [newrelic.ini](../newrelic.ini), with additional settings specified in each deployment environment's manifest file. -As described in [Environment variables](environment.md), you will need +As described in [Environment variables](#cloud-foundry-environment-variables), you will need to supply the `NEW_RELIC_LICENSE_KEY` as part of each deployment's [User Provided Service](#user-provided-service-ups). From ec662f32c18e6623910dc75cbaffd256fd0ce7d6 Mon Sep 17 00:00:00 2001 From: Roger Steve Ruiz Date: Wed, 28 Mar 2018 10:47:56 -0400 Subject: [PATCH 39/59] Cleanup whitespace --- docs/deployment-process.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/deployment-process.md b/docs/deployment-process.md index a6340d0e3..460190cc9 100644 --- a/docs/deployment-process.md +++ b/docs/deployment-process.md @@ -26,9 +26,9 @@ in the root directory of this project, prefixed with `manifest-` and ending in a `.yml` file extension. During local development and continuous integration testing, -`pipenv install --dev` is used, which installs both development -and production dependencies. During deployments, the Cloud Foundry -python buildpack generates a `requirements.txt` file with `pipenv lock -r` +`pipenv install --dev` is used, which installs both development +and production dependencies. During deployments, the Cloud Foundry +python buildpack generates a `requirements.txt` file with `pipenv lock -r` and installs only production dependencies. ### Cloud Foundry structure From ec3f00eaa5a3b40447dfa7a89bfcaad8f71466da Mon Sep 17 00:00:00 2001 From: Roger Steve Ruiz Date: Wed, 28 Mar 2018 10:48:18 -0400 Subject: [PATCH 40/59] Talking about production deployments and releases --- docs/deployment-process.md | 61 ++++++++------------------------------ 1 file changed, 13 insertions(+), 48 deletions(-) diff --git a/docs/deployment-process.md b/docs/deployment-process.md index 460190cc9..b2e3a9a97 100644 --- a/docs/deployment-process.md +++ b/docs/deployment-process.md @@ -153,7 +153,8 @@ cf zero-downtime-push tock-staging -f manifest-staging.yml ### Production servers -Production deploys are a somewhat manual process in that they are not done +Production deploys are also automated. They rely on the creation of a Git tag to +be made against the `master` branch following the from CI. However, just like in our CircleCI deployments to staging, we use the Cloud Foundry [autopilot plugin](https://github.com/contraband/autopilot). @@ -184,44 +185,23 @@ Then use the autopilot plugin's `zero-downtime-push` command to deploy: cf zero-downtime-push tock -f manifest-production.yml ``` - +Once this tag is pushed up to GitHub, draft or assign it to an already +drafted release in GitHub. CircleCI will deploy this tag to the Production +instance of Tock using CF Autopilot. ### Logs @@ -230,18 +210,3 @@ Logs in cloud.gov-deployed applications are generally viewable by running [UPS]: https://docs.cloudfoundry.org/devguide/services/user-provided.html [`README.md`]: https://github.com/18F/tock#readme - -### Automated Releases to Production - -Tock is automatically deployed to Production using CircleCI using GitHub -Releases and Git tags. Tags are versioned using the following structure, the -letter `v` followed by the full year, full month, full day, followed by a period -and last a version number for that release. For example: - -``` -v20180131.1 -``` - -Once this tag is pushed up to GitHub, you can draft or assigned to an already -drafted release and CircleCI will deploy this tag to the Production instance of -Tock using CF Autopilot. From 94c38fbae9e944368f7c024fdf11fc4205983fb6 Mon Sep 17 00:00:00 2001 From: Joe Krzystan Date: Wed, 28 Mar 2018 08:15:51 -0400 Subject: [PATCH 41/59] Pipenv generated requirements.txt and dependency updates Adding requirements.txt back into repository to accomodate gemnasium. Requirements generated by pipenv from Pipfile.lock. Update Pipfile.lock with current package versions. Added section to README.md on dependency management and updating. --- Pipfile.lock | 22 +++++++++++----------- requirements.txt | 26 ++++++++++++++++++++++++++ 2 files changed, 37 insertions(+), 11 deletions(-) create mode 100644 requirements.txt diff --git a/Pipfile.lock b/Pipfile.lock index cdb1adf9d..0aa73e634 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -39,9 +39,9 @@ }, "cg-django-uaa": { "hashes": [ - "sha256:f64b463a5a09b4ed5327d4d036dd5911446f56a92a7d56c6b2d9ef564a07cb8a" + "sha256:a12e502729b45e2b0d35e37e8fd2c6dadbd448411f883776071dcb91051bd81e" ], - "version": "==1.2.0" + "version": "==1.3.0" }, "chardet": { "hashes": [ @@ -419,10 +419,10 @@ }, "gitpython": { "hashes": [ - "sha256:ad61bc25deadb535b047684d06f3654c001d9415e1971e51c9c20f5b510076e9", - "sha256:b8367c432de995dc330b5b146c5bfdc0926b8496e100fda6692134e00c0dcdc5" + "sha256:05069e26177c650b3cb945dd543a7ef7ca449f8db5b73038b465105673c1ef61", + "sha256:c47cc31af6e88979c57a33962cbc30a7c25508d74a1b3a19ec5aa7ed64b03129" ], - "version": "==2.1.8" + "version": "==2.1.9" }, "idna": { "hashes": [ @@ -447,10 +447,10 @@ }, "pbr": { "hashes": [ - "sha256:05f61c71aaefc02d8e37c0a3eeb9815ff526ea28b3b76324769e6158d7f95be1", - "sha256:60c25b7dfd054ef9bb0ae327af949dd4676aa09ac3a9471cdc871d8a9213f9ac" + "sha256:8b9a7c3704657cb0831b3ded0a6b61377947c8235b76649bb7de4bfe2e6cfa56", + "sha256:cf66675e22ae91a4f20e4b8354f117d3e3d1de651513051d109cc39645fb3672" ], - "version": "==3.1.1" + "version": "==4.0.0" }, "pycodestyle": { "hashes": [ @@ -468,10 +468,10 @@ }, "python-dateutil": { "hashes": [ - "sha256:07009062406cffd554a9b4135cd2ff167c9bf6b7aac61fe946c93e69fad1bbd8", - "sha256:8f95bb7e6edbb2456a51a1fb58c8dca942024b4f5844cae62c90aa88afe6e300" + "sha256:3220490fb9741e2342e1cf29a503394fdac874bc39568288717ee67047ff29df", + "sha256:9d8074be4c993fbe4947878ce593052f71dac82932a677d49194d8ce9778002e" ], - "version": "==2.7.0" + "version": "==2.7.2" }, "pytz": { "hashes": [ diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 000000000..e334dcb1a --- /dev/null +++ b/requirements.txt @@ -0,0 +1,26 @@ +bleach==2.1.3 +certifi==2018.1.18 +cfenv==0.5.3 +cg-django-uaa==1.3.0 +chardet==3.0.4 +dj-database-url==0.5.0 +django==1.11.11 +djangorestframework-csv==2.1.0 +djangorestframework==3.6.4 +furl==1.0.1 +gevent==1.2.2 +greenlet==0.4.13 +gunicorn==19.7.1 +html5lib==1.0.1 +idna==2.6 +newrelic==3.0.0.89 +orderedmultidict==0.7.11 +psycopg2-binary==2.7.4 +pyjwt==1.6.1 +pytz==2018.3 +requests==2.18.4 +six==1.11.0 +unicodecsv==0.14.1 +urllib3==1.22 +webencodings==0.5.1 +whitenoise==3.3.1 From ef603ad7ee391260d18580b7e4a50966f5ed47ac Mon Sep 17 00:00:00 2001 From: Joe Krzystan Date: Wed, 28 Mar 2018 09:15:53 -0400 Subject: [PATCH 42/59] JS dependency updates Another batch of incremental js dependency updates. Include a brief section in readme for js package management. --- README.md | 174 ++++++++ package-lock.json | 397 +++++++++++------- package.json | 6 +- .../img/uswds/angle-arrow-down-primary.png | Bin 0 -> 214 bytes .../img/uswds/angle-arrow-down-primary.svg | 1 + 5 files changed, 421 insertions(+), 157 deletions(-) create mode 100644 tock/tock/static/img/uswds/angle-arrow-down-primary.png create mode 100644 tock/tock/static/img/uswds/angle-arrow-down-primary.svg diff --git a/README.md b/README.md index d04aa618b..a5b3a22ac 100644 --- a/README.md +++ b/README.md @@ -15,5 +15,179 @@ Read the project documentation in [the `/docs` directory][gh-docs]. Interested in the API docs? Read the API documentation in [the `/api-docs` directory][gh-api-docs]. +<<<<<<< HEAD [gh-docs]: https://github.com/18F/tock/tree/master/docs [gh-api-docs]: https://github.com/18F/tock/tree/master/api-docs +======= +1. Move into the `tock` directory at the repository root: + + ``` + $ cd tock + ``` + +1. Run: + + ```shell + $ docker-compose build + $ docker-compose run app python manage.py migrate + $ docker-compose run app python manage.py loaddata test_data/data-update-deduped.json + $ docker-compose run app \ + python manage.py \ + createsuperuser \ + --username admin.user \ + --email admin.user@gsa.gov \ + --noinput + ``` + +1. Once the above commands are successful, run: + + ``` + docker-compose up + ``` + + This will start up all required servers in containers and output their + log information to stdout. + +1. Visit [http://localhost:8000/][] directly to access the site. + + When prompted for an email address, enter `admin@gsa.gov`. + +You can access the admin panel at `/admin`. + +### Running static analysis tools + +We run two linting tools in continuous integration, +[`flake8`](http://flake8.pycqa.org/en/latest/) for general linting of unused +variables, style, etc. and [`bandit`](https://pypi.python.org/pypi/bandit), a +security-focused linter. + +To run this locally, run: +```sh +docker-compose run app bandit -r . -x manage.py,docker_entrypoint.py +docker-compose run app flake8 +``` + +### Dependency management + +#### Python + +Tock uses [Pipenv] to manage development and production dependencies. +In development and continuous integration the python environment is +established with `pipenv install --dev`. To acommodate 3rd party tools +which do not yet support [Pipenv] a `requirements.txt` file, containing +only production dependencies, is generated by [Pipenv] and included in +the repository. + +Development and production dependencies can be updated locally with: +```sh +pipenv update --dev +pipenv lock --requirements > requirements.txt +``` + +#### Javascript + +Tock uses [npm] to manage javascript dependencies. + +Dependencies can be updated locally with: +```sh +npm update +``` + +### Accessing the app container + +You'll likely want to run `manage.py` to do other things at some point. +To do this, it's probably easiest to run: + +``` +docker-compose run app bash +``` + +This will run an interactive bash session inside the main app container. +In this container, the `/tock` directory is mapped to the `tock` +directory of the repository on your host; you can run `manage.py` from there. + +#### Running `pdb` within the Docker container + +Once you have a running set containers, you should be able to attach to the +`tock_app` CONTAINER_ID using the following command. + +```sh +docker attach $(docker container ps | grep -E 'tock_app' | awk '{ print $1 }') +``` + +This will drop you into the `tock_app` container. Now you can use `pdb` in your +local code and have a Python Debugger. + +##### Exiting the debugger + +To properly exit the debugger, use the following keyboard commands within the +container: `Control + p, Control + q` one after another. + +If you mistakenly hit `Control + c` you will kill the `tock_app` container! In +that case, restart the `tock_app` container with a `docker-compose up` command. + +### Making CSS changes + +`docker-compose up` will also launch a [Node] machine that compiles the [Sass] +files in `tock/tock/static/sass` into corresponding CSS files in +`tock/tock/static/css/dist`. **The generated CSS files are not checked into +git, and should not be modified by hand.** + +You can also run the CSS build and watch scripts outside of the Docker +container. Just install [Node][] (e.g. with `brew install node` on OS X), then +install the dependencies with: + +```sh +npm install +``` + +Assuming that goes off without a hitch, you can then either build the CSS in +one go with: + +``` +npm run build-css +``` + +or start the watch process, which builds new CSS whenever the source Sass files +are changed: + +``` +npm run watch-css +``` + +## API + +Tock has an API! You may issue GET requests to various [endpoints](https://github.com/18F/tock/tree/master/api-docs) via the /api/ path with results returned as JSON objects. We use Django REST framework's TokenAuthentication library which requires all requests to include a token value in your request header using the following format (a cURL command line based request is used for this example for getting project data from our Tock deployment): +``` +$ curl https://tock.18f.gov/api/projects.json -H 'Authorization: Token randomalphanumericstringed854b18ba024327' +``` +To obtain your own Tock API authorization token, please visit [#tock-dev](https://gsa-tts.slack.com/messages/tock-dev/) on Slack! + +To access similar data in CSV format from within Tock, please visit the [/reports](https://tock.18f.gov/reports) page. + +## Authentication + +18F's current deployment of Tock relies on +[cloud.gov's User Account and Authentication (UAA) server][UAA] for +authentication. + +During development, a ["fake" cloud.gov UAA server][fakeUAA] is used for +authentication. Here you can actually enter any email address; if the +address is `@gsa.gov`, then a non-staff account will automatically +be created for the user and you'll be logged-in, but otherwise access +will be denied. + +The easiest way to create an administrative user is to first use +`manage.py createsuperuser` to create a user, and then log in +with that user's email address. See the "Getting Started" section +for an example of this. + +[Docker]: https://www.docker.com/ +[http://localhost:8000/]: http://localhost:8000/ +[Sass]: http://sass-lang.com/ +[Node]: https://nodejs.org/en/ +[UAA]: https://cloud.gov/docs/apps/leveraging-authentication/ +[fakeUAA]: http://cg-django-uaa.readthedocs.io/en/latest/quickstart.html#using-the-fake-cloud-gov-server +[Pipenv]: https://docs.pipenv.org/ +[npm]: https://www.npmjs.com +>>>>>>> c63780c... JS dependency updates diff --git a/package-lock.json b/package-lock.json index e5dfe0c2f..8478158b3 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2,10 +2,15 @@ "requires": true, "lockfileVersion": 1, "dependencies": { + "@types/node": { + "version": "8.10.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-8.10.0.tgz", + "integrity": "sha512-7IGHZQfRfa0bCd7zUBVUGFKFn31SpaLDFfNoCAqkTGQO5JlHC9BwQA/CG9KZlABFxIUtXznyFgechjPQEGrUTg==" + }, "JSONStream": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/JSONStream/-/JSONStream-1.3.1.tgz", - "integrity": "sha1-cH92HgHa6eFvG8+TcDt4xwlmV5o=", + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/JSONStream/-/JSONStream-1.3.2.tgz", + "integrity": "sha1-wQI3G27Dp887hHygDCC7D85Mbeo=", "requires": { "jsonparse": "1.3.1", "through": "2.3.8" @@ -21,6 +26,22 @@ "resolved": "https://registry.npmjs.org/acorn/-/acorn-4.0.13.tgz", "integrity": "sha1-EFSVrlNh1pe9GVyCUZLhrX8lN4c=" }, + "acorn-node": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/acorn-node/-/acorn-node-1.3.0.tgz", + "integrity": "sha512-efP54n3d1aLfjL2UMdaXa6DsswwzJeI5rqhbFvXMrKiJ6eJFpf+7R0zN7t8IC+XKn2YOAFAv6xbBNgHUkoHWLw==", + "requires": { + "acorn": "5.5.3", + "xtend": "4.0.1" + }, + "dependencies": { + "acorn": { + "version": "5.5.3", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.5.3.tgz", + "integrity": "sha512-jd5MkIUlbbmb07nXH0DT3y7rDVtkzDi4XZOUVWAer8ajmF/DTSSbl5oNFyDOl/OXA33Bl79+ypHhl2pN20VeOQ==" + } + } + }, "amdefine": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.1.tgz", @@ -81,9 +102,9 @@ "integrity": "sha1-2sh4dxPJlmhJ/IGAd36+nB3fO4Y=" }, "asn1.js": { - "version": "4.9.1", - "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-4.9.1.tgz", - "integrity": "sha1-SLokC0WpKA6UdImQull9IWYX/UA=", + "version": "4.10.1", + "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-4.10.1.tgz", + "integrity": "sha512-p32cOF5q0Zqs9uBiONKYLm6BClCoBCM5O9JfeUSlnQLBTxYdTK+pW+nXflm8UkKd2UYlEbYz5qEi0JuZR9ckSw==", "requires": { "bn.js": "4.11.8", "inherits": "2.0.3", @@ -137,9 +158,9 @@ "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" }, "base64-js": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.2.1.tgz", - "integrity": "sha512-dwVUVIXsBZXwTuwnXI9RK8sBmgq09NDHzyR9SAph9eqk76gKK2JSQmZARC2zRC81JC2QTtxD0ARU5qTS25gIGw==" + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.2.3.tgz", + "integrity": "sha512-MsAhsUW1GxCdgYSO6tAfZrNapmUKk7mWx/k5mFY/A1gBtkaCaNapTg+FExCw1r9yeaZhqx/xPg43xgTFH6KL5w==" }, "bcrypt-pbkdf": { "version": "1.0.1", @@ -186,15 +207,16 @@ "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=" }, "browser-pack": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/browser-pack/-/browser-pack-6.0.2.tgz", - "integrity": "sha1-+GzWzvT1MAyOY+B6TVEvZfv/RTE=", + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/browser-pack/-/browser-pack-6.0.4.tgz", + "integrity": "sha512-Q4Rvn7P6ObyWfc4stqLWHtG1MJ8vVtjgT24Zbu+8UTzxYuZouqZsmNRRTFVMY/Ux0eIKv1d+JWzsInTX+fdHPQ==", "requires": { - "JSONStream": "1.3.1", - "combine-source-map": "0.7.2", + "JSONStream": "1.3.2", + "combine-source-map": "0.8.0", "defined": "1.0.0", + "safe-buffer": "5.1.1", "through2": "2.0.3", - "umd": "3.0.1" + "umd": "3.0.3" } }, "browser-resolve": { @@ -217,9 +239,9 @@ "resolved": "https://registry.npmjs.org/browserify/-/browserify-13.3.0.tgz", "integrity": "sha1-tanJAgJD8McORnW+yCI7xifkFc4=", "requires": { - "JSONStream": "1.3.1", + "JSONStream": "1.3.2", "assert": "1.4.1", - "browser-pack": "6.0.2", + "browser-pack": "6.0.4", "browser-resolve": "1.11.2", "browserify-zlib": "0.1.4", "buffer": "4.9.1", @@ -227,7 +249,7 @@ "concat-stream": "1.5.2", "console-browserify": "1.1.0", "constants-browserify": "1.0.0", - "crypto-browserify": "3.11.1", + "crypto-browserify": "3.12.0", "defined": "1.0.0", "deps-sort": "2.0.0", "domain-browser": "1.1.7", @@ -238,8 +260,8 @@ "htmlescape": "1.1.1", "https-browserify": "0.0.1", "inherits": "2.0.3", - "insert-module-globals": "7.0.1", - "labeled-stream-splicer": "2.0.0", + "insert-module-globals": "7.0.4", + "labeled-stream-splicer": "2.0.1", "module-deps": "4.1.1", "os-browserify": "0.1.2", "parents": "1.0.1", @@ -249,17 +271,17 @@ "querystring-es3": "0.2.1", "read-only-stream": "2.0.0", "readable-stream": "2.3.3", - "resolve": "1.4.0", + "resolve": "1.6.0", "shasum": "1.0.2", "shell-quote": "1.6.1", "stream-browserify": "2.0.1", - "stream-http": "2.7.2", + "stream-http": "2.8.1", "string_decoder": "0.10.31", "subarg": "1.0.0", - "syntax-error": "1.3.0", + "syntax-error": "1.4.0", "through2": "2.0.3", "timers-browserify": "1.4.2", - "tty-browserify": "0.0.0", + "tty-browserify": "0.0.1", "url": "0.11.0", "util": "0.10.3", "vm-browserify": "0.0.4", @@ -274,15 +296,16 @@ } }, "browserify-aes": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.0.6.tgz", - "integrity": "sha1-Xncl297x/Vkw1OurSFZ85FHEigo=", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.1.1.tgz", + "integrity": "sha512-UGnTYAnB2a3YuYKIRy1/4FB2HdM866E0qC46JXvVTYKlBlZlnvfpSfY6OKfXZAkv70eJ2a1SqzpAo5CRhZGDFg==", "requires": { "buffer-xor": "1.0.3", "cipher-base": "1.0.4", "create-hash": "1.1.3", - "evp_bytestokey": "1.0.0", - "inherits": "2.0.3" + "evp_bytestokey": "1.0.3", + "inherits": "2.0.3", + "safe-buffer": "5.1.1" } }, "browserify-cipher": { @@ -290,9 +313,9 @@ "resolved": "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.0.tgz", "integrity": "sha1-mYgkSHS/XtTijalWZtzWasj8Njo=", "requires": { - "browserify-aes": "1.0.6", + "browserify-aes": "1.1.1", "browserify-des": "1.0.0", - "evp_bytestokey": "1.0.0" + "evp_bytestokey": "1.0.3" } }, "browserify-des": { @@ -311,7 +334,7 @@ "integrity": "sha1-IeCr+vbyApzy+vsTNWenAdQTVSQ=", "requires": { "bn.js": "4.11.8", - "randombytes": "2.0.5" + "randombytes": "2.0.6" } }, "browserify-sign": { @@ -341,11 +364,16 @@ "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.1.tgz", "integrity": "sha1-bRu2AbB6TvztlwlBMgkwJ8lbwpg=", "requires": { - "base64-js": "1.2.1", - "ieee754": "1.1.8", + "base64-js": "1.2.3", + "ieee754": "1.1.11", "isarray": "1.0.0" } }, + "buffer-from": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.0.0.tgz", + "integrity": "sha512-83apNb8KK0Se60UE1+4Ukbe3HbfELJ6UlI4ldtOGs7So4KD26orJM8hIY9lxdzP+UpItH1Yh/Y8GUvNFWFFRxA==" + }, "buffer-xor": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", @@ -398,9 +426,9 @@ } }, "chosen-js": { - "version": "1.8.2", - "resolved": "https://registry.npmjs.org/chosen-js/-/chosen-js-1.8.2.tgz", - "integrity": "sha512-eC5+gRZLU20osMWuChokjL2WPeVlCWzd2YbF5ucaGkmuyD6eThxotJ9+t203sYvKx06bDUVeZ9MhGkm57Oei9g==" + "version": "1.8.3", + "resolved": "https://registry.npmjs.org/chosen-js/-/chosen-js-1.8.3.tgz", + "integrity": "sha512-B1ruoi+9Y51W9lcw5BXBOWdWGrEGyk7sAPlBYn3tmmUKM/JelfFCrhR70tSAZ4YZlfGBdrbXTCHWxpHS/GwGCg==" }, "cipher-base": { "version": "1.0.4", @@ -432,20 +460,20 @@ "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=" }, "combine-source-map": { - "version": "0.7.2", - "resolved": "https://registry.npmjs.org/combine-source-map/-/combine-source-map-0.7.2.tgz", - "integrity": "sha1-CHAxKFazB6h8xKxIbzqaYq7MwJ4=", + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/combine-source-map/-/combine-source-map-0.8.0.tgz", + "integrity": "sha1-pY0N8ELBhvz4IqjoAV9UUNLXmos=", "requires": { "convert-source-map": "1.1.3", "inline-source-map": "0.6.2", "lodash.memoize": "3.0.4", - "source-map": "0.5.6" + "source-map": "0.5.7" }, "dependencies": { "source-map": { - "version": "0.5.6", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.6.tgz", - "integrity": "sha1-dc449SvwczxafwwRjYEzSiu19BI=" + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" } } }, @@ -542,7 +570,7 @@ "cipher-base": "1.0.4", "inherits": "2.0.3", "ripemd160": "2.0.1", - "sha.js": "2.4.8" + "sha.js": "2.4.11" } }, "create-hmac": { @@ -555,7 +583,7 @@ "inherits": "2.0.3", "ripemd160": "2.0.1", "safe-buffer": "5.1.1", - "sha.js": "2.4.8" + "sha.js": "2.4.11" } }, "cross-spawn": { @@ -576,9 +604,9 @@ } }, "crypto-browserify": { - "version": "3.11.1", - "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.11.1.tgz", - "integrity": "sha512-Na7ZlwCOqoaW5RwUK1WpXws2kv8mNhWdTlzob0UXulk6G9BDbyiJaGTYBIX61Ozn9l1EPPJpICZb4DaOpT9NlQ==", + "version": "3.12.0", + "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz", + "integrity": "sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==", "requires": { "browserify-cipher": "1.0.0", "browserify-sign": "4.0.4", @@ -587,9 +615,10 @@ "create-hmac": "1.1.6", "diffie-hellman": "5.0.2", "inherits": "2.0.3", - "pbkdf2": "3.0.13", + "pbkdf2": "3.0.14", "public-encrypt": "4.0.0", - "randombytes": "2.0.5" + "randombytes": "2.0.6", + "randomfill": "1.0.4" } }, "currently-unhandled": { @@ -645,7 +674,7 @@ "resolved": "https://registry.npmjs.org/deps-sort/-/deps-sort-2.0.0.tgz", "integrity": "sha1-CRckkC6EZYJg65EHSMzNGvbiH7U=", "requires": { - "JSONStream": "1.3.1", + "JSONStream": "1.3.2", "shasum": "1.0.2", "subarg": "1.0.0", "through2": "2.0.3" @@ -661,12 +690,19 @@ } }, "detective": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/detective/-/detective-4.5.0.tgz", - "integrity": "sha1-blqMaybmx6JUsca210kNmOyR7dE=", + "version": "4.7.1", + "resolved": "https://registry.npmjs.org/detective/-/detective-4.7.1.tgz", + "integrity": "sha512-H6PmeeUcZloWtdt4DAkFyzFL94arpHr3NOwwmVILFiy+9Qd4JTxxXrzfyGk/lmct2qVGBwTSwSXagqu2BxmWig==", "requires": { - "acorn": "4.0.13", + "acorn": "5.5.3", "defined": "1.0.0" + }, + "dependencies": { + "acorn": { + "version": "5.5.3", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.5.3.tgz", + "integrity": "sha512-jd5MkIUlbbmb07nXH0DT3y7rDVtkzDi4XZOUVWAer8ajmF/DTSSbl5oNFyDOl/OXA33Bl79+ypHhl2pN20VeOQ==" + } } }, "diffie-hellman": { @@ -675,8 +711,8 @@ "integrity": "sha1-tYNXOScM/ias9jIJn97SoH8gnl4=", "requires": { "bn.js": "4.11.8", - "miller-rabin": "4.0.0", - "randombytes": "2.0.5" + "miller-rabin": "4.0.1", + "randombytes": "2.0.6" } }, "domain-browser": { @@ -749,11 +785,12 @@ "integrity": "sha1-nr23Y1rQmccNzEwqH1AEKI6L2SQ=" }, "evp_bytestokey": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.0.tgz", - "integrity": "sha1-SXtmrZ/vZc18CKYYCCS6FHa2blM=", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", + "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==", "requires": { - "create-hash": "1.1.3" + "md5.js": "1.3.4", + "safe-buffer": "5.1.1" } }, "execa": { @@ -833,9 +870,9 @@ } }, "function-bind": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.0.tgz", - "integrity": "sha1-FhdnFMgBeY5Ojyz391KUZ7tKV3E=" + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" }, "gauge": { "version": "2.7.4", @@ -947,7 +984,7 @@ "resolved": "https://registry.npmjs.org/has/-/has-1.0.1.tgz", "integrity": "sha1-hGFzP1OLCDfJNh45qauelwTcLyg=", "requires": { - "function-bind": "1.1.0" + "function-bind": "1.1.1" } }, "has-ansi": { @@ -1032,9 +1069,9 @@ "integrity": "sha1-P5E2XKvmC3ftDruiS0VOPgnZWoI=" }, "ieee754": { - "version": "1.1.8", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.8.tgz", - "integrity": "sha1-vjPUCsEO8ZJnAfbwii2G+/0a0+Q=" + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.11.tgz", + "integrity": "sha512-VhDzCKN7K8ufStx/CLj5/PDTMgph+qwN5Pkd5i0sGnVwk56zJ0lkT8Qzi1xqWLS0Wp29DgDtNeS7v8/wMoZeHg==" }, "in-publish": { "version": "2.0.0", @@ -1073,29 +1110,58 @@ "resolved": "https://registry.npmjs.org/inline-source-map/-/inline-source-map-0.6.2.tgz", "integrity": "sha1-+Tk0ccGKedFyT4Y/o4tYY3Ct4qU=", "requires": { - "source-map": "0.5.6" + "source-map": "0.5.7" }, "dependencies": { "source-map": { - "version": "0.5.6", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.6.tgz", - "integrity": "sha1-dc449SvwczxafwwRjYEzSiu19BI=" + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" } } }, "insert-module-globals": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/insert-module-globals/-/insert-module-globals-7.0.1.tgz", - "integrity": "sha1-wDv04BywhtW15azorQr+eInWOMM=", + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/insert-module-globals/-/insert-module-globals-7.0.4.tgz", + "integrity": "sha512-Z/sfx2KOKyHQ3U4X3fnXn4Ms1Opa9pGvEfm8j6xKHE6oVqc1dMwVgBVxmj3yIrMtWTl8HYoy12rkhrR8MYym6A==", "requires": { - "JSONStream": "1.3.1", + "JSONStream": "1.3.2", "combine-source-map": "0.7.2", - "concat-stream": "1.5.2", - "is-buffer": "1.1.5", + "concat-stream": "1.6.2", + "is-buffer": "1.1.6", "lexical-scope": "1.2.0", "process": "0.11.10", "through2": "2.0.3", "xtend": "4.0.1" + }, + "dependencies": { + "combine-source-map": { + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/combine-source-map/-/combine-source-map-0.7.2.tgz", + "integrity": "sha1-CHAxKFazB6h8xKxIbzqaYq7MwJ4=", + "requires": { + "convert-source-map": "1.1.3", + "inline-source-map": "0.6.2", + "lodash.memoize": "3.0.4", + "source-map": "0.5.7" + } + }, + "concat-stream": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", + "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", + "requires": { + "buffer-from": "1.0.0", + "inherits": "2.0.3", + "readable-stream": "2.3.3", + "typedarray": "0.0.6" + } + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" + } } }, "invert-kv": { @@ -1109,9 +1175,9 @@ "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=" }, "is-buffer": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.5.tgz", - "integrity": "sha1-Hzsm72E7IUuIy8ojzGwB2Hlh7sw=" + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", + "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==" }, "is-builtin-module": { "version": "1.0.0", @@ -1210,6 +1276,14 @@ "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=" }, + "json-stable-stringify": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-0.0.1.tgz", + "integrity": "sha1-YRwj6BTbN1Un34URk9tZ3Sryf0U=", + "requires": { + "jsonify": "0.0.0" + } + }, "json-stringify-safe": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", @@ -1254,19 +1328,19 @@ "integrity": "sha1-ijGdjkWhMXL8pWKGNy+QwdTHAUw=" }, "labeled-stream-splicer": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/labeled-stream-splicer/-/labeled-stream-splicer-2.0.0.tgz", - "integrity": "sha1-pS4dE4AkwAuGscDJH2d5GLiuClk=", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/labeled-stream-splicer/-/labeled-stream-splicer-2.0.1.tgz", + "integrity": "sha512-MC94mHZRvJ3LfykJlTUipBqenZz1pacOZEMhhQ8dMGcDHs0SBE5GbsavUXV7YtP3icBW17W0Zy1I0lfASmo9Pg==", "requires": { "inherits": "2.0.3", - "isarray": "0.0.1", + "isarray": "2.0.4", "stream-splicer": "2.0.0" }, "dependencies": { "isarray": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=" + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.4.tgz", + "integrity": "sha512-GMxXOiUirWg1xTKRipM0Ek07rX+ubx4nNVElTJdNLYmNO/2YrDkgJGw9CljXn+r4EWiDQg/8lsRdHyg2PJuUaA==" } } }, @@ -1372,6 +1446,26 @@ "resolved": "https://registry.npmjs.org/matches-selector/-/matches-selector-1.2.0.tgz", "integrity": "sha512-c4vLwYWyl+Ji+U43eU/G5FwxWd4ZH0ePUsFs5y0uwD9HUEFBXUQ1zUUan+78IpRD+y4pUfG0nAzNM292K7ItvA==" }, + "md5.js": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.4.tgz", + "integrity": "sha1-6b296UogpawYsENA/Fdk1bCdkB0=", + "requires": { + "hash-base": "3.0.4", + "inherits": "2.0.3" + }, + "dependencies": { + "hash-base": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.0.4.tgz", + "integrity": "sha1-X8hoaEfs1zSZQDMZprCj8/auSRg=", + "requires": { + "inherits": "2.0.3", + "safe-buffer": "5.1.1" + } + } + } + }, "mem": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/mem/-/mem-1.1.0.tgz", @@ -1398,9 +1492,9 @@ } }, "miller-rabin": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.0.tgz", - "integrity": "sha1-SmL7HUKTPAVYOYL0xxb2+55sbT0=", + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz", + "integrity": "sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==", "requires": { "bn.js": "4.11.8", "brorand": "1.1.0" @@ -1467,17 +1561,17 @@ "resolved": "https://registry.npmjs.org/module-deps/-/module-deps-4.1.1.tgz", "integrity": "sha1-IyFYM/HaE/1gbMuAh7RIUty4If0=", "requires": { - "JSONStream": "1.3.1", + "JSONStream": "1.3.2", "browser-resolve": "1.11.2", "cached-path-relative": "1.0.1", "concat-stream": "1.5.2", "defined": "1.0.0", - "detective": "4.5.0", + "detective": "4.7.1", "duplexer2": "0.1.4", "inherits": "2.0.3", "parents": "1.0.1", "readable-stream": "2.3.3", - "resolve": "1.4.0", + "resolve": "1.6.0", "stream-combiner2": "1.1.1", "subarg": "1.0.0", "through2": "2.0.3", @@ -1517,9 +1611,9 @@ } }, "node-sass": { - "version": "4.7.2", - "resolved": "https://registry.npmjs.org/node-sass/-/node-sass-4.7.2.tgz", - "integrity": "sha512-CaV+wLqZ7//Jdom5aUFCpGNoECd7BbNhjuwdsX/LkXBrHl8eb1Wjw4HvWqcFvhr5KuNgAk8i/myf/MQ1YYeroA==", + "version": "4.8.3", + "resolved": "https://registry.npmjs.org/node-sass/-/node-sass-4.8.3.tgz", + "integrity": "sha512-tfFWhUsCk/Y19zarDcPo5xpj+IW3qCfOjVdHtYeG6S1CKbQOh1zqylnQK6cV3z9k80yxAnFX9Y+a9+XysDhhfg==", "requires": { "async-foreach": "0.1.3", "chalk": "1.1.3", @@ -1679,11 +1773,11 @@ "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.0.tgz", "integrity": "sha1-N8T5t+06tlx0gXtfJICTf7+XxxI=", "requires": { - "asn1.js": "4.9.1", - "browserify-aes": "1.0.6", + "asn1.js": "4.10.1", + "browserify-aes": "1.1.1", "create-hash": "1.1.3", - "evp_bytestokey": "1.0.0", - "pbkdf2": "3.0.13" + "evp_bytestokey": "1.0.3", + "pbkdf2": "3.0.14" } }, "parse-json": { @@ -1738,15 +1832,15 @@ } }, "pbkdf2": { - "version": "3.0.13", - "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.0.13.tgz", - "integrity": "sha512-+dCHxDH+djNtjgWmvVC/my3SYBAKpKNqKSjLkp+GtWWYe4XPE+e/PSD2aCanlEZZnqPk2uekTKNC/ccbwd2X2Q==", + "version": "3.0.14", + "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.0.14.tgz", + "integrity": "sha512-gjsZW9O34fm0R7PaLHRJmLLVfSoesxztjPjE9o6R+qtVJij90ltg1joIovN9GKrRW3t1PzhDDG3UMEMFfZ+1wA==", "requires": { "create-hash": "1.1.3", "create-hmac": "1.1.6", "ripemd160": "2.0.1", "safe-buffer": "5.1.1", - "sha.js": "2.4.8" + "sha.js": "2.4.11" } }, "pify": { @@ -1791,7 +1885,7 @@ "browserify-rsa": "4.0.1", "create-hash": "1.1.3", "parse-asn1": "5.1.0", - "randombytes": "2.0.5" + "randombytes": "2.0.6" } }, "punycode": { @@ -1815,13 +1909,22 @@ "integrity": "sha1-nsYfeQSYdXB9aUFFlv2Qek1xHnM=" }, "randombytes": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.0.5.tgz", - "integrity": "sha512-8T7Zn1AhMsQ/HI1SjcCfT/t4ii3eAqco3yOcSzS4mozsOz69lHLsoMXmF9nZgnFanYscnSlUSgs8uZyKzpE6kg==", + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.0.6.tgz", + "integrity": "sha512-CIQ5OFxf4Jou6uOKe9t1AOgqpeU5fd70A8NPdHSGeYXqXsPe6peOwI0cUl88RWZ6sP1vPMV3avd/R6cZ5/sP1A==", "requires": { "safe-buffer": "5.1.1" } }, + "randomfill": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/randomfill/-/randomfill-1.0.4.tgz", + "integrity": "sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==", + "requires": { + "randombytes": "2.0.6", + "safe-buffer": "5.1.1" + } + }, "read-only-stream": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/read-only-stream/-/read-only-stream-2.0.0.tgz", @@ -1929,9 +2032,9 @@ "integrity": "sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE=" }, "resolve": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.4.0.tgz", - "integrity": "sha512-aW7sVKPufyHqOmyyLzg/J+8606v5nevBgaliIlV7nUpVMsDnoBGV/cbSLNjZAg9q0Cfd/+easKVKQ8vOu8fn1Q==", + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.6.0.tgz", + "integrity": "sha512-mw7JQNu5ExIkcw4LPih0owX/TZXjD/ZUF/ZQ/pDnkw3ZKhDcZZw5klmBlj6gVMwjQ3Pz5Jgu7F3d0jcDVuEWdw==", "requires": { "path-parse": "1.0.5" } @@ -1994,11 +2097,12 @@ "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=" }, "sha.js": { - "version": "2.4.8", - "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.8.tgz", - "integrity": "sha1-NwaMLEdra69ALRSknGf1l5IfY08=", + "version": "2.4.11", + "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", + "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", "requires": { - "inherits": "2.0.3" + "inherits": "2.0.3", + "safe-buffer": "5.1.1" } }, "shasum": { @@ -2007,17 +2111,7 @@ "integrity": "sha1-5wEjENj0F/TetXEhUOVni4euVl8=", "requires": { "json-stable-stringify": "0.0.1", - "sha.js": "2.4.8" - }, - "dependencies": { - "json-stable-stringify": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-0.0.1.tgz", - "integrity": "sha1-YRwj6BTbN1Un34URk9tZ3Sryf0U=", - "requires": { - "jsonify": "0.0.0" - } - } + "sha.js": "2.4.11" } }, "shebang-command": { @@ -2139,9 +2233,9 @@ } }, "stream-http": { - "version": "2.7.2", - "resolved": "https://registry.npmjs.org/stream-http/-/stream-http-2.7.2.tgz", - "integrity": "sha512-c0yTD2rbQzXtSsFSVhtpvY/vS6u066PcXOX9kBB3mSO76RiUQzL340uJkGBWnlBg4/HZzqiUXtaVA7wcRcJgEw==", + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/stream-http/-/stream-http-2.8.1.tgz", + "integrity": "sha512-cQ0jo17BLca2r0GfRdZKYAGLU6JRoIWxqSOakUMuKOT6MOK7AAlE856L33QuDmAy/eeOrhLee3dZKX0Uadu93A==", "requires": { "builtin-status-codes": "3.0.0", "inherits": "2.0.3", @@ -2225,11 +2319,11 @@ "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=" }, "syntax-error": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/syntax-error/-/syntax-error-1.3.0.tgz", - "integrity": "sha1-HtkmbE1AvnXcVb+bsct3Biu5bKE=", + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/syntax-error/-/syntax-error-1.4.0.tgz", + "integrity": "sha512-YPPlu67mdnHGTup2A8ff7BC2Pjq0e0Yp/IyTFN03zWO0RcK07uLcbi7C2KpGR2FvWbaB0+bfE27a+sBKebSo7w==", "requires": { - "acorn": "4.0.13" + "acorn-node": "1.3.0" } }, "tar": { @@ -2305,9 +2399,9 @@ } }, "tty-browserify": { - "version": "0.0.0", - "resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.0.tgz", - "integrity": "sha1-oVe6QC2iTpv5V/mqadUk7tQpAaY=" + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.1.tgz", + "integrity": "sha512-C3TaO7K81YvjCgQH9Q1S3R3P3BtN3RIM8n+OvX4il1K1zgE8ZhI0op7kClgkxtutIE8hQrcrHBXvIheqKUUCxw==" }, "tunnel-agent": { "version": "0.4.3", @@ -2326,14 +2420,14 @@ "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=" }, "typescript": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-2.4.2.tgz", - "integrity": "sha1-+DlfhdRZJ2BnyYiqQYN6j4KHCEQ=" + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-2.8.1.tgz", + "integrity": "sha512-Ao/f6d/4EPLq0YwzsQz8iXflezpTkQzqAyenTiw4kCUGr1uPiFLC3+fZ+gMZz6eeI/qdRUqvC+HxIJzUAzEFdg==" }, "umd": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/umd/-/umd-3.0.1.tgz", - "integrity": "sha1-iuVW4RAR9jwllnCKiDclnwGz1g4=" + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/umd/-/umd-3.0.3.tgz", + "integrity": "sha512-4IcGSufhFshvLNcMCV80UnQVlZ5pMOC8mvNPForqwA4+lzYQuetTESLDQkeLmihq8bRcnpbQa48Wb8Lh16/xow==" }, "url": { "version": "0.11.0", @@ -2352,11 +2446,11 @@ } }, "uswds": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/uswds/-/uswds-1.6.0.tgz", - "integrity": "sha1-Jr9jpEPP2ktk2dQy1tKbqZcEkZ8=", + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/uswds/-/uswds-1.6.1.tgz", + "integrity": "sha512-h7DvkJKOwlCWTT106seB+tJxGNejZ+i3tn/OBs8o3an3lQs0q1oJKu5IgR3t0wsEXZt3zghHvVhmU7vbQjvOQQ==", "requires": { - "@types/node": "8.9.5", + "@types/node": "8.10.0", "array-filter": "1.0.0", "array-foreach": "1.0.2", "browserify": "13.3.0", @@ -2367,15 +2461,10 @@ "object-assign": "4.1.1", "receptor": "1.0.0", "resolve-id-refs": "0.1.0", - "typescript": "2.4.2", + "typescript": "2.8.1", "yargs": "8.0.2" }, "dependencies": { - "@types/node": { - "version": "8.9.5", - "resolved": "https://registry.npmjs.org/@types/node/-/node-8.9.5.tgz", - "integrity": "sha512-jRHfWsvyMtXdbhnz5CVHxaBgnV6duZnPlQuRSo/dm/GnmikNcmZhxIES4E9OZjUmQ8C+HCl4KJux+cXN/ErGDQ==" - }, "ansi-regex": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", diff --git a/package.json b/package.json index 87bf02ba5..951fae6c6 100644 --- a/package.json +++ b/package.json @@ -11,9 +11,9 @@ "node": ">=8.10.0" }, "dependencies": { - "chosen-js": "1.8.x", + "chosen-js": "^1.8.3", "jquery": "3.3.x", - "node-sass": "4.7.x", - "uswds": "^1.6.0" + "node-sass": "4.8.x", + "uswds": "^1.6.1" } } diff --git a/tock/tock/static/img/uswds/angle-arrow-down-primary.png b/tock/tock/static/img/uswds/angle-arrow-down-primary.png new file mode 100644 index 0000000000000000000000000000000000000000..ee7b9ed6009d3d3442ec3e0f622c4dd2d8511f03 GIT binary patch literal 214 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=ffJxt=bLAr-gY_U-0vFyLX$G-hDl zz@mM?YR$yH+8Ir}n^ \ No newline at end of file From fb2897702c89af8ddc4adbd43c57e0205daec3f1 Mon Sep 17 00:00:00 2001 From: Joe Krzystan Date: Wed, 28 Mar 2018 12:27:35 -0400 Subject: [PATCH 43/59] Don't diff generated dependency files and move related docs --- .gitattributes | 2 + README.md | 174 ---------------------------------- docs/dependency-management.md | 28 ++++++ 3 files changed, 30 insertions(+), 174 deletions(-) create mode 100644 docs/dependency-management.md diff --git a/.gitattributes b/.gitattributes index 1a6bd4587..c02c2d3ab 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1 +1,3 @@ package-lock.json binary +requirements.txt binary +Pipfile.lock binary diff --git a/README.md b/README.md index a5b3a22ac..d04aa618b 100644 --- a/README.md +++ b/README.md @@ -15,179 +15,5 @@ Read the project documentation in [the `/docs` directory][gh-docs]. Interested in the API docs? Read the API documentation in [the `/api-docs` directory][gh-api-docs]. -<<<<<<< HEAD [gh-docs]: https://github.com/18F/tock/tree/master/docs [gh-api-docs]: https://github.com/18F/tock/tree/master/api-docs -======= -1. Move into the `tock` directory at the repository root: - - ``` - $ cd tock - ``` - -1. Run: - - ```shell - $ docker-compose build - $ docker-compose run app python manage.py migrate - $ docker-compose run app python manage.py loaddata test_data/data-update-deduped.json - $ docker-compose run app \ - python manage.py \ - createsuperuser \ - --username admin.user \ - --email admin.user@gsa.gov \ - --noinput - ``` - -1. Once the above commands are successful, run: - - ``` - docker-compose up - ``` - - This will start up all required servers in containers and output their - log information to stdout. - -1. Visit [http://localhost:8000/][] directly to access the site. - - When prompted for an email address, enter `admin@gsa.gov`. - -You can access the admin panel at `/admin`. - -### Running static analysis tools - -We run two linting tools in continuous integration, -[`flake8`](http://flake8.pycqa.org/en/latest/) for general linting of unused -variables, style, etc. and [`bandit`](https://pypi.python.org/pypi/bandit), a -security-focused linter. - -To run this locally, run: -```sh -docker-compose run app bandit -r . -x manage.py,docker_entrypoint.py -docker-compose run app flake8 -``` - -### Dependency management - -#### Python - -Tock uses [Pipenv] to manage development and production dependencies. -In development and continuous integration the python environment is -established with `pipenv install --dev`. To acommodate 3rd party tools -which do not yet support [Pipenv] a `requirements.txt` file, containing -only production dependencies, is generated by [Pipenv] and included in -the repository. - -Development and production dependencies can be updated locally with: -```sh -pipenv update --dev -pipenv lock --requirements > requirements.txt -``` - -#### Javascript - -Tock uses [npm] to manage javascript dependencies. - -Dependencies can be updated locally with: -```sh -npm update -``` - -### Accessing the app container - -You'll likely want to run `manage.py` to do other things at some point. -To do this, it's probably easiest to run: - -``` -docker-compose run app bash -``` - -This will run an interactive bash session inside the main app container. -In this container, the `/tock` directory is mapped to the `tock` -directory of the repository on your host; you can run `manage.py` from there. - -#### Running `pdb` within the Docker container - -Once you have a running set containers, you should be able to attach to the -`tock_app` CONTAINER_ID using the following command. - -```sh -docker attach $(docker container ps | grep -E 'tock_app' | awk '{ print $1 }') -``` - -This will drop you into the `tock_app` container. Now you can use `pdb` in your -local code and have a Python Debugger. - -##### Exiting the debugger - -To properly exit the debugger, use the following keyboard commands within the -container: `Control + p, Control + q` one after another. - -If you mistakenly hit `Control + c` you will kill the `tock_app` container! In -that case, restart the `tock_app` container with a `docker-compose up` command. - -### Making CSS changes - -`docker-compose up` will also launch a [Node] machine that compiles the [Sass] -files in `tock/tock/static/sass` into corresponding CSS files in -`tock/tock/static/css/dist`. **The generated CSS files are not checked into -git, and should not be modified by hand.** - -You can also run the CSS build and watch scripts outside of the Docker -container. Just install [Node][] (e.g. with `brew install node` on OS X), then -install the dependencies with: - -```sh -npm install -``` - -Assuming that goes off without a hitch, you can then either build the CSS in -one go with: - -``` -npm run build-css -``` - -or start the watch process, which builds new CSS whenever the source Sass files -are changed: - -``` -npm run watch-css -``` - -## API - -Tock has an API! You may issue GET requests to various [endpoints](https://github.com/18F/tock/tree/master/api-docs) via the /api/ path with results returned as JSON objects. We use Django REST framework's TokenAuthentication library which requires all requests to include a token value in your request header using the following format (a cURL command line based request is used for this example for getting project data from our Tock deployment): -``` -$ curl https://tock.18f.gov/api/projects.json -H 'Authorization: Token randomalphanumericstringed854b18ba024327' -``` -To obtain your own Tock API authorization token, please visit [#tock-dev](https://gsa-tts.slack.com/messages/tock-dev/) on Slack! - -To access similar data in CSV format from within Tock, please visit the [/reports](https://tock.18f.gov/reports) page. - -## Authentication - -18F's current deployment of Tock relies on -[cloud.gov's User Account and Authentication (UAA) server][UAA] for -authentication. - -During development, a ["fake" cloud.gov UAA server][fakeUAA] is used for -authentication. Here you can actually enter any email address; if the -address is `@gsa.gov`, then a non-staff account will automatically -be created for the user and you'll be logged-in, but otherwise access -will be denied. - -The easiest way to create an administrative user is to first use -`manage.py createsuperuser` to create a user, and then log in -with that user's email address. See the "Getting Started" section -for an example of this. - -[Docker]: https://www.docker.com/ -[http://localhost:8000/]: http://localhost:8000/ -[Sass]: http://sass-lang.com/ -[Node]: https://nodejs.org/en/ -[UAA]: https://cloud.gov/docs/apps/leveraging-authentication/ -[fakeUAA]: http://cg-django-uaa.readthedocs.io/en/latest/quickstart.html#using-the-fake-cloud-gov-server -[Pipenv]: https://docs.pipenv.org/ -[npm]: https://www.npmjs.com ->>>>>>> c63780c... JS dependency updates diff --git a/docs/dependency-management.md b/docs/dependency-management.md new file mode 100644 index 000000000..b14a13ed2 --- /dev/null +++ b/docs/dependency-management.md @@ -0,0 +1,28 @@ +# Dependency management + +## Python + +Tock uses [Pipenv] to manage development and production dependencies. +In development and continuous integration the python environment is +established with `pipenv install --dev`. To acommodate 3rd party tools +which do not yet support [Pipenv] a `requirements.txt` file, containing +only production dependencies, is generated by [Pipenv] and included in +the repository. + +Development and production dependencies can be updated locally with: +```sh +pipenv update --dev +pipenv lock --requirements > requirements.txt +``` + +## Javascript + +Tock uses [npm] to manage javascript dependencies. + +Dependencies can be updated locally with: +```sh +npm update +``` + +[Pipenv]: https://docs.pipenv.org/ +[npm]: https://www.npmjs.com \ No newline at end of file From 6930ea0875bd6f9285ebf7e7e0a3d416342e0a13 Mon Sep 17 00:00:00 2001 From: Roger Steve Ruiz Date: Wed, 28 Mar 2018 17:19:41 -0400 Subject: [PATCH 44/59] Refactor name to what's used in staging & prod --- bin/run.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bin/run.sh b/bin/run.sh index 3aa8cc7f8..d8eb7b3c3 100755 --- a/bin/run.sh +++ b/bin/run.sh @@ -27,7 +27,7 @@ fi NEW_RELIC_API_KEY=$( echo "${VCAP_SERVICES}" | \ - jq '.[] | map(select(.name == "tock-credentials-logging")) | .[].credentials.NEW_RELIC_API_KEY' -r + jq '.[] | map(select(.name == "tock-credentials")) | .[].credentials.NEW_RELIC_API_KEY' -r ) # Append New Relic API key to New Relic INI file for `newrelic-admin` tool From 0fb732dad8db4ccdb0782b7b549afb7c11c72160 Mon Sep 17 00:00:00 2001 From: Roger Steve Ruiz Date: Wed, 28 Mar 2018 11:15:51 -0400 Subject: [PATCH 45/59] More progress on Production documentation --- docs/deployment-process.md | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/docs/deployment-process.md b/docs/deployment-process.md index b2e3a9a97..f9039d2e6 100644 --- a/docs/deployment-process.md +++ b/docs/deployment-process.md @@ -154,9 +154,10 @@ cf zero-downtime-push tock-staging -f manifest-staging.yml ### Production servers Production deploys are also automated. They rely on the creation of a Git tag to -be made against the `master` branch following the -from CI. However, just like in our CircleCI deployments to staging, we use the -Cloud Foundry [autopilot plugin](https://github.com/contraband/autopilot). +be made against the `master` branch following the [_Automated Releases to +Production_](#automated-releases-to-production) workflow. Sometimes, you may +need to make a manual deployment to production. If this is the case, please make +sure you are using the Cloud Foundry [autopilot plugin](https://github.com/contraband/autopilot). To deploy, first make sure you are targeting the prod space: @@ -170,13 +171,16 @@ Now, if you don't already have the autopilot plugin, you can install it by runni cf install-plugin autopilot -f -r CF-Community ``` -Open the `manifest-production.yml` file and add a `CIRCLE_TAG` value under -`env:` which matches the release that you're manually deploying to production. +Create a `VERSION` file with the name of the version that is being deployed to +production either with the Git SHA1 for the latest commit or the Git Tag for the +latest release. -```yaml -env: - # other variables - CIRCLE_TAG: v20180202.1 +```shell +# Manually creating a VERSION file from the latest Git SHA1 commit +echo $(git rev-parse HEAD | head -c 7) > tock/VERSION + +# Manually creating a VERSION file from the latest Git Tag release +echo $(git describe --abbrev=0 --tags) > tock/VERSION ``` Then use the autopilot plugin's `zero-downtime-push` command to deploy: From 5f52cdc4ad43567468278a05de89a18ad3617d79 Mon Sep 17 00:00:00 2001 From: Roger Steve Ruiz Date: Wed, 28 Mar 2018 17:17:02 -0400 Subject: [PATCH 46/59] Update Data Deletions message --- docs/logging.md | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/docs/logging.md b/docs/logging.md index d0e712b78..5a8a64d5e 100644 --- a/docs/logging.md +++ b/docs/logging.md @@ -17,20 +17,20 @@ access using [cloud.gov's logging system][cg-log-sys]. [cg-log-sys]: https://logs.fr.cloud.gov -| Description | Kibana Query | -| -------------------------- | -------------------------------------------------------------- | -| Deployments | `@cf.app:"tock" AND @message:"Recording deployment of"` | -| Authorization checks | `@cf.app:"tock" AND @message:"tock-auth"` | -| Authentication checks | `@cf.app:"tock" AND @message:"Authenticating user"` | -| Successful login events | `@cf.app:"tock" AND @message:"Successful login"` | -| Unsuccessful login events | `@cf.app:"tock" AND @message:"Unsuccessful login"` | -| Object access * | `@cf.app:"tock" AND @message:"TimecardObject"` | -| Account management events | `@cf.app:"tock" AND @message:"account-management"` | -| All administrator activity | `@cf.app:"tock" AND @message:"admin-log"` | -| Data deletions | `@cf.app:"tock" AND (@message:"remove" OR @message:"delete")` | -| Data access ** | `@cf.app:"tock" AND @message:"/api/reporting_period"` | -| Data changes * | `@cf.app:"tock" AND (@message:"create" OR @message:"change")` | -| Permission Changes | `@cf.app:"tock" AND @message:"account-management"` | +| Description | Kibana Query | +| -------------------------- | ---------------------------------------------------------------- | +| Deployments | `@cf.app:"tock" AND @message:"Recording deployment of"` | +| Authorization checks | `@cf.app:"tock" AND @message:"tock-auth"` | +| Authentication checks | `@cf.app:"tock" AND @message:"Authenticating user"` | +| Successful login events | `@cf.app:"tock" AND @message:"Successful login"` | +| Unsuccessful login events | `@cf.app:"tock" AND @message:"Unsuccessful login"` | +| Object access * | `@cf.app:"tock" AND @message:"TimecardObject"` | +| Account management events | `@cf.app:"tock" AND @message:"account-management"` | +| All administrator activity | `@cf.app:"tock" AND @message:"admin-log"` | +| Data deletions | `@cf.app:"tock" AND (@message:"removed" OR @message:"deleted")` | +| Data access ** | `@cf.app:"tock" AND @message:"/api/reporting_period"` | +| Data changes * | `@cf.app:"tock" AND (@message:"create" OR @message:"change")` | +| Permission Changes | `@cf.app:"tock" AND @message:"account-management"` | \* For "object access" search by Model name, `AND @message:"EmployeeGrade"` From 64deeaf9a19150bf4f8c7879d378451d7e062e19 Mon Sep 17 00:00:00 2001 From: Roger Steve Ruiz Date: Thu, 29 Mar 2018 08:32:59 -0400 Subject: [PATCH 47/59] Remove "Just" and add links --- docs/local-development.md | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/docs/local-development.md b/docs/local-development.md index d48937760..983cef2c1 100644 --- a/docs/local-development.md +++ b/docs/local-development.md @@ -94,7 +94,7 @@ files in `tock/tock/static/sass` into corresponding CSS files in git, and should not be modified by hand.** You can also run the CSS build and watch scripts outside of the Docker -container. Just install [Node][] (e.g. with `brew install node` on OS X), then +container. Install [Node][] (e.g. with `brew install node` on OS X), then install the dependencies with: ```sh @@ -114,3 +114,9 @@ are changed: ``` npm run watch-css ``` + +[Docker]: https://www.docker.com/ +[http://localhost:8000/]: http://localhost:8000/ +[Sass]: http://sass-lang.com/ +[Node]: https://nodejs.org/en/ +[UAA]: https://cloud.gov/docs/apps/leveraging-authentication/ From a774eb2832789a5fe47cd551a001e5f0307f955a Mon Sep 17 00:00:00 2001 From: Roger Steve Ruiz Date: Thu, 29 Mar 2018 08:39:48 -0400 Subject: [PATCH 48/59] Combine release-management and deployment-process --- docs/deployment-process.md | 152 ++++++++++++++++++++++++++++++------- docs/release-management.md | 69 ----------------- 2 files changed, 124 insertions(+), 97 deletions(-) delete mode 100644 docs/release-management.md diff --git a/docs/deployment-process.md b/docs/deployment-process.md index f9039d2e6..d3c585610 100644 --- a/docs/deployment-process.md +++ b/docs/deployment-process.md @@ -11,12 +11,18 @@ Download the Cloud Foundry CLI according to the [cloud.gov instructions][]. You will also need to install the [`autopilot`](https://github.com/contraband/autopilot) plugin for Cloud Foundry, which is used for zero-downtime deploys. -You can install via -`cf install-plugin autopilot -f -r CF-Community`. -Tock is deployed to the GovCloud instance of cloud.gov. You will need to login -to via the GovCloud api of cloud.gov: -`cf login -a api.fr.cloud.gov --sso` +```shell +# Install the plugin +cf install-plugin autopilot -f -r CF-Community +``` + +Tock is deployed to the GovCloud instance of cloud.gov. + +```shell +# Login to cloud.gov +cf login -a api.fr.cloud.gov --sso +``` Then target the org and space you want to work with. For example, if you wanted to work with the dev space: `cf target -o gsa-18f-tock -s dev` @@ -76,31 +82,29 @@ variables, instead of using the local environment (except for [New Relic-related You will need to create a UPS called `tock-credentials`, provide 'credentials' to it, and link it to the application instance. This will need to be done for every Cloud Foundry `space`. - - Then enter the following commands (filling in the main application instance name for ``) to create the user-provided service: ```sh +# Creating and uploading the credentials to the service cf cups tock-credentials -p credentials-.json + +# Binding the service to the app cf bind-service tock-credentials + +# Restaging the app to make use of the updated credentials. This will cause +# downtime in the application. It is better to use zero-downtime-push instead. cf restage ``` You can update the user-provided service with the following commands: ```sh +# Uploading the new credentials to the service cf uups tock-credentials -p credentials-staging.json + +# Restaging the app to make use of the updated credentials. This will cause +# downtime in the application. It is better to use zero-downtime-push instead. cf restage ``` @@ -175,7 +179,7 @@ Create a `VERSION` file with the name of the version that is being deployed to production either with the Git SHA1 for the latest commit or the Git Tag for the latest release. -```shell +```sh # Manually creating a VERSION file from the latest Git SHA1 commit echo $(git rev-parse HEAD | head -c 7) > tock/VERSION @@ -189,6 +193,102 @@ Then use the autopilot plugin's `zero-downtime-push` command to deploy: cf zero-downtime-push tock -f manifest-production.yml ``` +#### Troubleshooting failed manual zero-downtime deployments + +If at any point the deployment fails, there should still be zero-downtime for +the production instance. Please verify that the Tock applications that are +running are named correctly and are cleaned up. In the example commands below +the following variables should be replaced with the values found in the previous +commands. + +- `${STOPPED_TOCK_APP}` - The application that reads `stopped` from `cf apps`. +- `${TOCK_VERNERABLE_APP_NAME}` - The application that reads `-venerable` from + `cf apps`. + +```sh +# List all applications in the targeted space +cf apps + +# Delete the stopped application +cf delete ${STOPPED_TOCK_APP} -f + +# Rename the started application to match project conventions +cf rename ${TOCK_VERNERABLE_APP_NAME} tock +``` + +### Logs + +Logs in cloud.gov-deployed applications are generally viewable by running +`cf logs --recent` + +[UPS]: https://docs.cloudfoundry.org/devguide/services/user-provided.html +[`README.md`]: https://github.com/18F/tock#readme + +## Releasing Tock + +Releasing Tock onto Production happens whenever you create a Git tag and push it +up to the repository. The process is outlined below. + +Git tags can be manually created using the Git CLI as outlined below. You can +also create them in the GitHub Release interface when drafting and publishing +the release. + +## Creating a GitHub Release + +
+GitHub Release Template + +```markdown +### For Those About To Tock + +#### Liner Notes, XX/XX/XXXX + + +--- + +##### Stuff You Can See: + + + +- + +--- + +##### Admin-only Features: + + + +- + +--- + +##### Under The Hood: + + + +- + +--- + +##### Code Contributors for this release + +Team Tock would like to thank: + + + +- +``` + +
+ #### Automated Releases to Production Tock is automatically deployed to Production using CircleCI using GitHub @@ -196,8 +296,12 @@ Releases and Git tags. Tags are versioned using the following structure, the letter `v` followed by the full year, full month, full day, followed by a period and a version number for that release. For example: -``` -v20180131.1 +```sh +# Create the tag +git tag v20180131.1 + +# Push the tags up to GitHub +git push --tags ``` If multiple versions are needed to be released in a single day, increment the @@ -206,11 +310,3 @@ number after the period, e.g. `v20180131.1` turns into `v20180131.2`. Once this tag is pushed up to GitHub, draft or assign it to an already drafted release in GitHub. CircleCI will deploy this tag to the Production instance of Tock using CF Autopilot. - -### Logs - -Logs in cloud.gov-deployed applications are generally viewable by running -`cf logs --recent` - -[UPS]: https://docs.cloudfoundry.org/devguide/services/user-provided.html -[`README.md`]: https://github.com/18F/tock#readme diff --git a/docs/release-management.md b/docs/release-management.md deleted file mode 100644 index a494fcdc7..000000000 --- a/docs/release-management.md +++ /dev/null @@ -1,69 +0,0 @@ -# Releasing Tock - -[:arrow_left: Back to Tock -Documentation](https://github.com/18F/tock/tree/master/docs) - -Releasing Tock onto Production happens whenever you create a Git tag and push it -up to the repository. The process is outlined below. - -## Creating a GitHub Release - - - -
-GitHub Release Template - -```markdown -### For Those About To Tock - -#### Liner Notes, XX/XX/XXXX - - ---- - -##### Stuff You Can See: - - - -- - ---- - -##### Admin-only Features: - - - -- - ---- - -##### Under The Hood: - - - -- - ---- - -##### Code Contributors for this release - -Team Tock would like to thank: - - - -- -``` - -
- -## Create a Git Tag - - From ae6bbff438fcc1d59dd08c4f2377550de27fa33a Mon Sep 17 00:00:00 2001 From: Roger Steve Ruiz Date: Thu, 29 Mar 2018 08:58:12 -0400 Subject: [PATCH 49/59] Final draft for on/off boarding docs --- docs/offboarding.md | 24 +++++++++++++++++++++++- docs/onboarding.md | 31 ++++++++++++++++++++++++------- 2 files changed, 47 insertions(+), 8 deletions(-) diff --git a/docs/offboarding.md b/docs/offboarding.md index ec74d6f5c..25ad2cf7e 100644 --- a/docs/offboarding.md +++ b/docs/offboarding.md @@ -1 +1,23 @@ -# Tock Offboarding +# Leaving the Tock team + +[:arrow_left: Back to Tock +Documentation](https://github.com/18F/tock/tree/master/docs) + +## Offboarding + +When you leave the Tock team, these checklist items will be completed either by +remaining Tock Developers or the Tock Project Owner on the team. For some of the +more technical items, a Tock Developer must perform them. + +## Checklist + +Create a new issue with the following checklist. Swapping out {TockDeveloper} +with the name of the onboarding developer. + +- [ ] {TockDeveloper} no longer has access to New Relic +- [ ] {TockDeveloper} no longer has access to SpaceDeveloper roles in Cloud + Foundry for spaces `staging` and `prod`. +- [ ] Rotating of secrets {TockDeveloper} had access to + - [ ] Rotation of cloud.gov service provider Service Keys + - [ ] Rotating of cloud.gov identity provider Service Keys + - [ ] Rotation of New Relic API key diff --git a/docs/onboarding.md b/docs/onboarding.md index 4beefa01c..1fdfc1f82 100644 --- a/docs/onboarding.md +++ b/docs/onboarding.md @@ -1,5 +1,8 @@ # Joining the Tock team +[:arrow_left: Back to Tock +Documentation](https://github.com/18F/tock/tree/master/docs) + ## Onboarding When you join the Tock team, you may be expected to complete the following @@ -8,17 +11,31 @@ schedule check-in time with you to ensure that you're progressing and aren't stuck. If there is another Tock developer already on the project, you will be assigned them as a buddy to help you progress through onboarding. +## Checklist + +Create a new issue with the following checklist. Swapping out {TockDeveloper} +with the name of the onboarding developer. + +- [ ] {TockDeveloper} has access to New Relic +- [ ] {TockDeveloper} has access to GitHub repository +- [ ] {TockDeveloper} has access to SpaceDeveloper roles in Cloud Foundry for + spaces `staging` and `prod`. +- [ ] {TockDeveloper} is invited to #tock-dev in Slack +- [ ] {TockDeveloper} is familiar with the [deployment process of + Tock](https://github.com/18f/tock/tree/master/docs/deployment-process.md) + + ## Things we maintain - [Tock](tock-app), a Python Django framework web application comprised of multiple sub-apps. - - tock - - employees - - projects - - hours - - organizations - - api - - utilization + - tock - The main application + - employees - The application that manages the employee data + - projects - The application that manages the project data + - hours - The application that manages the hours and reporting data + - organizations - The application that manages organizations + - api - The application that manages the API + - utilization - The application that manages the utilization functionality - [AngryTock](tock-bot), a Golang Slack RTM-based bot - [#tock-dev](tock-chat), a Slack channel where Tock users come for technical support. From 4b4e8e9ecfb8643179b23d2091be8e86d4ca7612 Mon Sep 17 00:00:00 2001 From: Roger Steve Ruiz Date: Mon, 2 Apr 2018 09:18:20 -0400 Subject: [PATCH 50/59] Refactor config to use placeholder variables --- .circleci/config.yml | 30 +++++++++++++++++------------- 1 file changed, 17 insertions(+), 13 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index f601b7214..046a6aacb 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -2,6 +2,16 @@ # # Check https://circleci.com/docs/2.0/language-python/ for more details # +cf-docker-image: &CF_DOCKER_IMAGE + docker: + - image: 18fgsa/cloud-foundry-cli + environment: + - TZ=America/New_York + - CF_API: https://api.fr.cloud.gov +working-directory: &WORKING_DIRECTORY + working_directory: ~/repo + + version: 2 jobs: build: @@ -21,7 +31,7 @@ jobs: - POSTGRES_USER=circleci - POSTGRES_DB=tock-test - working_directory: ~/repo + <<: *WORKING_DIRECTORY steps: - checkout @@ -70,13 +80,10 @@ jobs: - ./* deploy_to_staging: - docker: - - image: 18fgsa/cloud-foundry-cli - environment: - - TZ=America/New_York - - CF_API: https://api.fr.cloud.gov + <<: *CF_DOCKER_IMAGE + + <<: *WORKING_DIRECTORY - working_directory: ~/repo steps: - attach_workspace: at: . @@ -88,12 +95,9 @@ jobs: cf_deploy.sh tock gsa-18f-tock staging manifest-staging.yml deploy_to_production: - docker: - - image: 18fgsa/cloud-foundry-cli - environment: - - TZ=America/New_York - - CF_API: https://api.fr.cloud.gov - working_directory: ~/repo + <<: *CF_DOCKER_IMAGE + + <<: *WORKING_DIRECTORY steps: - attach_workspace: From ab51e948a84d3796f33edb18caba05c79e44b666 Mon Sep 17 00:00:00 2001 From: Roger Steve Ruiz Date: Mon, 2 Apr 2018 09:32:25 -0400 Subject: [PATCH 51/59] Add recycle for production on schedule --- .circleci/config.yml | 26 +++++++++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 046a6aacb..2dc26e2fa 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -104,10 +104,24 @@ jobs: at: . - run: name: deploy Tock Production to cloud.gov + + recycle_production: + <<: *CF_DOCKER_IMAGE + + <<: *WORKING_DIRECTORY + + steps: + - run: + name: Login to cloud.gov Production + command: cf login -a ${CF_API} -u ${CF_DEPLOYER_USERNAME_PRODUCTION} -p ${CF_DEPLOYER_PASSWORD_PRODUCTION} + - run: + name: Install cf-recycle-plugin 1.0.0 release command: | - cf login -a ${CF_API} -u ${CF_DEPLOYER_USERNAME_PRODUCTION} -p ${CF_DEPLOYER_PASSWORD_PRODUCTION} - echo ${CIRCLE_TAG} > tock/VERSION - cf_deploy.sh tock gsa-18f-tock prod manifest-production.yml + curl -o cf-recycle-plugin https://github.com/rogeruiz/cf-recycle-plugin/releases/download/v1.0.0/cf-recycle-plugin.linux64 + cf install-plugin cf-recycle-plugin -f + - run: + name: Recycle Tock Production instances + command: cf recycle tock workflows: version: 2 @@ -145,3 +159,9 @@ workflows: only: /v20[1-9][0-9][0-9]+\.[0-9]+/ branches: ignore: /.*/ + recycle-prod: + jobs: + - recycle_production + triggers: + - schedule: + cron: "0 10 * * *" # Roughly 5am ET From 4eb536266e59e70844d7e938fa46e5852e1364cf Mon Sep 17 00:00:00 2001 From: Roger Steve Ruiz Date: Mon, 2 Apr 2018 09:33:28 -0400 Subject: [PATCH 52/59] Refactor deployments with more named commands --- .circleci/config.yml | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 2dc26e2fa..4050be3e1 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -87,12 +87,15 @@ jobs: steps: - attach_workspace: at: . + - run: + name: Login to cloud.gov Staging + command: cf login -a ${CF_API} -u ${CF_DEPLOYER_USERNAME_STAGING} -p ${CF_DEPLOYER_PASSWORD_STAGING} + - run: + name: Save version to file system + command: echo ${CIRCLE_SHA1} > tock/VERSION - run: name: deploy Tock Staging to cloud.gov - command: | - cf login -a ${CF_API} -u ${CF_DEPLOYER_USERNAME_STAGING} -p ${CF_DEPLOYER_PASSWORD_STAGING} - echo ${CIRCLE_SHA1} > tock/VERSION - cf_deploy.sh tock gsa-18f-tock staging manifest-staging.yml + command: cf_deploy.sh tock gsa-18f-tock staging manifest-staging.yml deploy_to_production: <<: *CF_DOCKER_IMAGE @@ -103,7 +106,14 @@ jobs: - attach_workspace: at: . - run: - name: deploy Tock Production to cloud.gov + name: Login to cloud.gov Production + command: cf login -a ${CF_API} -u ${CF_DEPLOYER_USERNAME_PRODUCTION} -p ${CF_DEPLOYER_PASSWORD_PRODUCTION} + - run: + name: Save version to file system + command: echo ${CIRCLE_TAG} > tock/VERSION + - run: + name: Deploy Tock Production to cloud.gov + command: cf_deploy.sh tock gsa-18f-tock prod manifest-production.yml recycle_production: <<: *CF_DOCKER_IMAGE From 275427c424d7219e0e42cd0f1d34ed724f9dc03b Mon Sep 17 00:00:00 2001 From: Roger Steve Ruiz Date: Mon, 2 Apr 2018 09:46:29 -0400 Subject: [PATCH 53/59] CircleCI requires filters; This shouldn't actually affect the recycle as we don't do a code check out on the file system for this job. --- .circleci/config.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.circleci/config.yml b/.circleci/config.yml index 4050be3e1..5ff772065 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -175,3 +175,6 @@ workflows: triggers: - schedule: cron: "0 10 * * *" # Roughly 5am ET + filters: + branches: + only: master From ba1a5f38640ff55f6af24c03d8f02a1b0b6c3d23 Mon Sep 17 00:00:00 2001 From: Roger Steve Ruiz Date: Mon, 2 Apr 2018 10:28:22 -0400 Subject: [PATCH 54/59] Make plugin executable --- .circleci/config.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.circleci/config.yml b/.circleci/config.yml index 5ff772065..b95765976 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -128,6 +128,7 @@ jobs: name: Install cf-recycle-plugin 1.0.0 release command: | curl -o cf-recycle-plugin https://github.com/rogeruiz/cf-recycle-plugin/releases/download/v1.0.0/cf-recycle-plugin.linux64 + chmod +x cf-recycle-plugin cf install-plugin cf-recycle-plugin -f - run: name: Recycle Tock Production instances From 644780264783e4f7df86f4f51349909c26b2a6c6 Mon Sep 17 00:00:00 2001 From: Roger Steve Ruiz Date: Mon, 2 Apr 2018 10:34:16 -0400 Subject: [PATCH 55/59] Follow redirects to binary --- .circleci/config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index b95765976..51ea0a546 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -127,7 +127,7 @@ jobs: - run: name: Install cf-recycle-plugin 1.0.0 release command: | - curl -o cf-recycle-plugin https://github.com/rogeruiz/cf-recycle-plugin/releases/download/v1.0.0/cf-recycle-plugin.linux64 + curl -L -o cf-recycle-plugin https://github.com/rogeruiz/cf-recycle-plugin/releases/download/v1.0.0/cf-recycle-plugin.linux64 chmod +x cf-recycle-plugin cf install-plugin cf-recycle-plugin -f - run: From b18ed88945fbf3d5816a0a36be800eb03a5dd0cd Mon Sep 17 00:00:00 2001 From: Roger Steve Ruiz Date: Mon, 2 Apr 2018 10:47:47 -0400 Subject: [PATCH 56/59] Allow for filters to any branch --- .circleci/config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 51ea0a546..3712e46ba 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -178,4 +178,4 @@ workflows: cron: "0 10 * * *" # Roughly 5am ET filters: branches: - only: master + only: /.*/ From c672dc91274356c2fb26bb65543b81a0d9a54af7 Mon Sep 17 00:00:00 2001 From: Carlo Costino Date: Tue, 3 Apr 2018 12:41:44 -0400 Subject: [PATCH 57/59] Update Django and several project-related dependencies This changeset updates Django to the latest security release for 1.11, and accounts for several other system-level dependencies with the Docker and CircleCI configurations to make sure things are kept up to date with recent security releases. --- .cfignore | 1 + .circleci/config.yml | 2 +- Dockerfile | 2 +- Pipfile.lock | 56 ++++++++++++++++++++++++-------------------- docker-compose.yml | 4 ++-- requirements.txt | 2 +- 6 files changed, 36 insertions(+), 31 deletions(-) diff --git a/.cfignore b/.cfignore index e229385ea..15b17a2a9 100644 --- a/.cfignore +++ b/.cfignore @@ -22,6 +22,7 @@ var/ *.egg-info/ .installed.cfg *.egg +requirements.txt # PyInstaller # Usually these files are written by a python script from a template diff --git a/.circleci/config.yml b/.circleci/config.yml index 3712e46ba..2f9cea369 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -26,7 +26,7 @@ jobs: # Specify service dependencies here if necessary # CircleCI maintains a library of pre-built images # documented at https://circleci.com/docs/2.0/circleci-images/ - - image: circleci/postgres:9.6.6 + - image: circleci/postgres:9.6.8 environment: - POSTGRES_USER=circleci - POSTGRES_DB=tock-test diff --git a/Dockerfile b/Dockerfile index 5a2ed6b73..f1fc38d08 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM python:3.6.4 +FROM python:3.6.5 RUN apt-get update && apt-get install -y postgresql-client diff --git a/Pipfile.lock b/Pipfile.lock index 0aa73e634..bc018aa1d 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -21,6 +21,7 @@ "sha256:b8fa79e91f96c2c2cd9fd1f9eda906efb1b88b483048978ba62fef680e962b34", "sha256:eb7386f632349d10d9ce9d4a838b134d4731571851149f9cc2c05a9a837a9a44" ], + "index": "pypi", "version": "==2.1.3" }, "certifi": { @@ -35,12 +36,14 @@ "sha256:7815bffcc4a3db350f92517157fafc577c11b5a7ff172dc5632f1042b93073e8", "sha256:c7a91a4c82431acfc35db664c194d5e6cc7f4df3dcb692d0f836a6ceb0156167" ], + "index": "pypi", "version": "==0.5.3" }, "cg-django-uaa": { "hashes": [ "sha256:a12e502729b45e2b0d35e37e8fd2c6dadbd448411f883776071dcb91051bd81e" ], + "index": "pypi", "version": "==1.3.0" }, "chardet": { @@ -55,26 +58,30 @@ "sha256:4aeaeb1f573c74835b0686a2b46b85990571159ffc21aa57ecd4d1e1cb334163", "sha256:851785365761ebe4994a921b433062309eb882fedd318e1b0fcecc607ed02da9" ], + "index": "pypi", "version": "==0.5.0" }, "django": { "hashes": [ - "sha256:74077d7309b48b97dacdac2dfb35c968028becf00a7a684e7f29b2af1b980edc", - "sha256:fd186d544c7c2f835668cf11f77be071307c9eb22615a5b3a16bdb14c8357f41" + "sha256:056fe5b9e1f8f7fed9bb392919d64f6b33b3a71cfb0f170a90ee277a6ed32bc2", + "sha256:4d398c7b02761e234bbde490aea13ea94cb539ceeb72805b72303f348682f2eb" ], - "version": "==1.11.11" + "index": "pypi", + "version": "==1.11.12" }, "djangorestframework": { "hashes": [ "sha256:0f9bfbac702f3376dfb2db4971ad8af4e066bfa35393b1b85e085f7e8b91189a", "sha256:de8ac68b3cf6dd41b98e01dcc92dc0022a5958f096eafc181a17fa975d18ca42" ], + "index": "pypi", "version": "==3.6.4" }, "djangorestframework-csv": { "hashes": [ "sha256:2f008b20a44f2d3c37835ea5b5ddfe19f54394f07b9cb267c616a917a7f7e27c" ], + "index": "pypi", "version": "==2.1.0" }, "furl": { @@ -115,6 +122,7 @@ "sha256:df52e06a2754c2d905aad75a7dc06a732c804d9edbc87f06f47c8f483ba98bca", "sha256:fce894a64db3911897cdad6c37fbb23dfb18b7bf8b9cb8c00a8ea0a7253651c9" ], + "index": "pypi", "version": "==1.2.2" }, "greenlet": { @@ -144,6 +152,7 @@ "sha256:75af03c99389535f218cc596c7de74df4763803f7b63eb09d77e92b3956b36c6", "sha256:eee1169f0ca667be05db3351a0960765620dad53f53434262ff8901b68a1b622" ], + "index": "pypi", "version": "==19.7.1" }, "html5lib": { @@ -164,6 +173,7 @@ "hashes": [ "sha256:fe010adbbaf16ac18583e5b8601e8c2811c7901b5f03a33ef065fb1b2f565444" ], + "index": "pypi", "version": "==3.0.0.89" }, "orderedmultidict": { @@ -202,6 +212,7 @@ "sha256:d8940b5104588d6313315e037f0f5ed68d2e5f62ccc1c429d3cff11d2ba6de3f", "sha256:de4f88f823037a71ea5ef3c1041d96b8a68d73343133edda684fd42f575bd9d7" ], + "index": "pypi", "version": "==2.7.4" }, "pyjwt": { @@ -264,6 +275,7 @@ "sha256:15f43b2e701821b95c9016cf469d29e2a546cb1c7dead584ba82c36f843995cf", "sha256:9d81515f2b5b27051910996e1e860b1332e354d9e7bcf30c98f21dcb6713e0dd" ], + "index": "pypi", "version": "==3.3.1" } }, @@ -273,6 +285,7 @@ "sha256:cb977045497f83ec3a02616973ab845c829cdab8144ce2e757fe031104a9abd4", "sha256:de4cc19d6ba32d6f542c6a1ddadb4404571347d83ef1ed1e7afb7d0b38e0c25b" ], + "index": "pypi", "version": "==1.4.0" }, "beautifulsoup4": { @@ -308,15 +321,9 @@ "sha256:8ed8b7c6791010d359baed66f84f061bba5bd41174bf324c31311e8737602788", "sha256:ae00d68e18d8a20e9c3288ba3875ae03db3a8e892115bf9b83ef20507732bed4" ], + "index": "pypi", "version": "==2.0.15" }, - "configparser": { - "hashes": [ - "sha256:5308b47021bc2340965c371f0f058cc6971a04502638d4244225c49d80db273a" - ], - "markers": "python_version < '3.2'", - "version": "==3.5.0" - }, "coverage": { "hashes": [ "sha256:03481e81d558d30d230bc12999e3edffe392d244349a90f4ef9b88425fac74ba", @@ -356,20 +363,23 @@ "sha256:f3f501f345f24383c0000395b26b726e46758b71393267aeae0bd36f8b3ade80", "sha256:f8a923a85cb099422ad5a2e345fe877bbc89a8a8b23235824a93488150e45f6e" ], + "index": "pypi", "version": "==4.5.1" }, "django": { "hashes": [ - "sha256:74077d7309b48b97dacdac2dfb35c968028becf00a7a684e7f29b2af1b980edc", - "sha256:fd186d544c7c2f835668cf11f77be071307c9eb22615a5b3a16bdb14c8357f41" + "sha256:056fe5b9e1f8f7fed9bb392919d64f6b33b3a71cfb0f170a90ee277a6ed32bc2", + "sha256:4d398c7b02761e234bbde490aea13ea94cb539ceeb72805b72303f348682f2eb" ], - "version": "==1.11.11" + "index": "pypi", + "version": "==1.11.12" }, "django-debug-toolbar": { "hashes": [ "sha256:4af2a4e1e932dadbda197b18585962d4fc20172b4e5a479490bc659fe998864d", "sha256:d9ea75659f76d8f1e3eb8f390b47fc5bad0908d949c34a8a3c4c87978eb40a0f" ], + "index": "pypi", "version": "==1.9.1" }, "django-webtest": { @@ -377,23 +387,15 @@ "sha256:11c32547966917281fb487203a85b28c313670c1874a3d4d99a3632a123a33c4", "sha256:28f41acbd1b9eef4cfc2d312b12f6fe93c3ffce6de925c378abae7778e0b3eff" ], + "index": "pypi", "version": "==1.9.2" }, - "enum34": { - "hashes": [ - "sha256:2d81cbbe0e73112bdfe6ef8576f2238f2ba27dd0d55752a776c41d38b7da2850", - "sha256:644837f692e5f550741432dd3f223bbb9852018674981b1664e5dc339387588a", - "sha256:6bd0f6ad48ec2aa117d3d141940d484deccda84d4fcd884f5c3d93c23ecd8c79", - "sha256:8ad8c4783bf61ded74527bffb48ed9b54166685e4230386a9ed9b1279e2df5b1" - ], - "markers": "python_version < '3.4'", - "version": "==1.1.6" - }, "factory-boy": { "hashes": [ "sha256:bd5a096d0f102d79b6c78cef1c8c0b650f2e1a3ecba351c735c6d2df8dabd29c", "sha256:be2abc8092294e4097935a29b4e37f5b9ed3e4205e2e32df215c0315b625995e" ], + "index": "pypi", "version": "==2.10.0" }, "faker": { @@ -408,6 +410,7 @@ "sha256:7253265f7abd8b313e3892944044a365e3f4ac3fcdcfb4298f55ee9ddf188ba0", "sha256:c7841163e2b576d435799169b78703ad6ac1bbb0f199994fc05f700b2a90ea37" ], + "index": "pypi", "version": "==3.5.0" }, "gitdb2": { @@ -443,14 +446,15 @@ "sha256:334542aa5760e13fd546060d188850660eade7bc0b447618035e488fb3e1380b", "sha256:7386feb6a7bdf38e365bbb0fec917a75e0e642bf62bb8eaede8fba60d3cb5fea" ], + "index": "pypi", "version": "==0.9.0" }, "pbr": { "hashes": [ - "sha256:8b9a7c3704657cb0831b3ded0a6b61377947c8235b76649bb7de4bfe2e6cfa56", - "sha256:cf66675e22ae91a4f20e4b8354f117d3e3d1de651513051d109cc39645fb3672" + "sha256:56b7a8ba7d64bf6135a9dfefb85a80d95924b3fde5ed6343a1a1d464a040dae3", + "sha256:de75cf1d510542c746beeff66b52241eb12c8f95f2ef846ee50ed5d72392caa4" ], - "version": "==4.0.0" + "version": "==4.0.1" }, "pycodestyle": { "hashes": [ diff --git a/docker-compose.yml b/docker-compose.yml index 757f224d8..d670a6482 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -18,12 +18,12 @@ app: - "8000:8000" command: "python manage.py runserver 0.0.0.0:8000" db: - image: postgres:9.6.6 + image: postgres:9.6.8 environment: - POSTGRES_DB=tock - POSTGRES_USER=tock_user sass: - image: node:8.10.0 + image: node:8.11.1 volumes: - .:/tock - /tock/node_modules diff --git a/requirements.txt b/requirements.txt index e334dcb1a..903b10520 100644 --- a/requirements.txt +++ b/requirements.txt @@ -4,7 +4,7 @@ cfenv==0.5.3 cg-django-uaa==1.3.0 chardet==3.0.4 dj-database-url==0.5.0 -django==1.11.11 +django==1.11.12 djangorestframework-csv==2.1.0 djangorestframework==3.6.4 furl==1.0.1 From b08ecab0a5d92d09cfacc806995c1c120cca4b1b Mon Sep 17 00:00:00 2001 From: Carlo Costino Date: Tue, 3 Apr 2018 14:33:09 -0400 Subject: [PATCH 58/59] Updated CircleCI config with new Python version h/t to @rogeruiz for calling out that I failed to save the file with the change... --- .circleci/config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 2f9cea369..ccbdba2b3 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -18,7 +18,7 @@ jobs: docker: # specify the version you desire here # use `-browsers` prefix for selenium tests, e.g. `3.6.1-browsers` - - image: circleci/python:3.6.4-jessie-node-browsers + - image: circleci/python:3.6.5-jessie-node-browsers environment: - TZ=America/New_York - PIPENV_VENV_IN_PROJECT=true From dec2eecd0455ce0b2153c315783b4cb78fa2ff28 Mon Sep 17 00:00:00 2001 From: Carlo Costino Date: Tue, 3 Apr 2018 16:35:55 -0400 Subject: [PATCH 59/59] Remove requirements.txt from .cfignore This changeset restores the requirements.txt file to be read by Cloud Foundry with the Python buildpack to account for a pipenv issue currently taking place, which breaks deployments. --- .cfignore | 1 - 1 file changed, 1 deletion(-) diff --git a/.cfignore b/.cfignore index 15b17a2a9..e229385ea 100644 --- a/.cfignore +++ b/.cfignore @@ -22,7 +22,6 @@ var/ *.egg-info/ .installed.cfg *.egg -requirements.txt # PyInstaller # Usually these files are written by a python script from a template