Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
Menu
Open sidebar
David Seaward
Keel - LDH Middleware
Commits
828b3379
Commit
828b3379
authored
Dec 14, 2017
by
David Seaward
Browse files
Merge branch 'master' of code.puri.sm:purist/middleware into jwt_authentication
parents
c511aedf
644b07ef
Changes
17
Hide whitespace changes
Inline
Side-by-side
README.md
View file @
828b3379
...
...
@@ -32,6 +32,13 @@ Usage
another way.
*
Manage user profile at
<https://example.com/accounts/profile/>
Models
------

(Generated with
`./manage.py graph_models --all-applications --group-models --verbose-name --output models.png`
)
Sharing and contributions
-------------------------
...
...
ldapregister/tests.py
deleted
100755 → 0
View file @
c511aedf
from
django.test
import
TestCase
# Create your tests here.
limitmonitor/migrations/0003_auto_20171208_1327.py
0 → 100644
View file @
828b3379
# -*- coding: utf-8 -*-
# Generated by Django 1.11.6 on 2017-12-08 13:27
from
__future__
import
unicode_literals
import
choicesenum.django.fields
from
django.db
import
migrations
import
limitmonitor.models
class
Migration
(
migrations
.
Migration
):
dependencies
=
[
(
'limitmonitor'
,
'0002_auto_20171009_2334'
),
]
operations
=
[
migrations
.
AlterField
(
model_name
=
'externalbundle'
,
name
=
'parser'
,
field
=
choicesenum
.
django
.
fields
.
EnumIntegerField
(
default
=
limitmonitor
.
models
.
ExternalParser
(
0
),
enum
=
limitmonitor
.
models
.
ExternalParser
),
),
migrations
.
AlterField
(
model_name
=
'externalbundle'
,
name
=
'service'
,
field
=
choicesenum
.
django
.
fields
.
EnumIntegerField
(
default
=
limitmonitor
.
models
.
Service
(
0
),
enum
=
limitmonitor
.
models
.
Service
),
),
migrations
.
AlterField
(
model_name
=
'externalcredit'
,
name
=
'parser'
,
field
=
choicesenum
.
django
.
fields
.
EnumIntegerField
(
default
=
limitmonitor
.
models
.
ExternalParser
(
0
),
enum
=
limitmonitor
.
models
.
ExternalParser
),
),
migrations
.
AlterField
(
model_name
=
'limit'
,
name
=
'service'
,
field
=
choicesenum
.
django
.
fields
.
EnumIntegerField
(
default
=
limitmonitor
.
models
.
Service
(
0
),
enum
=
limitmonitor
.
models
.
Service
),
),
]
limitmonitor/models.py
View file @
828b3379
from
choicesenum
import
ChoicesEnum
from
choicesenum.django.fields
import
EnumIntegerField
from
django.conf
import
settings
from
django.db
import
models
from
django.utils
import
timezone
EXTERNAL_PARSER_CHOICES
=
(
(
"WOO1"
,
"WooCommerce v1"
),
(
"WOOSUB1"
,
"WooCommerce Subscription v1"
),
)
SERVICE_CHOICES
=
(
(
"TUNNEL"
,
"Tunnel"
),
(
"COMMUNICATION"
,
"Communication"
),
)
class
ExternalParser
(
ChoicesEnum
):
UNDEFINED
=
0
,
"Undefined"
WOO1
=
1
,
"WooCommerce v1"
WOOSUB1
=
2
,
"WooCommerce Subscription v1"
class
Service
(
ChoicesEnum
):
UNDEFINED
=
0
,
"Undefined"
TUNNEL
=
1
,
"Tunnel"
COMMUNICATION
=
2
,
"Communication"
def
create_missing_user_limits
(
user
):
for
code
,
label
in
SERVICE_CHOICES
:
if
not
Limit
.
objects
.
filter
(
user
=
user
,
service
=
code
).
exists
():
for
code
,
label
in
Service
.
choices
():
is_undefined
=
code
==
Service
.
UNDEFINED
.
value
is_exists
=
Limit
.
objects
.
filter
(
user
=
user
,
service
=
code
).
exists
()
if
not
is_undefined
and
not
is_exists
:
Limit
(
user
=
user
,
service
=
code
).
save
()
class
Limit
(
models
.
Model
):
user
=
models
.
ForeignKey
(
settings
.
AUTH_USER_MODEL
)
service
=
models
.
CharField
(
max_length
=
30
,
choices
=
SERVICE_CHOICES
)
service
=
EnumIntegerField
(
enum
=
Service
,
default
=
Service
.
UNDEFINED
)
renewal_date
=
models
.
DateTimeField
(
default
=
None
,
blank
=
True
,
null
=
True
)
expiry_date
=
models
.
DateTimeField
(
default
=
None
,
blank
=
True
,
null
=
True
)
volume_total
=
models
.
DecimalField
(
default
=
0
,
decimal_places
=
2
,
max_digits
=
6
)
...
...
@@ -33,7 +39,7 @@ class Limit(models.Model):
def
service_label
(
self
):
label
=
"None"
for
key
,
value
in
S
ERVICE_CHOICES
:
for
key
,
value
in
S
ervice
.
choices
()
:
if
self
.
service
==
key
:
label
=
value
...
...
@@ -71,7 +77,7 @@ class Limit(models.Model):
def
credit_label
(
self
):
if
self
.
service
==
"
TUNNEL
"
:
if
self
.
service
==
Service
.
TUNNEL
:
return
self
.
days_credit_label
()
else
:
return
self
.
days_credit_label
()
...
...
@@ -80,7 +86,13 @@ class Limit(models.Model):
single_day
=
60
*
60
*
24
days
=
int
(
round
(
delta
.
total_seconds
()
/
single_day
))
return
str
(
days
)
+
" days"
if
days
<=
62
:
return
str
(
days
)
+
" days"
elif
days
<=
744
:
return
str
(
days
//
30
)
+
" months"
else
:
return
str
(
days
//
365
)
+
" years"
def
days_credit_label
(
self
):
...
...
@@ -106,9 +118,9 @@ class Limit(models.Model):
class
ExternalBundle
(
models
.
Model
):
parser
=
models
.
CharField
(
max_length
=
30
,
choices
=
EXTERNAL_PARSER_CHOICES
)
parser
=
EnumIntegerField
(
enum
=
ExternalParser
,
default
=
ExternalParser
.
UNDEFINED
)
external_key
=
models
.
CharField
(
max_length
=
30
)
service
=
models
.
CharField
(
max_length
=
30
,
choices
=
SERVICE_CHOICES
)
service
=
EnumIntegerField
(
enum
=
Service
,
default
=
Service
.
UNDEFINED
)
time_credit
=
models
.
DecimalField
(
default
=
0
,
decimal_places
=
2
,
max_digits
=
6
)
volume_credit
=
models
.
DecimalField
(
default
=
0
,
decimal_places
=
2
,
max_digits
=
6
)
created_date
=
models
.
DateTimeField
(
default
=
timezone
.
now
)
...
...
@@ -116,7 +128,7 @@ class ExternalBundle(models.Model):
class
ExternalCredit
(
models
.
Model
):
parser
=
models
.
CharField
(
max_length
=
30
,
choices
=
EXTERNAL_PARSER_CHOICES
)
parser
=
EnumIntegerField
(
enum
=
ExternalParser
,
default
=
ExternalParser
.
UNDEFINED
)
external_key
=
models
.
CharField
(
max_length
=
30
)
label
=
models
.
CharField
(
max_length
=
30
)
bundle_key
=
models
.
CharField
(
max_length
=
30
)
...
...
limitmonitor/task_resources/common.py
View file @
828b3379
import
pathlib
import
django.contrib.auth
import
paramiko
from
celery.utils.log
import
get_task_logger
...
...
@@ -6,7 +8,7 @@ from django.db import transaction
from
django.utils
import
timezone
from
woocommerce
import
API
as
WOO_API
from
..models
import
ExternalCredit
,
ExternalBundle
,
Limit
from
..models
import
ExternalCredit
,
ExternalBundle
,
Limit
,
Service
logger
=
get_task_logger
(
__name__
)
...
...
@@ -99,8 +101,14 @@ def activate(ssh, limit, credit_timedelta=None, renewal_date=None):
# otherwise, activate the limit before saving
if
limit
.
service
==
"TUNNEL"
:
managed_exec
(
ssh
,
"./create_new_ovpn_config --generate %s"
%
(
limit
.
user
.
get_identity
(),))
if
limit
.
service
==
Service
.
TUNNEL
:
user_identity
=
limit
.
user
.
get_identity
()
filepath
=
settings
.
OVPN_FILEPATH
.
replace
(
"{USER_IDENTITY}"
,
user_identity
)
is_file
=
pathlib
.
Path
(
filepath
).
is_file
()
# only create certificate if it doesn't exist
if
not
is_file
:
managed_exec
(
ssh
,
"./create_new_ovpn_config --generate %s"
%
(
user_identity
,))
else
:
# skip unsupported limits
limit
.
is_active
=
False
...
...
@@ -109,7 +117,7 @@ def activate(ssh, limit, credit_timedelta=None, renewal_date=None):
def
deactivate
(
ssh
,
limit
):
if
limit
.
service
==
"
TUNNEL
"
:
if
limit
.
service
==
Service
.
TUNNEL
:
managed_exec
(
ssh
,
"./create_new_ovpn_config --revoke %s"
%
(
limit
.
user
.
get_identity
(),))
limit
.
is_active
=
False
...
...
limitmonitor/tasks.py
View file @
828b3379
...
...
@@ -28,10 +28,3 @@ def deactivate_all_expired_limits():
@
shared_task
def
debug_connection_task
():
common
.
debug_connection_task
()
@
shared_task
def
monitor_woo1
():
# keep legacy task header so that it is flushed out of queue
# FIXME: this will be removed in the next release
pass
limitmonitor/tests.py
deleted
100644 → 0
View file @
c511aedf
# Create your tests here.
middleware/settings.py
View file @
828b3379
...
...
@@ -39,7 +39,8 @@ ALLOWED_HOSTS = config("ALLOWED_HOSTS", cast=Csv())
# INSTALLED APPLICATIONS
#
INSTALLED_APPS
+=
[
"crispy_forms"
,
"django_agpl"
,
"django_celery_beat"
,
"ldapregister"
,
"limitmonitor"
,
"purist"
]
INSTALLED_APPS
+=
[
"crispy_forms"
,
"django_agpl"
,
"django_celery_beat"
,
"django_extensions"
,
"ldapregister"
,
"limitmonitor"
,
"purist"
]
#
# AGPL APPLICATION
...
...
models.png
0 → 100644
View file @
828b3379
279 KB
purist/migrations/0002_auto_20171208_1327.py
0 → 100644
View file @
828b3379
# -*- coding: utf-8 -*-
# Generated by Django 1.11.6 on 2017-12-08 13:27
from
__future__
import
unicode_literals
from
django.db
import
migrations
,
models
import
purist.custom
class
Migration
(
migrations
.
Migration
):
dependencies
=
[
(
'purist'
,
'0001_initial'
),
]
operations
=
[
migrations
.
AlterField
(
model_name
=
'user'
,
name
=
'username'
,
field
=
models
.
CharField
(
error_messages
=
{
'unique'
:
'A user with that username already exists.'
},
help_text
=
'Required. Start with a letter, followed by letters and numbers.'
,
max_length
=
150
,
unique
=
True
,
validators
=
[
purist
.
custom
.
UsernameValidator
()],
verbose_name
=
'username'
),
),
]
purist/models.py
View file @
828b3379
...
...
@@ -55,9 +55,6 @@ class User(AbstractUser):
},
)
def
__init__
(
self
,
*
args
,
**
kwargs
):
super
(
User
,
self
).
__init__
(
*
args
,
**
kwargs
)
@
classmethod
def
normalize_username
(
cls
,
username
):
username
=
super
(
User
,
cls
).
normalize_username
(
username
)
...
...
@@ -71,10 +68,6 @@ class User(AbstractUser):
return
username
def
validate_unique
(
self
,
exclude
=
None
):
return
super
(
User
,
self
).
validate_unique
(
exclude
)
def
get_ldap
(
self
):
return
LdapPerson
.
objects
.
get
(
uid
=
self
.
get_username
())
...
...
purist/tests.py
deleted
100644 → 0
View file @
c511aedf
from
django.test
import
TestCase
# Create your tests here.
requirements.txt
0 → 100644
View file @
828b3379
# Requirements for a development instance
-r requires/production.txt # functional requirements and dependencies
-r requires/documentation.txt # documentation requirements
requires/dependencies.txt
View file @
828b3379
# Dependencies of the core packages in production.txt
amqp==2.2.2
asn1crypto==0.23.0
bcrypt==3.1.4
...
...
requires/development.txt
deleted
100755 → 0
View file @
c511aedf
-r documentation.txt
requires/documentation.txt
View file @
828b3379
-r r
equirements
.txt
# R
equirements
for documentation building
alabaster==0.7.10
Babel==2.5.1
certifi==2017.7.27.1
...
...
requires/
requirements
.txt
→
requires/
production
.txt
100755 → 100644
View file @
828b3379
-r dependencies.txt
# Top-level requirements for a production instance
-r dependencies.txt # dependencies of these core packages
celery==4.1.0
choicesenum==0.2.2
confusable_homoglyphs==2.0.2
dj-database-url==0.4.2
Django==1.11.7
...
...
@@ -7,6 +9,7 @@ django-agpl==4.0.0
django-auth-ldap==1.2.16
django-celery-beat==1.0.1
django-crispy-forms==1.6.1
django-extensions==1.9.8
django-ldapdb==0.9.0
django-registration==2.3
Jinja2==2.9.6
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment