lots of stuff to get authentication up
diff --git a/AppMgr/admin.py b/AppMgr/admin.py
index 8c38f3f..4917232 100644
--- a/AppMgr/admin.py
+++ b/AppMgr/admin.py
@@ -1,3 +1,37 @@
 from django.contrib import admin
 
+from django.contrib.contenttypes.admin import GenericTabularInline
+
+from custom_user.models import EmailUser 
+from custom_user.admin import EmailUserAdmin as BaseUserAdmin
+
+from AppMgr.models import UserProfile, Organization, Application, AppVersion
+
 # Register your models here.
+
+class UserProfileInline(admin.StackedInline):
+    model = UserProfile
+
+class UserAdmin(BaseUserAdmin):
+    inlines = (UserProfileInline, )
+
+class OrganizationAdmin(admin.ModelAdmin):
+    search_fields = ['name']
+    list_display = ['name']
+
+class ApplicationInline(GenericTabularInline):
+    model = Application
+    ct_field = 'content_type'
+    ct_fk_field = 'object_id'
+
+class ApplicationAdmin(admin.ModelAdmin):
+    inlines = [ApplicationInline]
+    search_fields = ['name']
+    list_display = ['name']
+
+admin.site.unregister(EmailUser)
+admin.site.register(EmailUser, UserAdmin)
+
+admin.site.register(Organization, OrganizationAdmin)
+
+admin.site.register(Application, ApplicationAdmin)
diff --git a/AppMgr/models.py b/AppMgr/models.py
index 218b378..b44e9c5 100644
--- a/AppMgr/models.py
+++ b/AppMgr/models.py
@@ -1,23 +1,70 @@
 from django.db import models
 from django.conf import settings
+from django.contrib.postgres.fields import JSONField
+
+from django.contrib.contenttypes.models import ContentType
+from django.contrib.contenttypes.fields import GenericForeignKey
 
 # Create your models here.
 class UserProfile(models.Model):
     user = models.OneToOneField(settings.AUTH_USER_MODEL)
 
-    # additional user parameters
-
     def __unicode__(self):
         return self.user.email
 
 class Organization(models.Model):
     name = models.CharField(max_length=255)
 
+    members = models.ManyToManyField(UserProfile)
+
+    class Meta:
+        permissions = (
+            ("admin", "All organizational privileges"),
+            ("change_apps", "Create/Modify/Delete Org's Applications"),
+            ("change_members", "Add/Remove Users"),
+        )
+
     def __unicode__(self):
         return self.name
 
 class Application(models.Model):
     name = models.CharField(max_length=255)
 
+    isPublic = models.BooleanField(default=True)
+
+    #Application owner can be either a UserProfile or an Organization    
+    limit = models.Q(app_label='AppMgr', model='UserProfile') | \
+            models.Q(app_label='AppMgr', model='Organization') 
+    content_type = models.ForeignKey(
+            ContentType,
+            verbose_name='application owner',
+            limit_choices_to=limit,
+            null=True,
+            blank=True,
+    )
+    object_id = models.PositiveIntegerField(
+            verbose_name='app owner id',
+            null=True,
+    )
+    content_object = GenericForeignKey('content_type', 'object_id')
+
+    class Meta:
+        permissions = (
+            ("admin", "All application privileges"),
+            ("edit", "add/modify application attributes"),
+            ("view", "read access to the application"),
+        )
+
+    def __unicode__(self):
+        return self.name
+
+class AppVersion(models.Model):
+    name = models.CharField(max_length=255)
+
+    app = models.ForeignKey(Application, null=True, blank=False)
+
+    aliases = JSONField()
+    domain = models.URLField(max_length=255)
+
     def __unicode__(self):
         return self.name
diff --git a/AppMgr/views.py b/AppMgr/views.py
index 91ea44a..29e3bc4 100644
--- a/AppMgr/views.py
+++ b/AppMgr/views.py
@@ -1,3 +1,147 @@
-from django.shortcuts import render
+from django.shortcuts import render, redirect, render_to_response
+from django.http import HttpResponseRedirect, HttpResponse
+from django.contrib.auth.decorators import login_required
+from django.contrib.auth import authenticate, login, logout, get_user_model
+from django.contrib.auth.views import password_reset, password_reset_confirm
+from django.contrib.sites.shortcuts import get_current_site
+from django.core.urlresolvers import reverse
+from django.template import RequestContext
+from django.conf import settings
 
+from django.db import IntegrityError
+
+from axes.decorators import watch_login
+
+from AppMgr.models import UserProfile, Organization, Application, AppVersion
 # Create your views here.
+
+# creates a new user 
+def register(request):
+    # TODO : add logging back in.  Good practice!!
+    # Like before, get the request's context.
+    context = RequestContext(request)
+
+    # A boolean value for telling the template whether the registration was successful.
+    # Set to False initially. Code changes value to True when registration succeeds.
+    registrationSuccessful = False
+    userExists = False
+    error = False
+
+    # If it's a HTTP POST, we're interested in processing form data.
+    if request.method == 'POST':
+
+        # Now we hash the password with the set_password method.
+        # Once hashed, we can update the user object.
+        user = get_user_model()(email=request.POST['email'])
+        user.set_password(request.POST['password'])
+        user.last_login = '1970-01-01 00:00'
+
+        if not user.email or not request.POST['password']:
+            error = True
+            return render_to_response('registration/register.html', {'registrationSuccessful': registrationSuccessful, 'userExists': userExists, 'error': error}, context)
+
+        try:
+            user.save()
+        except IntegrityError:
+            userExists = True
+            return render_to_response('registration/register.html', {'registrationSuccessful': registrationSuccessful, 'userExists': userExists, 'error': error}, context)
+
+        # Now sort out the UserProfile instance.
+        # Since we need to set the user attribute ourselves, we set commit=False.
+        # This delays saving the model until we're ready to avoid integrity problems.
+        userprofile = UserProfile()
+        userprofile.user = user
+
+        # Now we save the UserProfile model instance.
+        userprofile.save()
+
+        # Update our variable to tell the template registration was successful.
+        registrationSuccessful = True
+        # add some logic to log events, log in users directly
+        print "successful registration of " + request.POST['email'] +" "+ datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
+        request.POST['email_to'] = user.email
+        request.POST['email_subject'] = 'Welcome to TAP'
+        request.POST['email_message'] = 'Your registration was successful!\n\nIn case you forget your password, please go to the following page and reset your password:\n\nhttps://' + get_current_site(request).domain + '/AppMgr/reset/\n\nYour username, in case you\'ve forgotten, is the email address this message was sent to.\n\nThanks for using our site!\n\nThe ' + get_current_site(request).name + ' team'
+
+        # Update this if TAP wants email on registration
+        #exp_portal.email.send_email(request)
+
+    #return render_to_response('abcd.html', context)
+    return render_to_response('registration/register.html', {'registrationSuccessful': registrationSuccessful, 'userExists': userExists, 'error': error}, context)
+
+
+def logout_user(request):
+    """
+    Log users out and re-direct them to the main page.
+    """
+    logout(request)
+    return HttpResponseRedirect('/')
+
+@watch_login
+def login_user(request):
+        # Like before, obtain the context for the user's request.
+    context = RequestContext(request)
+
+    # If the request is a HTTP POST, try to pull out the relevant information.
+    if request.method == 'POST':
+        # Gather the username (email) and password provided by the user.
+        # This information is obtained from the login form.
+        email = request.POST['email']
+        password = request.POST['password']
+        # print "Login attempt by " + username + " at " + datetime
+
+        # Use Django's machinery to attempt to see if the username/password
+        # combination is valid - a User object is returned if it is.
+        user = authenticate(email=email, password=password)
+
+        # If we have a User object, the details are correct.
+        # If None (Python's way of representing the absence of a value), no user
+        # with matching credentials was found.
+        if user:
+            # Is the account active? It could have been disabled.
+            if user.is_active:
+                # If the account is valid and active, we can log the user in.
+                # We'll send the user back to the homepage.
+                login(request, user)
+                return HttpResponseRedirect('/AppMgr/user_profile')
+            else:
+                # An inactive account was used - no logging in!
+                return HttpResponse("Your TAP account is disabled.")
+        else:
+            # Bad login details were provided. So we can't log the user in.
+            print "Invalid login details: {0}, {1}".format(email, password)
+            return HttpResponse("Invalid login details supplied.")
+
+    # The request is not a HTTP POST, so display the login form.
+    # This scenario would most likely be a HTTP GET.
+    else:
+        # No context variables to pass to the template system, hence the
+        # blank dictionary object...
+        # experiment_title = title
+        return render(request, 'registration/login.html')
+        # return render(request, 'registration/login.html', {'experiment_title': experiment_title})
+
+        # return login_view(request, authentication_form=MyAuthForm)
+
+def reset_confirm(request, uidb64=None, token=None):
+    return password_reset_confirm(request, template_name='registration/reset_password_confirm.html',
+                                  uidb64=uidb64, token=token,
+                                  post_reset_redirect=reverse('AppMgr:login'))
+
+
+def reset(request):
+    return password_reset(request, template_name='registration/reset_password_form.html',
+                          email_template_name='registration/reset_password_email.html',
+                          post_reset_redirect=reverse('AppMgr:reset_sent'),
+                          from_email=settings.EMAIL_FROM_NOMINAL_ADDRESS)
+
+def reset_sent(request):
+    return render(request, 'registration/reset_password_done.html')
+
+@login_required(login_url='/AppMgr/login')
+def view_profile(request):
+    user = request.user
+    return render(request, 'user_profile.html',
+                  {'user': request.user,
+                  }
+                 )
diff --git a/tap/settings/base.py b/tap/settings/base.py
index 8c6a8b2..01a2567 100644
--- a/tap/settings/base.py
+++ b/tap/settings/base.py
@@ -26,7 +26,25 @@
 # SECURITY WARNING: don't run with debug turned on in production!
 DEBUG = True
 
-ALLOWED_HOSTS = []
+ALLOWED_HOSTS = ['*']
+
+SITE_ROOT = os.path.realpath(os.path.dirname(os.path.dirname(__file__)))
+
+SITE_ID = 1
+
+# Email integration setup
+EMAIL_USE_TLS = True
+EMAIL_HOST = 'email-smtp.us-east-1.amazonaws.com'
+EMAIL_PORT = 587
+EMAIL_HOST_USER = 'AKIAJJDM2ZC67STGF4IA'
+EMAIL_HOST_PASSWORD = MY_EMAIL_PASSWORD
+
+# Configurable email addresses
+# These are addresses where mail is sent from...
+EMAIL_FROM_NOMINAL_ADDRESS = "onlinetesting@xdataonline.com"
+EMAIL_FROM_ERROR_ADDRESS = "no-reply@xdataonline.com"
+# These are addresses used to send mail to...
+EMAIL_TO_ERROR_ADDRESS = "errors@xdataonline.com"
 
 
 # Application definition
@@ -37,9 +55,11 @@
     'django.contrib.contenttypes',
     'django.contrib.sessions',
     'django.contrib.messages',
+    'django.contrib.sites',
     'django.contrib.staticfiles',
     'custom_user',
     'AppMgr',
+    'axes',
 )
 
 MIDDLEWARE_CLASSES = (
@@ -55,12 +75,16 @@
 
 ROOT_URLCONF = 'tap.urls'
 
+AUTHENTICATION_BACKENDS = (
+    'django.contrib.auth.backends.ModelBackend',
+    )
+
 AUTH_USER_MODEL = 'custom_user.EmailUser'
 
 TEMPLATES = [
     {
         'BACKEND': 'django.template.backends.django.DjangoTemplates',
-        'DIRS': [],
+        'DIRS': [os.path.join(SITE_ROOT, 'templates')],
         'APP_DIRS': True,
         'OPTIONS': {
             'context_processors': [
@@ -77,7 +101,7 @@
 
 
 # Database
-# https://docs.djangoproject.com/en/1.8/ref/settings/#databases
+# https://docs.djangoproject.com/en/1.9/ref/settings/#databases
 
 DATABASES = {
     'default': {
@@ -96,7 +120,7 @@
 
 LANGUAGE_CODE = 'en-us'
 
-TIME_ZONE = 'UTC'
+TIME_ZONE = 'America/New_York'
 
 USE_I18N = True
 
@@ -109,3 +133,31 @@
 # https://docs.djangoproject.com/en/1.8/howto/static-files/
 
 STATIC_URL = '/static/'
+
+LOGGING = {
+    'version': 1,
+    'disable_existing_loggers': True,
+    'formatters': {
+        'verbose': {
+            'format': '%(levelname)s %(asctime)s %(module)s %(process)d %(thread)d %(message)s'
+        },
+    },
+    'handlers': {
+        'console': {
+            'level': 'NOTSET',
+            'class': 'logging.StreamHandler',
+            'formatter': 'verbose'
+        }
+    },
+    'loggers': {
+        '': {
+            'handlers': ['console'],
+            'level': 'NOTSET',
+        },
+        'django.request': {
+            'handlers': ['console'],
+            'propagate': False,
+            'level': 'ERROR'
+        }
+    }
+}
diff --git a/tap/settings/dev.py b/tap/settings/dev.py
index 32726e3..b594469 100644
--- a/tap/settings/dev.py
+++ b/tap/settings/dev.py
@@ -18,10 +18,7 @@
 
 DEBUG = True
 
-TEMPLATES = [
-    {
-        'OPTIONS': {
-            'debug': DEBUG,
-        },
-    },
-]
+for T in TEMPLATES:
+    T['OPTIONS']['debug'] = DEBUG
+
+
diff --git a/tap/settings/production.py b/tap/settings/production.py
index aba9e05..dd9aadc 100644
--- a/tap/settings/production.py
+++ b/tap/settings/production.py
@@ -18,11 +18,6 @@
 
 DEBUG = False
 
-TEMPLATES = [
-    {
-        'OPTIONS': {
-            'debug': DEBUG,
-        },
-    },
-]
+for T in TEMPLATES:
+    T['OPTIONS']['debug'] = DEBUG
 
diff --git a/tap/urls.py b/tap/urls.py
index ef54922..2f0ce05 100644
--- a/tap/urls.py
+++ b/tap/urls.py
@@ -17,4 +17,5 @@
 
 urlpatterns = [
     url(r'^admin/', include(admin.site.urls)),
+    url(r'^AppMgr/', include('AppMgr.urls', namespace='AppMgr')),
 ]
diff --git a/tap/wsgi.py b/tap/wsgi.py
index 41f366d..e862716 100644
--- a/tap/wsgi.py
+++ b/tap/wsgi.py
@@ -8,9 +8,12 @@
 """
 
 import os, sys
+sys.path.append('/var/www/AppMgr/tap')
+sys.path.append('/var/www/AppMgr')
 
 sys.path.append('./tap/settings')
-os.environ.setdefault("DJANGO_SETTINGS_MODULE", "tap.production")
+os.environ.setdefault("DJANGO_SETTINGS_MODULE", "production")
+
 
 from django.core.wsgi import get_wsgi_application
 application = get_wsgi_application()