├── example ├── __init__.py ├── urls.py ├── manage.py └── settings.py ├── freeradius ├── __init__.py ├── views.py ├── admin.py └── models.py ├── .gitignore └── README.rst /example/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /freeradius/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.pyc 2 | *~ 3 | database.sqlite 4 | -------------------------------------------------------------------------------- /freeradius/views.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | -------------------------------------------------------------------------------- /example/urls.py: -------------------------------------------------------------------------------- 1 | from django.conf.urls.defaults import * 2 | 3 | # Uncomment the next two lines to enable the admin: 4 | from django.contrib import admin 5 | admin.autodiscover() 6 | 7 | urlpatterns = patterns('', 8 | # Example: 9 | # (r'^example/', include('example.foo.urls')), 10 | 11 | # Uncomment the admin/doc line below and add 'django.contrib.admindocs' 12 | # to INSTALLED_APPS to enable admin documentation: 13 | # (r'^admin/doc/', include('django.contrib.admindocs.urls')), 14 | 15 | # Uncomment the next line to enable the admin: 16 | (r'^admin/', include(admin.site.urls)), 17 | ) 18 | -------------------------------------------------------------------------------- /example/manage.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | import os, sys 3 | sys.path.insert(0, os.path.abspath('./..')) 4 | 5 | """manage.py""" 6 | from django.core.management import execute_manager 7 | try: 8 | import settings # Assumed to be in the same directory. 9 | except ImportError: 10 | import sys 11 | sys.stderr.write("Error: Can't find the file 'settings.py' in the directory containing %r. It appears you've customized things.\nYou'll have to run django-admin.py, passing it your settings module.\n(If the file settings.py does indeed exist, it's causing an ImportError somehow.)\n" % __file__) 12 | sys.exit(1) 13 | 14 | if __name__ == "__main__": 15 | execute_manager(settings) 16 | -------------------------------------------------------------------------------- /README.rst: -------------------------------------------------------------------------------- 1 | Example Project 2 | ======================== 3 | 4 | The 'example' directory contains a ready made Django project that should "just work" in the same way 5 | that any standard Django app does. 6 | 7 | Firsly, create the database and admin user:: 8 | 9 | user@machine:~/django-freeradius/example> ./manage.py syncdb 10 | Creating table auth_permission 11 | Creating table auth_group_permissions 12 | Creating table auth_group 13 | Creating table auth_user_user_permissions 14 | Creating table auth_user_groups 15 | Creating table auth_user 16 | Creating table auth_message 17 | Creating table django_content_type 18 | Creating table django_session 19 | Creating table django_site 20 | Creating table django_admin_log 21 | Creating table realmgroup 22 | Creating table realms 23 | Creating table attributelist 24 | Creating table nas 25 | Creating table radpostauth 26 | Creating table radreply 27 | Creating table radusergroup 28 | Creating table radcheck 29 | Creating table radgroupcheck 30 | Creating table radgroupreply 31 | Creating table radippool 32 | Creating table radacct 33 | 34 | You just installed Django's auth system, which means you don't have any superusers defined. 35 | Would you like to create one now? (yes/no): yes 36 | Username (Leave blank to use 'user'): 37 | E-mail address: user@domain.com 38 | Username (Leave blank to use 'root'): peter 39 | E-mail address: peter.nixon@vodafone.com 40 | Password: 41 | Password (again): 42 | Superuser created successfully. 43 | Installing index for auth.Permission model 44 | Installing index for auth.Group_permissions model 45 | Installing index for auth.User_user_permissions model 46 | Installing index for auth.User_groups model 47 | Installing index for auth.Message model 48 | Installing index for admin.LogEntry model 49 | No fixtures found. 50 | 51 | 52 | Secondly, run the development web server:: 53 | 54 | user@machine:~/django-freeradius/example> ./manage.py runserver 55 | Validating models... 56 | 0 errors found 57 | 58 | Django version 1.1.1, using settings 'example.settings' 59 | Development server is running at http://127.0.0.1:8000/ 60 | Quit the server with CONTROL-C. 61 | 62 | Thirdly, navigate to http://127.0.0.1:8000/admin/ with your favourite web browser. 63 | -------------------------------------------------------------------------------- /example/settings.py: -------------------------------------------------------------------------------- 1 | # Django settings for example project. 2 | import os 3 | 4 | DEBUG = True 5 | TEMPLATE_DEBUG = DEBUG 6 | BASE_DIR = os.path.dirname(os.path.dirname(__file__)) 7 | BASE_DIR = os.path.abspath(BASE_DIR) 8 | 9 | ADMINS = ( 10 | # ('Your Name', 'your_email@domain.com'), 11 | ) 12 | 13 | MANAGERS = ADMINS 14 | 15 | DATABASE_ENGINE = 'sqlite3' 16 | DATABASE_NAME = os.path.join(BASE_DIR, 'example', 'database.sqlite') 17 | DATABASE_USER = '' # Not used with sqlite3. 18 | DATABASE_PASSWORD = '' # Not used with sqlite3. 19 | DATABASE_HOST = '' # Set to empty string for localhost. Not used with sqlite3. 20 | DATABASE_PORT = '' # Set to empty string for default. Not used with sqlite3. 21 | 22 | # Local time zone for this installation. Choices can be found here: 23 | # http://en.wikipedia.org/wiki/List_of_tz_zones_by_name 24 | # although not all choices may be available on all operating systems. 25 | # If running in a Windows environment this must be set to the same as your 26 | # system time zone. 27 | TIME_ZONE = 'America/Maceio' 28 | 29 | # Language code for this installation. All choices can be found here: 30 | # http://www.i18nguy.com/unicode/language-identifiers.html 31 | LANGUAGE_CODE = 'pt-br' 32 | 33 | SITE_ID = 1 34 | 35 | # If you set this to False, Django will make some optimizations so as not 36 | # to load the internationalization machinery. 37 | USE_I18N = True 38 | 39 | # Absolute path to the directory that holds media. 40 | # Example: "/home/media/media.lawrence.com/" 41 | MEDIA_ROOT = '' 42 | 43 | # URL that handles the media served from MEDIA_ROOT. Make sure to use a 44 | # trailing slash if there is a path component (optional in other cases). 45 | # Examples: "http://media.lawrence.com", "http://example.com/media/" 46 | MEDIA_URL = '' 47 | 48 | # URL prefix for admin media -- CSS, JavaScript and images. Make sure to use a 49 | # trailing slash. 50 | # Examples: "http://foo.com/media/", "/media/". 51 | ADMIN_MEDIA_PREFIX = '/media/' 52 | 53 | # Make this unique, and don't share it with anybody. 54 | SECRET_KEY = '-=v_u)0r_u4*x(3aw@hh*dx6zmmqwoj+tf*9-k&99t9)b$a+d*' 55 | 56 | # List of callables that know how to import templates from various sources. 57 | TEMPLATE_LOADERS = ( 58 | 'django.template.loaders.filesystem.load_template_source', 59 | 'django.template.loaders.app_directories.load_template_source', 60 | # 'django.template.loaders.eggs.load_template_source', 61 | ) 62 | 63 | MIDDLEWARE_CLASSES = ( 64 | 'django.middleware.common.CommonMiddleware', 65 | 'django.contrib.sessions.middleware.SessionMiddleware', 66 | 'django.contrib.auth.middleware.AuthenticationMiddleware', 67 | ) 68 | 69 | ROOT_URLCONF = 'example.urls' 70 | 71 | TEMPLATE_DIRS = ( 72 | # Put strings here, like "/home/html/django_templates" or "C:/www/django/templates". 73 | # Always use forward slashes, even on Windows. 74 | # Don't forget to use absolute paths, not relative paths. 75 | ) 76 | 77 | INSTALLED_APPS = ( 78 | 'django.contrib.auth', 79 | 'django.contrib.contenttypes', 80 | 'django.contrib.sessions', 81 | 'django.contrib.sites', 82 | 'django.contrib.admin', 83 | 'freeradius', 84 | ) 85 | -------------------------------------------------------------------------------- /freeradius/admin.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | from django.contrib import admin 3 | 4 | from freeradius.models import Attributelist 5 | from freeradius.models import Nas 6 | from freeradius.models import Radpostauth 7 | from freeradius.models import Realmgroup 8 | from freeradius.models import Realms 9 | from freeradius.models import Radreply 10 | from freeradius.models import Radusergroup 11 | from freeradius.models import Radcheck 12 | from freeradius.models import Radgroupcheck 13 | from freeradius.models import Radgroupreply 14 | from freeradius.models import Radippool 15 | from freeradius.models import Radacct 16 | 17 | 18 | class AttributelistAdmin(admin.ModelAdmin): 19 | list_display = ('attribute', 'enabled', 'checkitem',) 20 | list_filter = ('enabled', 'checkitem',) 21 | ordering = ('attribute', ) 22 | search_fields = ('attribute',) 23 | 24 | class NasAdmin(admin.ModelAdmin): 25 | list_display = ('nasname', 'shortname', 'type', 'ports', 'naslocation',) 26 | list_filter = ('type', 'naslocation',) 27 | ordering = ('nasname', ) 28 | search_fields = ('nasname', 'shortname', 'ports', 'naslocation',) 29 | 30 | class RadpostauthAdmin(admin.ModelAdmin): 31 | pass 32 | 33 | class RealmgroupAdmin(admin.ModelAdmin): 34 | pass 35 | 36 | class RealmsAdmin(admin.ModelAdmin): 37 | pass 38 | 39 | class RadreplyAdmin(admin.ModelAdmin): 40 | list_display = ('calledstationid', 'custid', 'username', 'attribute', 'op', 'value',) 41 | list_filter = ('calledstationid', 'custid', 'username',) 42 | search_fields = ('attribute', 'value',) 43 | 44 | class RadusergroupAdmin(admin.ModelAdmin): 45 | list_display = ('groupname', 'username',) 46 | list_filter = ('groupname',) 47 | search_fields = ('username',) 48 | 49 | class RadcheckAdmin(admin.ModelAdmin): 50 | list_display = ('username', 'attribute', 'op', 'value',) 51 | list_filter = ('username',) 52 | search_fields = ('attribute', 'value',) 53 | 54 | class RadgroupcheckAdmin(admin.ModelAdmin): 55 | list_display = ('groupname', 'attribute', 'op', 'value',) 56 | list_filter = ('groupname',) 57 | 58 | class RadgroupreplyAdmin(admin.ModelAdmin): 59 | list_display = ('groupname', 'attribute', 'op', 'value',) 60 | list_filter = ('groupname',) 61 | 62 | class RadippoolAdmin(admin.ModelAdmin): 63 | list_display = ('pool_name', 'framedipaddress', 'nasipaddress', 'expiry_time',) 64 | list_filter = ('pool_name', 'nasipaddress', 'expiry_time',) 65 | search_fields = ('framedipaddress',) 66 | 67 | class RadacctAdmin(admin.ModelAdmin): 68 | list_display = ('acctuniqueid', 'username', 'nasipaddress', 'acctstarttime', 'acctsessiontime',) 69 | list_filter = ('nasipaddress',) 70 | 71 | 72 | admin.site.register(Attributelist,AttributelistAdmin) 73 | admin.site.register(Nas,NasAdmin) 74 | admin.site.register(Radpostauth,RadpostauthAdmin) 75 | admin.site.register(Realmgroup,RealmgroupAdmin) 76 | admin.site.register(Realms,RealmsAdmin) 77 | admin.site.register(Radreply,RadreplyAdmin) 78 | admin.site.register(Radusergroup,RadusergroupAdmin) 79 | admin.site.register(Radcheck,RadcheckAdmin) 80 | admin.site.register(Radgroupcheck,RadgroupcheckAdmin) 81 | admin.site.register(Radgroupreply,RadgroupreplyAdmin) 82 | admin.site.register(Radippool,RadippoolAdmin) 83 | admin.site.register(Radacct,RadacctAdmin) 84 | 85 | 86 | 87 | -------------------------------------------------------------------------------- /freeradius/models.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | from django.db import models 3 | 4 | RADOP_CHECK_TYPES = ( 5 | ('=', '='), 6 | (':=', ':='), 7 | ('==', '=='), 8 | ('+=', '+='), 9 | ('!=', '!='), 10 | ('>', '>'), 11 | ('>=', '>='), 12 | ('<', '<'), 13 | ('<=', '<='), 14 | ('=~', '=~'), 15 | ('!~', '!~'), 16 | ('=*', '=*'), 17 | ('!*', '!*'), 18 | ) 19 | RADOP_REPLY_TYPES = ( 20 | ('=', '='), 21 | (':=', ':='), 22 | ('+=', '+='), 23 | ) 24 | 25 | class Realmgroup(models.Model): 26 | realmname = models.CharField(max_length=30) 27 | groupname = models.CharField(max_length=30) 28 | def __str__(self): 29 | return str(self.realmname) 30 | class Meta: 31 | db_table = 'realmgroup' 32 | 33 | class Realms(models.Model): 34 | realmname = models.CharField(max_length=64) 35 | nas = models.CharField(max_length=128) 36 | authport = models.IntegerField() 37 | options = models.CharField(max_length=128) 38 | def __str__(self): 39 | return str(self.realmname) 40 | class Meta: 41 | db_table = 'realms' 42 | verbose_name_plural = "realms" 43 | 44 | class Attributelist(models.Model): 45 | attribute = models.CharField(max_length=60) 46 | enabled = models.BooleanField() 47 | checkitem = models.BooleanField() 48 | def __str__(self): 49 | return str(self.attribute) 50 | class Meta: 51 | db_table = 'attributelist' 52 | 53 | class Nas(models.Model): 54 | NAS_TYPES = ( 55 | ('cisco', 'cisco'), 56 | ('computone', 'computone'), 57 | ('livingston', 'livingston'), 58 | ('max40xx', 'max40xx'), 59 | ('multitech', 'multitech'), 60 | ('netserver', 'netserver'), 61 | ('pathras', 'pathras'), 62 | ('patton', 'patton'), 63 | ('portslave', 'portslave'), 64 | ('tc', 'tc'), 65 | ('usrhiper', 'usrhiper'), 66 | ('other', 'other'), 67 | ) 68 | vhost = models.CharField(max_length=128, unique=True, help_text='NAS Name (or IP address)') 69 | nasname = models.CharField(max_length=128, unique=True, help_text='NAS Name (or IP address)') 70 | shortname = models.CharField(max_length=32) 71 | type = models.CharField(max_length=30, choices=NAS_TYPES) 72 | secret = models.CharField(max_length=60, help_text='Shared Secret') 73 | coasecret = models.CharField(max_length=60, help_text='CoA Secret', blank=True, null=True) 74 | ports = models.IntegerField(blank=True, null=True) 75 | naslocation = models.CharField(max_length=32, blank=True, null=True) 76 | community = models.CharField(max_length=50, blank=True, null=True) 77 | snmp = models.CharField(max_length=10, blank=True, null=True) 78 | def __str__(self): 79 | return str(self.nasname) 80 | class Meta: 81 | db_table = 'nas' 82 | verbose_name_plural = "nas" 83 | 84 | class Radpostauth(models.Model): 85 | username = models.CharField(max_length=64) 86 | password = models.CharField(db_column='pass', max_length=64) # Field renamed because it was a Python reserved word. 87 | reply = models.CharField(max_length=32) 88 | authdate = models.DateTimeField() 89 | calledstationid = models.CharField(max_length=64) 90 | callingstationid = models.CharField(max_length=50) 91 | def __str__(self): 92 | return str(self.username) 93 | class Meta: 94 | db_table = 'radpostauth' 95 | verbose_name_plural = "radpostauth" 96 | 97 | class Radreply(models.Model): 98 | username = models.CharField(max_length=30) 99 | attribute = models.CharField(max_length=30) 100 | op = models.CharField(max_length=2, choices=RADOP_REPLY_TYPES) 101 | value = models.CharField(max_length=40) 102 | calledstationid = models.CharField(max_length=64) 103 | custid = models.IntegerField() 104 | def __str__(self): 105 | return str(self.username) 106 | class Meta: 107 | db_table = 'radreply' 108 | verbose_name_plural = "radreply" 109 | 110 | class Radusergroup(models.Model): 111 | username = models.CharField(max_length=30) 112 | groupname = models.CharField(max_length=30) 113 | calledstationid = models.CharField(max_length=64) 114 | def __str__(self): 115 | return str(self.username) 116 | class Meta: 117 | db_table = 'radusergroup' 118 | 119 | class Radcheck(models.Model): 120 | username = models.CharField(max_length=64) 121 | attribute = models.CharField(max_length=64) 122 | op = models.CharField(max_length=2, choices=RADOP_CHECK_TYPES) 123 | value = models.CharField(max_length=253) 124 | def __str__(self): 125 | return str(self.username) 126 | class Meta: 127 | db_table = 'radcheck' 128 | verbose_name_plural = "radcheck" 129 | 130 | class Radgroupcheck(models.Model): 131 | groupname = models.CharField(max_length=64) 132 | attribute = models.CharField(max_length=64) 133 | op = models.CharField(max_length=2, choices=RADOP_CHECK_TYPES) 134 | value = models.CharField(max_length=253) 135 | class Meta: 136 | db_table = 'radgroupcheck' 137 | verbose_name_plural = "radgroupcheck" 138 | 139 | class Radgroupreply(models.Model): 140 | groupname = models.CharField(max_length=64) 141 | attribute = models.CharField(max_length=64) 142 | op = models.CharField(max_length=2, choices=RADOP_REPLY_TYPES) 143 | value = models.CharField(max_length=253) 144 | def __str__(self): 145 | return str(self.groupname) 146 | class Meta: 147 | db_table = 'radgroupreply' 148 | verbose_name_plural = "radgroupreply" 149 | 150 | class Radippool(models.Model): 151 | pool_name = models.CharField(max_length=64,help_text='The IP Pool name') 152 | framedipaddress = models.IPAddressField(help_text='The users IP address') 153 | nasipaddress = models.CharField(max_length=16) 154 | callingstationid = models.TextField('Calling-Station-Id', help_text='The MAC Address or CLI of the user') 155 | expiry_time = models.DateTimeField(help_text='The IP Lease expiry time') 156 | username = models.CharField(max_length=64) 157 | groupname = models.CharField(max_length=30) 158 | pool_key = models.CharField(max_length=30) 159 | fixed = models.BooleanField() 160 | def __str__(self): 161 | return str(self.framedipaddress) 162 | class Meta: 163 | db_table = 'radippool' 164 | verbose_name_plural = "radippool" 165 | 166 | class Radacct(models.Model): 167 | radacctid = models.AutoField(primary_key=True) 168 | acctsessionid = models.CharField(max_length=32) 169 | acctuniqueid = models.CharField(max_length=32) 170 | username = models.CharField(max_length=253, null=True) 171 | realm = models.CharField(max_length=64, null=True) 172 | nasipaddress = models.IPAddressField() 173 | nasportid = models.CharField(max_length=15, null=True) 174 | nasporttype = models.CharField(max_length=32, null=True) 175 | acctstarttime = models.DateTimeField(null=True) 176 | acctstoptime = models.DateTimeField(null=True) 177 | acctsessiontime = models.BigIntegerField(null=True) 178 | acctauthentic = models.CharField(max_length=32, null=True) 179 | acctinputoctets = models.BigIntegerField(null=True) 180 | acctoutputoctets = models.BigIntegerField(null=True) 181 | calledstationid = models.CharField(max_length=50, null=True) 182 | callingstationid = models.CharField(max_length=50, null=True) 183 | framedipaddress = models.IPAddressField(null=True) 184 | connectinfo_start = models.CharField(max_length=50, null=True) 185 | connectinfo_stop = models.CharField(max_length=50, null=True) 186 | acctterminatecause = models.CharField(max_length=32, null=True) 187 | servicetype = models.CharField(max_length=32, null=True) 188 | framedprotocol = models.CharField(max_length=32, null=True) 189 | acctstartdelay = models.IntegerField(null=True) 190 | acctstopdelay = models.IntegerField(null=True) 191 | xascendsessionsvrkey = models.CharField(max_length=10, null=True) 192 | def __str__(self): 193 | return str(self.acctuniqueid) 194 | class Meta: 195 | db_table = 'radacct' 196 | verbose_name_plural = "radacct" 197 | --------------------------------------------------------------------------------