aboutsummaryrefslogtreecommitdiffstats
path: root/src/account
diff options
context:
space:
mode:
authorGergely Csatari <gergely.csatari@nokia.com>2023-10-26 10:33:28 +0300
committerGergely Csatari <gergely.csatari@nokia.com>2023-10-26 10:34:28 +0300
commit2ec0d7b9f5c1354977b821c6b06c24a3ffa13142 (patch)
tree6e449d92ddfc880ed007e9d8a8f25bda8fc7cb0f /src/account
parent0d3dd290aa6e7f39e7b0b3cbe448b6622f924240 (diff)
Removing project content and adding a noteHEADmaster
that the development continues in GitHub Change-Id: I25c58a679dbf92b2367d826429b7cda936bf9f0e Signed-off-by: Gergely Csatari <gergely.csatari@nokia.com>
Diffstat (limited to 'src/account')
-rw-r--r--src/account/__init__.py8
-rw-r--r--src/account/admin.py19
-rw-r--r--src/account/apps.py15
-rw-r--r--src/account/forms.py29
-rw-r--r--src/account/middleware.py35
-rw-r--r--src/account/migrations/0001_initial.py65
-rw-r--r--src/account/migrations/0002_lab_description.py19
-rw-r--r--src/account/migrations/0003_publicnetwork.py25
-rw-r--r--src/account/migrations/0004_downtime.py24
-rw-r--r--src/account/migrations/0005_auto_20200723_2100.py23
-rw-r--r--src/account/migrations/0006_auto_20201109_1947.py23
-rw-r--r--src/account/migrations/0007_userprofile_pulic_user.py18
-rw-r--r--src/account/migrations/0008_auto_20210324_2106.py18
-rw-r--r--src/account/migrations/0009_auto_20210324_2107.py18
-rw-r--r--src/account/migrations/__init__.py0
-rw-r--r--src/account/models.py297
-rw-r--r--src/account/tests/__init__.py8
-rw-r--r--src/account/tests/test_general.py60
-rw-r--r--src/account/urls.py59
-rw-r--r--src/account/views.py226
20 files changed, 0 insertions, 989 deletions
diff --git a/src/account/__init__.py b/src/account/__init__.py
deleted file mode 100644
index b6fef6c..0000000
--- a/src/account/__init__.py
+++ /dev/null
@@ -1,8 +0,0 @@
-##############################################################################
-# Copyright (c) 2016 Max Breitenfeldt and others.
-#
-# All rights reserved. This program and the accompanying materials
-# are made available under the terms of the Apache License, Version 2.0
-# which accompanies this distribution, and is available at
-# http://www.apache.org/licenses/LICENSE-2.0
-##############################################################################
diff --git a/src/account/admin.py b/src/account/admin.py
deleted file mode 100644
index b4c142c..0000000
--- a/src/account/admin.py
+++ /dev/null
@@ -1,19 +0,0 @@
-##############################################################################
-# Copyright (c) 2016 Max Breitenfeldt and others.
-# Copyright (c) 2018 Parker Berberian, Sawyer Bergeron, and others.
-#
-# All rights reserved. This program and the accompanying materials
-# are made available under the terms of the Apache License, Version 2.0
-# which accompanies this distribution, and is available at
-# http://www.apache.org/licenses/LICENSE-2.0
-##############################################################################
-
-
-from django.contrib import admin
-
-from account.models import UserProfile, Lab, VlanManager, PublicNetwork
-
-admin.site.register(UserProfile)
-admin.site.register(Lab)
-admin.site.register(VlanManager)
-admin.site.register(PublicNetwork)
diff --git a/src/account/apps.py b/src/account/apps.py
deleted file mode 100644
index 9814648..0000000
--- a/src/account/apps.py
+++ /dev/null
@@ -1,15 +0,0 @@
-##############################################################################
-# Copyright (c) 2016 Max Breitenfeldt and others.
-#
-# All rights reserved. This program and the accompanying materials
-# are made available under the terms of the Apache License, Version 2.0
-# which accompanies this distribution, and is available at
-# http://www.apache.org/licenses/LICENSE-2.0
-##############################################################################
-
-
-from django.apps import AppConfig
-
-
-class AccountsConfig(AppConfig):
- name = 'account'
diff --git a/src/account/forms.py b/src/account/forms.py
deleted file mode 100644
index 28cb27d..0000000
--- a/src/account/forms.py
+++ /dev/null
@@ -1,29 +0,0 @@
-##############################################################################
-# Copyright (c) 2016 Max Breitenfeldt and others.
-#
-# All rights reserved. This program and the accompanying materials
-# are made available under the terms of the Apache License, Version 2.0
-# which accompanies this distribution, and is available at
-# http://www.apache.org/licenses/LICENSE-2.0
-##############################################################################
-
-
-import django.forms as forms
-import pytz as pytz
-from django.utils.translation import gettext_lazy as _
-
-from account.models import UserProfile
-
-
-class AccountSettingsForm(forms.ModelForm):
- class Meta:
- model = UserProfile
- fields = ['company', 'email_addr', 'public_user', 'ssh_public_key', 'pgp_public_key', 'timezone']
- labels = {
- 'email_addr': _('Email Address'),
- 'ssh_public_key': _('SSH Public Key'),
- 'pgp_public_key': _('PGP Public Key'),
- 'public_user': _('Public User')
- }
-
- timezone = forms.ChoiceField(choices=[(x, x) for x in pytz.common_timezones], initial='UTC')
diff --git a/src/account/middleware.py b/src/account/middleware.py
deleted file mode 100644
index 6a46dfe..0000000
--- a/src/account/middleware.py
+++ /dev/null
@@ -1,35 +0,0 @@
-##############################################################################
-# Copyright (c) 2016 Max Breitenfeldt and others.
-#
-# All rights reserved. This program and the accompanying materials
-# are made available under the terms of the Apache License, Version 2.0
-# which accompanies this distribution, and is available at
-# http://www.apache.org/licenses/LICENSE-2.0
-##############################################################################
-
-
-from django.utils import timezone
-from django.utils.deprecation import MiddlewareMixin
-
-from account.models import UserProfile
-
-
-class TimezoneMiddleware(MiddlewareMixin):
- """
- Manage user's Timezone preference.
-
- Activate the timezone from request.user.userprofile if user is authenticated,
- deactivate the timezone otherwise and use default (UTC)
- """
-
- def process_request(self, request):
- if request.user.is_authenticated:
- try:
- tz = request.user.userprofile.timezone
- timezone.activate(tz)
- except UserProfile.DoesNotExist:
- UserProfile.objects.create(user=request.user)
- tz = request.user.userprofile.timezone
- timezone.activate(tz)
- else:
- timezone.deactivate()
diff --git a/src/account/migrations/0001_initial.py b/src/account/migrations/0001_initial.py
deleted file mode 100644
index c8b5bdc..0000000
--- a/src/account/migrations/0001_initial.py
+++ /dev/null
@@ -1,65 +0,0 @@
-# Generated by Django 2.1 on 2018-09-14 14:48
-
-import account.models
-from django.conf import settings
-from django.db import migrations, models
-import django.db.models.deletion
-
-
-class Migration(migrations.Migration):
-
- initial = True
-
- dependencies = [
- migrations.swappable_dependency(settings.AUTH_USER_MODEL),
- ]
-
- operations = [
- migrations.CreateModel(
- name='Lab',
- fields=[
- ('name', models.CharField(max_length=200, primary_key=True, serialize=False, unique=True)),
- ('contact_email', models.EmailField(blank=True, max_length=200, null=True)),
- ('contact_phone', models.CharField(blank=True, max_length=20, null=True)),
- ('status', models.IntegerField(default=0)),
- ('location', models.TextField(default='unknown')),
- ('api_token', models.CharField(max_length=50)),
- ('lab_user', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
- ],
- ),
- migrations.CreateModel(
- name='UserProfile',
- fields=[
- ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
- ('timezone', models.CharField(default='UTC', max_length=100)),
- ('ssh_public_key', models.FileField(blank=True, null=True, upload_to=account.models.upload_to)),
- ('pgp_public_key', models.FileField(blank=True, null=True, upload_to=account.models.upload_to)),
- ('email_addr', models.CharField(default='email@mail.com', max_length=300)),
- ('company', models.CharField(max_length=200)),
- ('oauth_token', models.CharField(max_length=1024)),
- ('oauth_secret', models.CharField(max_length=1024)),
- ('jira_url', models.CharField(default='', max_length=100)),
- ('full_name', models.CharField(default='', max_length=100)),
- ('booking_privledge', models.BooleanField(default=False)),
- ('user', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
- ],
- options={
- 'db_table': 'user_profile',
- },
- ),
- migrations.CreateModel(
- name='VlanManager',
- fields=[
- ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
- ('vlans', models.TextField()),
- ('block_size', models.IntegerField()),
- ('allow_overlapping', models.BooleanField()),
- ('reserved_vlans', models.TextField()),
- ],
- ),
- migrations.AddField(
- model_name='lab',
- name='vlan_manager',
- field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, to='account.VlanManager'),
- ),
- ]
diff --git a/src/account/migrations/0002_lab_description.py b/src/account/migrations/0002_lab_description.py
deleted file mode 100644
index 445501a..0000000
--- a/src/account/migrations/0002_lab_description.py
+++ /dev/null
@@ -1,19 +0,0 @@
-# Generated by Django 2.1 on 2018-09-14 20:22
-
-from django.db import migrations, models
-
-
-class Migration(migrations.Migration):
-
- dependencies = [
- ('account', '0001_initial'),
- ]
-
- operations = [
- migrations.AddField(
- model_name='lab',
- name='description',
- field=models.CharField(default='Lab description default', max_length=240),
- preserve_default=False,
- ),
- ]
diff --git a/src/account/migrations/0003_publicnetwork.py b/src/account/migrations/0003_publicnetwork.py
deleted file mode 100644
index 71e5caa..0000000
--- a/src/account/migrations/0003_publicnetwork.py
+++ /dev/null
@@ -1,25 +0,0 @@
-# Generated by Django 2.1 on 2018-09-26 14:41
-
-from django.db import migrations, models
-import django.db.models.deletion
-
-
-class Migration(migrations.Migration):
-
- dependencies = [
- ('account', '0002_lab_description'),
- ]
-
- operations = [
- migrations.CreateModel(
- name='PublicNetwork',
- fields=[
- ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
- ('vlan', models.IntegerField()),
- ('in_use', models.BooleanField(default=False)),
- ('cidr', models.CharField(default='0.0.0.0/0', max_length=50)),
- ('gateway', models.CharField(default='0.0.0.0', max_length=50)),
- ('lab', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='account.Lab')),
- ],
- ),
- ]
diff --git a/src/account/migrations/0004_downtime.py b/src/account/migrations/0004_downtime.py
deleted file mode 100644
index fc700d1..0000000
--- a/src/account/migrations/0004_downtime.py
+++ /dev/null
@@ -1,24 +0,0 @@
-# Generated by Django 2.2 on 2019-08-13 16:45
-
-from django.db import migrations, models
-import django.db.models.deletion
-
-
-class Migration(migrations.Migration):
-
- dependencies = [
- ('account', '0003_publicnetwork'),
- ]
-
- operations = [
- migrations.CreateModel(
- name='Downtime',
- fields=[
- ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
- ('start', models.DateTimeField()),
- ('end', models.DateTimeField()),
- ('description', models.TextField(default='This lab will be down for maintenance')),
- ('lab', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='account.Lab')),
- ],
- ),
- ]
diff --git a/src/account/migrations/0005_auto_20200723_2100.py b/src/account/migrations/0005_auto_20200723_2100.py
deleted file mode 100644
index d995f80..0000000
--- a/src/account/migrations/0005_auto_20200723_2100.py
+++ /dev/null
@@ -1,23 +0,0 @@
-# Generated by Django 2.2 on 2020-07-23 21:00
-
-from django.db import migrations, models
-
-
-class Migration(migrations.Migration):
-
- dependencies = [
- ('account', '0004_downtime'),
- ]
-
- operations = [
- migrations.AddField(
- model_name='lab',
- name='lab_info_link',
- field=models.URLField(null=True),
- ),
- migrations.AddField(
- model_name='lab',
- name='project',
- field=models.CharField(default='LaaS', max_length=100),
- ),
- ]
diff --git a/src/account/migrations/0006_auto_20201109_1947.py b/src/account/migrations/0006_auto_20201109_1947.py
deleted file mode 100644
index d08c426..0000000
--- a/src/account/migrations/0006_auto_20201109_1947.py
+++ /dev/null
@@ -1,23 +0,0 @@
-# Generated by Django 2.2 on 2020-11-09 19:47
-
-from django.db import migrations, models
-
-
-class Migration(migrations.Migration):
-
- dependencies = [
- ('account', '0005_auto_20200723_2100'),
- ]
-
- operations = [
- migrations.AlterField(
- model_name='userprofile',
- name='full_name',
- field=models.CharField(blank=True, default='', max_length=100, null=True),
- ),
- migrations.AlterField(
- model_name='userprofile',
- name='jira_url',
- field=models.CharField(blank=True, default='', max_length=100, null=True),
- ),
- ]
diff --git a/src/account/migrations/0007_userprofile_pulic_user.py b/src/account/migrations/0007_userprofile_pulic_user.py
deleted file mode 100644
index 6a229e6..0000000
--- a/src/account/migrations/0007_userprofile_pulic_user.py
+++ /dev/null
@@ -1,18 +0,0 @@
-# Generated by Django 2.2 on 2021-03-24 21:06
-
-from django.db import migrations, models
-
-
-class Migration(migrations.Migration):
-
- dependencies = [
- ('account', '0006_auto_20201109_1947'),
- ]
-
- operations = [
- migrations.AddField(
- model_name='userprofile',
- name='pulic_user',
- field=models.BooleanField(default=False),
- ),
- ]
diff --git a/src/account/migrations/0008_auto_20210324_2106.py b/src/account/migrations/0008_auto_20210324_2106.py
deleted file mode 100644
index 9ff513d..0000000
--- a/src/account/migrations/0008_auto_20210324_2106.py
+++ /dev/null
@@ -1,18 +0,0 @@
-# Generated by Django 2.2 on 2021-03-24 21:06
-
-from django.db import migrations
-
-
-class Migration(migrations.Migration):
-
- dependencies = [
- ('account', '0007_userprofile_pulic_user'),
- ]
-
- operations = [
- migrations.RenameField(
- model_name='userprofile',
- old_name='pulic_user',
- new_name='public_user',
- ),
- ]
diff --git a/src/account/migrations/0009_auto_20210324_2107.py b/src/account/migrations/0009_auto_20210324_2107.py
deleted file mode 100644
index baa7382..0000000
--- a/src/account/migrations/0009_auto_20210324_2107.py
+++ /dev/null
@@ -1,18 +0,0 @@
-# Generated by Django 2.2 on 2021-03-24 21:07
-
-from django.db import migrations, models
-
-
-class Migration(migrations.Migration):
-
- dependencies = [
- ('account', '0008_auto_20210324_2106'),
- ]
-
- operations = [
- migrations.AlterField(
- model_name='userprofile',
- name='public_user',
- field=models.BooleanField(default=False),
- ),
- ]
diff --git a/src/account/migrations/__init__.py b/src/account/migrations/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/src/account/migrations/__init__.py
+++ /dev/null
diff --git a/src/account/models.py b/src/account/models.py
deleted file mode 100644
index 32229b1..0000000
--- a/src/account/models.py
+++ /dev/null
@@ -1,297 +0,0 @@
-##############################################################################
-# Copyright (c) 2016 Max Breitenfeldt and others.
-#
-# All rights reserved. This program and the accompanying materials
-# are made available under the terms of the Apache License, Version 2.0
-# which accompanies this distribution, and is available at
-# http://www.apache.org/licenses/LICENSE-2.0
-##############################################################################
-
-
-from django.contrib.auth.models import User
-from django.db import models
-from django.apps import apps
-import json
-import random
-
-from collections import Counter
-
-from dashboard.exceptions import ResourceAvailabilityException
-
-
-class LabStatus(object):
- """
- A Poor man's enum for the status of a lab.
-
- If everything is working fine at a lab, it is UP.
- If it is down temporarily e.g. for maintenance, it is TEMP_DOWN
- If its broken, its DOWN
- """
-
- UP = 0
- TEMP_DOWN = 100
- DOWN = 200
-
-
-def upload_to(object, filename):
- return object.user.username + '/' + filename
-
-
-class UserProfile(models.Model):
- """Extend the Django User model."""
-
- user = models.OneToOneField(User, on_delete=models.CASCADE)
- timezone = models.CharField(max_length=100, blank=False, default='UTC')
- ssh_public_key = models.FileField(upload_to=upload_to, null=True, blank=True)
- pgp_public_key = models.FileField(upload_to=upload_to, null=True, blank=True)
- email_addr = models.CharField(max_length=300, blank=False, default='email@mail.com')
- company = models.CharField(max_length=200, blank=False)
-
- oauth_token = models.CharField(max_length=1024, blank=False)
- oauth_secret = models.CharField(max_length=1024, blank=False)
-
- jira_url = models.CharField(max_length=100, null=True, blank=True, default='')
-
- full_name = models.CharField(max_length=100, null=True, blank=True, default='')
- booking_privledge = models.BooleanField(default=False)
-
- public_user = models.BooleanField(default=False)
-
- class Meta:
- db_table = 'user_profile'
-
- def __str__(self):
- return self.user.username
-
-
-class VlanManager(models.Model):
- """
- Keeps track of the vlans for a lab.
-
- Vlans are represented as indexes into a 4096 element list.
- This list is serialized to JSON for storing in the DB.
- """
-
- # list of length 4096 containing either 0 (not available) or 1 (available)
- vlans = models.TextField()
- # list of length 4096 containing either 0 (not reserved) or 1 (reserved)
- reserved_vlans = models.TextField()
-
- block_size = models.IntegerField()
-
- # True if the lab allows two different users to have the same private vlans
- # if they use QinQ or a vxlan overlay, for example
- allow_overlapping = models.BooleanField()
-
- def get_vlans(self, count=1, within=None):
- """
- Return the IDs of available vlans as a list[int], but does not reserve them.
-
- Will throw index exception if not enough vlans are available.
- Always returns a list of ints
-
- If `within` is not none, will filter against that as a set, requiring that any vlans returned are within that set
- """
- allocated = []
- vlans = json.loads(self.vlans)
- reserved = json.loads(self.reserved_vlans)
-
- for i in range(0, len(vlans) - 1):
- if len(allocated) >= count:
- break
-
- if vlans[i] == 0 and self.allow_overlapping is False:
- continue
-
- if reserved[i] == 1:
- continue
-
- # vlan is available and not reserved, so safe to add
- if within is not None:
- if i in within:
- allocated.append(i)
- else:
- allocated.append(i)
- continue
-
- if len(allocated) != count:
- raise ResourceAvailabilityException("There were not enough available private vlans for the allocation. Please contact the administrators.")
-
- return allocated
-
- def get_public_vlan(self, within=None):
- """Return reference to an available public network without reserving it."""
- r = PublicNetwork.objects.filter(lab=self.lab_set.first(), in_use=False)
- if within is not None:
- r = r.filter(vlan__in=within)
-
- if r.count() < 1:
- raise ResourceAvailabilityException("There were not enough available public vlans for the allocation. Please contact the administrators.")
-
- return r.first()
-
- def reserve_public_vlan(self, vlan):
- """Reserves the Public Network that has the given vlan."""
- net = PublicNetwork.objects.get(lab=self.lab_set.first(), vlan=vlan, in_use=False)
- net.in_use = True
- net.save()
-
- def release_public_vlan(self, vlan):
- """Un-reserves a public network with the given vlan."""
- net = PublicNetwork.objects.get(lab=self.lab_set.first(), vlan=vlan, in_use=True)
- net.in_use = False
- net.save()
-
- def public_vlan_is_available(self, vlan):
- """
- Whether the public vlan is available.
-
- returns true if the network with the given vlan is free to use,
- False otherwise
- """
- net = PublicNetwork.objects.get(lab=self.lab_set.first(), vlan=vlan)
- return not net.in_use
-
- def is_available(self, vlans):
- """
- If the vlans are available.
-
- 'vlans' is either a single vlan id integer or a list of integers
- will return true (available) or false
- """
- if self.allow_overlapping:
- return True
-
- reserved = json.loads(self.reserved_vlans)
- vlan_master_list = json.loads(self.vlans)
- try:
- iter(vlans)
- except Exception:
- vlans = [vlans]
-
- for vlan in vlans:
- if not vlan_master_list[vlan] or reserved[vlan]:
- return False
- return True
-
- def release_vlans(self, vlans):
- """
- Make the vlans available for another booking.
-
- 'vlans' is either a single vlan id integer or a list of integers
- will make the vlans available
- doesnt return a value
- """
- my_vlans = json.loads(self.vlans)
-
- try:
- iter(vlans)
- except Exception:
- vlans = [vlans]
-
- for vlan in vlans:
- my_vlans[vlan] = 1
- self.vlans = json.dumps(my_vlans)
- self.save()
-
- def reserve_vlans(self, vlans):
- """
- Reserves all given vlans or throws a ValueError.
-
- vlans can be an integer or a list of integers.
- """
- my_vlans = json.loads(self.vlans)
-
- reserved = json.loads(self.reserved_vlans)
-
- try:
- iter(vlans)
- except Exception:
- vlans = [vlans]
-
- vlans = set(vlans)
-
- for vlan in vlans:
- if my_vlans[vlan] == 0 or reserved[vlan] == 1:
- raise ValueError("vlan " + str(vlan) + " is not available")
-
- my_vlans[vlan] = 0
- self.vlans = json.dumps(my_vlans)
- self.save()
-
-
-class Lab(models.Model):
- """
- Model representing a Hosting Lab.
-
- Anybody that wants to host resources for LaaS needs to have a Lab model
- We associate hardware with Labs so we know what is available and where.
- """
-
- lab_user = models.OneToOneField(User, on_delete=models.CASCADE)
- name = models.CharField(max_length=200, primary_key=True, unique=True, null=False, blank=False)
- contact_email = models.EmailField(max_length=200, null=True, blank=True)
- contact_phone = models.CharField(max_length=20, null=True, blank=True)
- status = models.IntegerField(default=LabStatus.UP)
- vlan_manager = models.ForeignKey(VlanManager, on_delete=models.CASCADE, null=True)
- location = models.TextField(default="unknown")
- # This token must apear in API requests from this lab
- api_token = models.CharField(max_length=50)
- description = models.CharField(max_length=240)
- lab_info_link = models.URLField(null=True)
- project = models.CharField(default='LaaS', max_length=100)
-
- @staticmethod
- def make_api_token():
- """Generate random 45 character string for API token."""
- alphabet = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
- key = ""
- for i in range(45):
- key += random.choice(alphabet)
- return key
-
- def get_available_resources(self):
- # Cannot import model normally due to ciruclar import
- Server = apps.get_model('resource_inventory', 'Server') # TODO: Find way to import ResourceQuery
- resources = [str(resource.profile) for resource in Server.objects.filter(lab=self, working=True, booked=False)]
- return dict(Counter(resources))
-
- def __str__(self):
- return self.name
-
-
-class PublicNetwork(models.Model):
- """L2/L3 network that can reach the internet."""
-
- vlan = models.IntegerField()
- lab = models.ForeignKey(Lab, on_delete=models.CASCADE)
- in_use = models.BooleanField(default=False)
- cidr = models.CharField(max_length=50, default="0.0.0.0/0")
- gateway = models.CharField(max_length=50, default="0.0.0.0")
-
-
-class Downtime(models.Model):
- """
- A Downtime event.
-
- Labs can create Downtime objects so the dashboard can
- alert users that the lab is down, etc
- """
-
- start = models.DateTimeField()
- end = models.DateTimeField()
- lab = models.ForeignKey(Lab, on_delete=models.CASCADE)
- description = models.TextField(default="This lab will be down for maintenance")
-
- def save(self, *args, **kwargs):
- if self.start >= self.end:
- raise ValueError('Start date is after end date')
-
- # check for overlapping downtimes
- overlap_start = Downtime.objects.filter(lab=self.lab, start__gt=self.start, start__lt=self.end).exists()
- overlap_end = Downtime.objects.filter(lab=self.lab, end__lt=self.end, end__gt=self.start).exists()
-
- if overlap_start or overlap_end:
- raise ValueError('Overlapping Downtime')
-
- return super(Downtime, self).save(*args, **kwargs)
diff --git a/src/account/tests/__init__.py b/src/account/tests/__init__.py
deleted file mode 100644
index b6fef6c..0000000
--- a/src/account/tests/__init__.py
+++ /dev/null
@@ -1,8 +0,0 @@
-##############################################################################
-# Copyright (c) 2016 Max Breitenfeldt and others.
-#
-# All rights reserved. This program and the accompanying materials
-# are made available under the terms of the Apache License, Version 2.0
-# which accompanies this distribution, and is available at
-# http://www.apache.org/licenses/LICENSE-2.0
-##############################################################################
diff --git a/src/account/tests/test_general.py b/src/account/tests/test_general.py
deleted file mode 100644
index 4020d89..0000000
--- a/src/account/tests/test_general.py
+++ /dev/null
@@ -1,60 +0,0 @@
-##############################################################################
-# Copyright (c) 2016 Max Breitenfeldt and others.
-#
-# All rights reserved. This program and the accompanying materials
-# are made available under the terms of the Apache License, Version 2.0
-# which accompanies this distribution, and is available at
-# http://www.apache.org/licenses/LICENSE-2.0
-##############################################################################
-
-
-from django.contrib.auth.models import User
-from django.test import Client
-from django.test import TestCase
-from django.urls import reverse
-from django.utils import timezone
-
-from account.models import UserProfile
-
-
-class AccountMiddlewareTestCase(TestCase):
- def setUp(self):
- self.client = Client()
- self.user1 = User.objects.create(username='user1')
- self.user1.set_password('user1')
- self.user1profile = UserProfile.objects.create(user=self.user1)
- self.user1.save()
-
- def test_timezone_middleware(self):
- """
- Verify timezone is being set by Middleware.
-
- The timezone should be UTC for anonymous users,
- for authenticated users it should be set to user.userprofile.timezone
- """
- # default
- self.assertEqual(timezone.get_current_timezone_name(), 'UTC')
-
- url = reverse('account:settings')
- # anonymous request
- self.client.get(url)
- self.assertEqual(timezone.get_current_timezone_name(), 'UTC')
-
- # authenticated user with UTC timezone (userprofile default)
- self.client.login(username='user1', password='user1')
- self.client.get(url)
- self.assertEqual(timezone.get_current_timezone_name(), 'UTC')
-
- # authenticated user with custom timezone (userprofile default)
- self.user1profile.timezone = 'Etc/Greenwich'
- self.user1profile.save()
- self.client.get(url)
- self.assertEqual(timezone.get_current_timezone_name(), 'GMT')
-
- # if there is no profile for a user, it should be created
- user2 = User.objects.create(username='user2')
- user2.set_password('user2')
- user2.save()
- self.client.login(username='user2', password='user2')
- self.client.get(url)
- self.assertTrue(user2.userprofile)
diff --git a/src/account/urls.py b/src/account/urls.py
deleted file mode 100644
index 6d4ef2f..0000000
--- a/src/account/urls.py
+++ /dev/null
@@ -1,59 +0,0 @@
-##############################################################################
-# Copyright (c) 2016 Max Breitenfeldt and others.
-# Copyright (c) 2018 Parker Berberian, Sawyer Bergeron, and others.
-#
-# All rights reserved. This program and the accompanying materials
-# are made available under the terms of the Apache License, Version 2.0
-# which accompanies this distribution, and is available at
-# http://www.apache.org/licenses/LICENSE-2.0
-##############################################################################
-
-
-"""
-laas_dashboard URL Configuration.
-
-The `urlpatterns` list routes URLs to views. For more information please see:
- https://docs.djangoproject.com/en/1.10/topics/http/urls/
-Examples:
-Function views
- 1. Add an import: from my_app import views
- 2. Add a URL to urlpatterns: url(r'^$', views.home, name='home')
-Class-based views
- 1. Add an import: from other_app.views import Home
- 2. Add a URL to urlpatterns: url(r'^$', Home.as_view(), name='home')
-Including another URLconf
- 1. Import the include() function: from django.conf.urls import url, include
- 2. Add a URL to urlpatterns: url(r'^blog/', include('blog.urls'))
-"""
-from django.conf.urls import url
-from django.urls import path
-
-from account.views import (
- AccountSettingsView,
- OIDCLoginView,
- LogoutView,
- UserListView,
- account_resource_view,
- account_booking_view,
- account_images_view,
- account_detail_view,
- template_delete_view,
- booking_cancel_view,
- image_delete_view,
-)
-
-app_name = 'account'
-
-urlpatterns = [
- url(r'^settings/', AccountSettingsView.as_view(), name='settings'),
- url(r'^login/$', OIDCLoginView.as_view(), name='login'),
- url(r'^logout/$', LogoutView.as_view(), name='logout'),
- url(r'^users/$', UserListView.as_view(), name='users'),
- url(r'^my/resources/$', account_resource_view, name='my-resources'),
- path('my/resources/delete/<int:resource_id>', template_delete_view),
- url(r'^my/bookings/$', account_booking_view, name='my-bookings'),
- path('my/bookings/cancel/<int:booking_id>', booking_cancel_view),
- url(r'^my/images/$', account_images_view, name='my-images'),
- path('my/images/delete/<int:image_id>', image_delete_view),
- url(r'^my/$', account_detail_view, name='my-account'),
-]
diff --git a/src/account/views.py b/src/account/views.py
deleted file mode 100644
index 8976ff9..0000000
--- a/src/account/views.py
+++ /dev/null
@@ -1,226 +0,0 @@
-##############################################################################
-# Copyright (c) 2016 Max Breitenfeldt and others.
-# Copyright (c) 2018 Parker Berberian, Sawyer Bergeron, and others.
-#
-# All rights reserved. This program and the accompanying materials
-# are made available under the terms of the Apache License, Version 2.0
-# which accompanies this distribution, and is available at
-# http://www.apache.org/licenses/LICENSE-2.0
-##############################################################################
-
-
-import os
-
-from django.utils import timezone
-from django.contrib import messages
-from django.contrib.auth import logout
-from django.contrib.auth.decorators import login_required
-from django.contrib.auth.mixins import LoginRequiredMixin
-from django.contrib.auth.models import User
-from django.urls import reverse
-from django.http import HttpResponse
-from django.shortcuts import get_object_or_404
-from django.utils.decorators import method_decorator
-from django.views.generic import RedirectView, TemplateView, UpdateView
-from django.shortcuts import render
-from rest_framework.authtoken.models import Token
-from mozilla_django_oidc.auth import OIDCAuthenticationBackend
-
-
-from account.forms import AccountSettingsForm
-from account.models import UserProfile
-from booking.models import Booking
-from resource_inventory.models import ResourceTemplate, Image
-
-
-@method_decorator(login_required, name='dispatch')
-class AccountSettingsView(UpdateView):
- model = UserProfile
- form_class = AccountSettingsForm
- template_name_suffix = '_update_form'
-
- def get_success_url(self):
- messages.add_message(self.request, messages.INFO,
- 'Settings saved')
- return '/'
-
- def get_object(self, queryset=None):
- return self.request.user.userprofile
-
- def get_context_data(self, **kwargs):
- token, created = Token.objects.get_or_create(user=self.request.user)
- context = super(AccountSettingsView, self).get_context_data(**kwargs)
- context.update({'title': "Settings", 'token': token})
- return context
-
-
-class MyOIDCAB(OIDCAuthenticationBackend):
- def filter_users_by_claims(self, claims):
- """
- Checks to see if user exists and create user if not
-
- Linux foundation does not allow users to change their
- username, so chose to match users based on their username.
- If this changes we will need to match users based on some
- other criterea.
- """
- username = claims.get(os.environ.get('CLAIMS_ENDPOINT') + 'username')
-
- if not username:
- return HttpResponse('No username provided, contact support.')
-
- try:
- # For literally no (good) reason user needs to be a queryset
- user = User.objects.filter(username=username)
- return user
- except User.DoesNotExist:
- return self.UserModel.objects.none()
-
- def create_user(self, claims):
- """ This creates a user and user profile"""
- user = super(MyOIDCAB, self).create_user(claims)
- user.username = claims.get(os.environ['CLAIMS_ENDPOINT'] + 'username')
- user.save()
-
- up = UserProfile()
- up.user = user
- up.email_addr = claims.get('email')
- up.save()
- return user
-
- def update_user(self, user, claims):
- """ If their account has different email, change the email """
- up = UserProfile.objects.get(user=user)
- up.email_addr = claims.get('email')
- up.save()
- return user
-
-
-class OIDCLoginView(RedirectView):
- def get_redirect_url(self, *args, **kwargs):
- return reverse('oidc_authentication_init')
-
-
-class LogoutView(LoginRequiredMixin, RedirectView):
- def get_redirect_url(self, *args, **kwargs):
- logout(self.request)
- return '/'
-
-
-@method_decorator(login_required, name='dispatch')
-class UserListView(TemplateView):
- template_name = "account/user_list.html"
-
- def get_context_data(self, **kwargs):
- users = UserProfile.objects.filter(public_user=True).select_related('user')
- context = super(UserListView, self).get_context_data(**kwargs)
- context.update({'title': "Dashboard Users", 'users': users})
- return context
-
-
-def account_detail_view(request):
- template = "account/details.html"
- return render(request, template)
-
-
-def account_resource_view(request):
- """
- Display a user's resources.
-
- gathers a users genericResoureBundles and
- turns them into displayable objects
- """
- if not request.user.is_authenticated:
- return render(request, "dashboard/login.html", {'title': 'Authentication Required'})
- template = "account/resource_list.html"
-
- active_bundles = [book.resource for book in Booking.objects.filter(
- owner=request.user, end__gte=timezone.now(), resource__template__temporary=False)]
- active_resources = [bundle.template.id for bundle in active_bundles]
- resource_list = list(ResourceTemplate.objects.filter(owner=request.user, temporary=False))
-
- context = {
- "resources": resource_list,
- "active_resources": active_resources,
- "title": "My Resources"
- }
- return render(request, template, context=context)
-
-
-def account_booking_view(request):
- if not request.user.is_authenticated:
- return render(request, "dashboard/login.html", {'title': 'Authentication Required'})
- template = "account/booking_list.html"
- bookings = list(Booking.objects.filter(owner=request.user, end__gt=timezone.now()).order_by("-start"))
- my_old_bookings = Booking.objects.filter(owner=request.user, end__lt=timezone.now()).order_by("-start")
- collab_old_bookings = request.user.collaborators.filter(end__lt=timezone.now()).order_by("-start")
- expired_bookings = list(my_old_bookings.union(collab_old_bookings))
- collab_bookings = list(request.user.collaborators.filter(end__gt=timezone.now()).order_by("-start"))
- context = {
- "title": "My Bookings",
- "bookings": bookings,
- "collab_bookings": collab_bookings,
- "expired_bookings": expired_bookings
- }
- return render(request, template, context=context)
-
-
-def account_images_view(request):
- if not request.user.is_authenticated:
- return render(request, "dashboard/login.html", {'title': 'Authentication Required'})
- template = "account/image_list.html"
- my_images = Image.objects.filter(owner=request.user)
- public_images = Image.objects.filter(public=True)
- used_images = {}
- for image in my_images:
- if image.in_use():
- used_images[image.id] = "true"
- context = {
- "title": "Images",
- "images": my_images,
- "public_images": public_images,
- "used_images": used_images
- }
- return render(request, template, context=context)
-
-
-def template_delete_view(request, resource_id=None):
- if not request.user.is_authenticated:
- return HttpResponse(status=403)
- template = get_object_or_404(ResourceTemplate, pk=resource_id)
- if not request.user.id == template.owner.id:
- return HttpResponse(status=403)
- if Booking.objects.filter(resource__template=template, end__gt=timezone.now()).exists():
- return HttpResponse(status=403)
- template.public = False
- template.temporary = True
- template.save()
- return HttpResponse(status=200)
-
-
-def booking_cancel_view(request, booking_id=None):
- if not request.user.is_authenticated:
- return HttpResponse('no') # 403?
- booking = get_object_or_404(Booking, pk=booking_id)
- if not request.user.id == booking.owner.id:
- return HttpResponse('no') # 403?
-
- if booking.end < timezone.now(): # booking already over
- return HttpResponse('')
-
- booking.end = timezone.now()
- booking.save()
- return HttpResponse('')
-
-
-def image_delete_view(request, image_id=None):
- if not request.user.is_authenticated:
- return HttpResponse('no') # 403?
- image = get_object_or_404(Image, pk=image_id)
- if image.public or image.owner.id != request.user.id:
- return HttpResponse('no') # 403?
- # check if used in booking
- if image.in_use():
- return HttpResponse('no') # 403?
- image.delete()
- return HttpResponse('')