Skip to content

Commit

Permalink
Config management
Browse files Browse the repository at this point in the history
  • Loading branch information
the-glu committed Jan 5, 2014
1 parent 1aaecab commit 48895a5
Show file tree
Hide file tree
Showing 78 changed files with 6,825 additions and 22 deletions.
1 change: 1 addition & 0 deletions app/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,7 @@

'main',
'users',
'configs',
)

SESSION_SERIALIZER = 'django.contrib.sessions.serializers.JSONSerializer'
Expand Down
1 change: 1 addition & 0 deletions app/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@

url(r'', include('main.urls')),
url(r'^users/', include('users.urls')),
url(r'^configs/', include('configs.urls')),

(r'^' + settings.MEDIA_URL[1:] + '(?P<path>.*)$', 'django.views.static.serve', {'document_root': settings.MEDIA_ROOT}), # In prod, use apache !
(r'^' + settings.STATIC_URL[1:] + '(?P<path>.*)$', 'django.views.static.serve', {'document_root': settings.STATIC_ROOT}), # In prod, use apache !
Expand Down
Empty file added configs/__init__.py
Empty file.
18 changes: 18 additions & 0 deletions configs/forms.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
from django.forms import ModelForm

from configs.models import Config


class ConfigForm(ModelForm):
class Meta:
model = Config
exclude = ('key_request', 'key_ipn', 'key_api')

def __init__(self, user, *args, **kwargs):
super(ConfigForm, self).__init__(*args, **kwargs)

if not user.is_superuser:
del self.fields['admin_enable']

if kwargs['instance'].pk:
del self.fields['test_mode']
95 changes: 95 additions & 0 deletions configs/migrations/0001_initial.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
# -*- coding: utf-8 -*-
import datetime
from south.db import db
from south.v2 import SchemaMigration
from django.db import models


class Migration(SchemaMigration):

def forwards(self, orm):
# Adding model 'Config'
db.create_table(u'configs_config', (
(u'id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
('name', self.gf('django.db.models.fields.CharField')(max_length=255)),
('active', self.gf('django.db.models.fields.BooleanField')(default=True)),
('admin_enable', self.gf('django.db.models.fields.BooleanField')(default=True)),
('test_mode', self.gf('django.db.models.fields.BooleanField')(default=True)),
('url_ipn', self.gf('django.db.models.fields.URLField')(max_length=200)),
('key_request', self.gf('django.db.models.fields.CharField')(max_length=255)),
('key_ipn', self.gf('django.db.models.fields.CharField')(max_length=255)),
('key_api', self.gf('django.db.models.fields.CharField')(max_length=255)),
))
db.send_create_signal(u'configs', ['Config'])

# Adding M2M table for field allowed_users on 'Config'
m2m_table_name = db.shorten_name(u'configs_config_allowed_users')
db.create_table(m2m_table_name, (
('id', models.AutoField(verbose_name='ID', primary_key=True, auto_created=True)),
('config', models.ForeignKey(orm[u'configs.config'], null=False)),
('user', models.ForeignKey(orm[u'auth.user'], null=False))
))
db.create_unique(m2m_table_name, ['config_id', 'user_id'])


def backwards(self, orm):
# Deleting model 'Config'
db.delete_table(u'configs_config')

# Removing M2M table for field allowed_users on 'Config'
db.delete_table(db.shorten_name(u'configs_config_allowed_users'))


models = {
u'auth.group': {
'Meta': {'object_name': 'Group'},
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}),
'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
},
u'auth.permission': {
'Meta': {'ordering': "(u'content_type__app_label', u'content_type__model', u'codename')", 'unique_together': "((u'content_type', u'codename'),)", 'object_name': 'Permission'},
'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['contenttypes.ContentType']"}),
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
},
u'auth.user': {
'Meta': {'object_name': 'User'},
'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}),
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}),
'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
},
u'configs.config': {
'Meta': {'object_name': 'Config'},
'active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
'admin_enable': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
'allowed_users': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['auth.User']", 'symmetrical': 'False'}),
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'key_api': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'key_ipn': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'key_request': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'test_mode': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
'url_ipn': ('django.db.models.fields.URLField', [], {'max_length': '200'})
},
u'contenttypes.contenttype': {
'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
}
}

complete_apps = ['configs']
87 changes: 87 additions & 0 deletions configs/migrations/0002_auto__add_configlogs.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
# -*- coding: utf-8 -*-
import datetime
from south.db import db
from south.v2 import SchemaMigration
from django.db import models


class Migration(SchemaMigration):

def forwards(self, orm):
# Adding model 'ConfigLogs'
db.create_table(u'configs_configlogs', (
(u'id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
('config', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['configs.Config'])),
('user', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['auth.User'])),
('when', self.gf('django.db.models.fields.DateTimeField')(auto_now_add=True, blank=True)),
('text', self.gf('django.db.models.fields.TextField')()),
))
db.send_create_signal(u'configs', ['ConfigLogs'])


def backwards(self, orm):
# Deleting model 'ConfigLogs'
db.delete_table(u'configs_configlogs')


models = {
u'auth.group': {
'Meta': {'object_name': 'Group'},
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}),
'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
},
u'auth.permission': {
'Meta': {'ordering': "(u'content_type__app_label', u'content_type__model', u'codename')", 'unique_together': "((u'content_type', u'codename'),)", 'object_name': 'Permission'},
'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['contenttypes.ContentType']"}),
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
},
u'auth.user': {
'Meta': {'object_name': 'User'},
'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}),
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}),
'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
},
u'configs.config': {
'Meta': {'object_name': 'Config'},
'active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
'admin_enable': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
'allowed_users': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['auth.User']", 'symmetrical': 'False', 'blank': 'True'}),
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'key_api': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'key_ipn': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'key_request': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'test_mode': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
'url_ipn': ('django.db.models.fields.URLField', [], {'max_length': '200'})
},
u'configs.configlogs': {
'Meta': {'object_name': 'ConfigLogs'},
'config': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['configs.Config']"}),
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'text': ('django.db.models.fields.TextField', [], {}),
'user': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['auth.User']"}),
'when': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'})
},
u'contenttypes.contenttype': {
'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
}
}

complete_apps = ['configs']
Empty file added configs/migrations/__init__.py
Empty file.
119 changes: 119 additions & 0 deletions configs/models.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
from django.db import models
from django.contrib.auth.models import User

import uuid
import datetime
import random
import hashlib


class Config(models.Model):
"""Represent a website configuration"""

name = models.CharField(max_length=255)

active = models.BooleanField(default=True)
admin_enable = models.BooleanField(default=True)

test_mode = models.BooleanField(default=True)

url_ipn = models.URLField()

key_request = models.CharField(max_length=255)
key_ipn = models.CharField(max_length=255)
key_api = models.CharField(max_length=255)

allowed_users = models.ManyToManyField(User, blank=True)

def __unicode__(self):
bonus = ''

if self.test_mode:
bonus += '<i class="fa fa-flask"></i>'

if not self.active or not self.admin_enable:
bonus += '<i class="glyphicon glyphicon-ban-circle"></i>'

if bonus:
bonus = ' (' + bonus + ')'

return self.name + bonus

def build_user_list(self):
"""Return a list of user in text format"""
return ','.join([x.username for x in self.allowed_users.order_by('username').all()])

def generate_diff(self, object):
"""Generate diff from this objet an another one (for logs)"""
retour = '\n\n'

for (prop, prop_name) in (('name', 'Name'), ('active', 'Active'), ('admin_enable', 'Admin enable'), ('test_mode', 'Test mode'), ('url_ipn', 'URL Ipn')):
if not object.pk or getattr(self, prop) != getattr(object, prop):
retour += prop_name + '=' + str(getattr(self, prop))

if object.pk:
retour += ' (was ' + str(getattr(object, prop)) + ')'

retour += '\n'

retour += 'User list: ' + self.build_user_list()
return retour

def is_user_allowed(self, user):
"""Return true is a user is allowed to display / edit the config"""

if user.is_superuser:
return True

if not self.pk:
return user.is_staff # Only staff can create configs

return user in self.allowed_users

def gen_key(self):
"""Return a random key suitable for keys of the model"""

h = hashlib.sha512()

for i in range(0, 2):
h.update(str(uuid.uuid4()))
h.update(str(datetime.datetime.now()))
h.update(str(random.random()))
h.update(str(self.pk))
h.update(self.name)

return h.hexdigest()

def gen_key_api(self):
"""Generate a new key for api"""
self.key_api = self.gen_key()

def gen_key_ipn(self):
"""Generate a new key for ipn"""
self.key_ipn = self.gen_key()

def gen_key_request(self):
"""Generate a new key for requests"""
self.key_request = self.gen_key()

def save(self, *args, **kwargs):
"""Overide the save request to check if all keys have been generated"""

if not self.key_api:
self.gen_key_api()

if not self.key_ipn:
self.gen_key_ipn()

if not self.key_request:
self.gen_key_request()

super(Config, self).save(*args, **kwargs)


class ConfigLogs(models.Model):

config = models.ForeignKey(Config)
user = models.ForeignKey(User)
when = models.DateTimeField(auto_now_add=True)
text = models.TextField()
53 changes: 53 additions & 0 deletions configs/templates/configs/configs/edit.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
{% extends "base.html" %}
{% load i18n %}
{% load bootstrap3 %}

{% block title %}{{block.super}} :: {% trans "Config management" %} :: {% trans "Edition" %}{% endblock %}

{% block content %}

<script type="text/javascript">$('#nav-configs').addClass('active');</script>

<h2>{% trans "Config management" %}</h2>

<ol class="breadcrumb">
<li><a href="{% url 'main.views.home' %}"><i class="fa fa-home"></i> {% trans "Home" %}</a></li>
<li><a href="{% url 'configs.views.list' %}"><i class="fa fa-cogs"></i> {% trans "Configs" %}</a></li>
{% if form.instance.pk %}
<li><a href="{% url 'configs.views.show' form.instance.pk %}"><i class="fa fa-cog"></i> {{form.instance|safe}}</a></li>
{% endif %}
<li class="active"><i class="fa fa-pencil"></i> {% if form.instance.pk %}{% trans "Edition" %}{% else %}{% trans "New config" %}{% endif %}</li>

</ol>

<div class="row-fluid">
<div class="panel panel-primary">
<div class="panel-heading">
<h3 class="panel-title">{% trans "Edition of a config" %}</h3>
</div>
<div class="panel-body">

<form action="" method="POST">
{% csrf_token %}

{% bootstrap_form form %}

<div class="row-fluid box-section" style="text-align: right;">
<a href="{% url 'configs.views.list' %}" class="btn btn-default"><i class="glyphicon glyphicon-list"></i> {% trans "Back to the list" %}</a>
<input type="submit" class="btn btn-primary" value="{% trans "Save" %}">
</div>

</form>


</div>
</div>

</div>

<script type="text/javascript">
$('#id_allowed_users').select2();
</script>


{% endblock %}
Loading

0 comments on commit 48895a5

Please sign in to comment.