#! /usr/bin/python

#------------------------------------------------------------------------
# name:
# author: 		J Skinner
# Date Written:	
# Purpose:
# Notes
#------------------------------------------------------------------------



#------------------------   GLOBALS  ------------------------------------

DEBUG_MAIN = 0
DEBUG = 0
IS_CGI = 1
IS_DB = 1

#------------------------   IMPORTS  ------------------------------------

import string
import os
import sys

import cgi
import traceback

import MySQLdb
import access
import Cookie

from the_form import The_Form


TEMPLATE_DIR = '/home/joe/Work/pysocks/'

def get_file_as_string(fname):
    return '\n'.join(open(fname, 'r').readlines())


class Auth:
    auth_exception = 'authentication exception'
    # error pages start at id 10000
    ERROR_PAGE = 10001
    __logout_link = '<a href="./index.cgi?action=logout">logout</a>'
    __login_link = '<a href="./index.cgi?action=login">login</a>'

    def test(self):
        print 'visted', self.__visted, '<br>'
        print 'auth_level', self.auth_level, '<br>'
        print 'user_id', self.__user_id, '<br>' 
        print 'cookie', self.__cookie, '<br>' 
        print 'auth_id', self.__auth_id, '<br>' 
        print 'set_cookie', self.__set_cookie, '<br>' 
        print 
        print 'logged_in', self.__logged_in, '<br>' 
        #print 'cookie', self.__cookie['pysocks_id'].value, '<br>'
        #print 'env cookie', os.environ['HTTP_COOKIE'], '<br>'
        #print 'form_data', `self.__form_data`

        
    def __init__(self, db, form_data=None):
        self.__visted = []
        self.__form_data = form_data
        self.__db = db
        self.auth_level = 0 
        self.__user_id = None
        self.__cookie = None
        self.__auth_id = None
        self.__set_cookie = None
        self.do_login = None
        self.do_logout = None
        self.do_download = None
        
        self.__logged_in = None

        self.__setup()

        if self.__form_data.action == 'login':
            self.do_login = 1
        elif self.__form_data.action == 'login_check':
            self.login_check()
        elif self.__form_data.action == 'logout':
            self.do_logout = 1
            self.logout()
        elif self.__form_data.action == 'download':
            self.do_download = 1

    def __setup(self):
        
        if os.environ.has_key('HTTP_COOKIE'):
            self.__visted.append('setup: environ check')
            self.__cookie = Cookie.SmartCookie(os.environ['HTTP_COOKIE'])
        else:
            self.__cookie = Cookie.SmartCookie()

        if self.__cookie.has_key('pysocks_id'):
            self.__visted.append('setup: cookie key')
            self.__user_id = self.__cookie['pysocks_id'].value
            try:
                self.__auth_id, self.__status = self.__db.get('auth', 
                    ['auth_id', 'status'],
                    where='auth_id="%s"'%self.__user_id)[0]
                self.__visted.append('setup: %s'%self.__auth_id)
                if self.__status not in [-1, 0]:
                    self.__logged_in = 1
            except self.__db.NO_DATA:
                # something wrong - maybe the cookie has been expired.
                # set the cookie to the active but not logged in status
                # 0 and give the person a new auth record.
                

                self.__auth_id = self.__db.put('auth', {'status':'0'} )

                self.__cookie['pysocks_id'] = self.__auth_id
                self.__visted.append('setup: except clause')
                

        else: 
            # we have no cookie set it up
            # check to see that the login isn't expired
            self.__auth_id = self.__db.put('auth', {'status':'0'} )

            self.__cookie['pysocks_id'] = self.__auth_id

            # if expired send them to a login screen or an error screen 
            # not sure which.

            # get further details.

#            user_info = self.__db.get_dict('user', [...],
#                where='auth_id="%s"'%self.__auth_id)[0]

                
            
    def show_login(self):
        #  this is a temp hack.
        self.__set_cookie = 1
        print get_file_as_string(Template_DIR+'login.html') 

    def login_check(self):
        # this is broken fix.
        
        self.__visted.append('login_check')

        if self.__form_data.username and \
            self.__form_data.passwd:
            pass
        else:
            # we have a bad password bail out.
            return -1, 1000

        try:
            results = self.__db.get_dict('users', 
                ['username', 'passwd', 'user_id', 'auth_level'],
                where='username="%s" and passwd="%s"'%(
                self.__form_data.username, self.__form_data.passwd))[0]
            self.__db.set('auth', {'status':1},
                where='auth_id="%s"'%self.__auth_id)
            self.auth_level = results['auth_level'] 
            self.__logged_in = 1
        except self.__db.NO_DATA:
            return -1, 1000

        return 1, 1
             
    def logout(self):
        '''\
        expire the cookie to logout the person and 
        update the status in the db'''

        try:
            self.__db.set('auth', {'status':0},
                where='auth_id=%s'%self.__cookie['pysocks_id'].value)
        except:
            self.__visted.append('logout: Error in auth.logout()')

        self.__cookie['pysocks_id'] = 0
        self.__logged_in = 0
        self.__visted.append('logout: %s'%self.__logged_in)
        self.__visted.append('logout: %s'%str(self.__cookie))


    def is_logged_in(self):
        return self.__logged_in
        
    def __get_cookie(self):
        if os.environ.has_key('HTTP_COOKIE'):
            self.__cookie.load(os.environ['HTTP_COOKIE'])
            self.__user_id = self.__cookie['pysocks_id']

            # query the database to check if this is still valid.

            try:
                self.__user_id, self.auth_level = \
                    self.__db.get_dict('auth', ['logged_in'],
                    where='id=%s'%self.__cockie['user_id', 'auth_level'])[0]
            except self.__db.NO_DATA:
                # no one home.
                # generate an error
                raise self.auth_exception


    def error_page(self):
        return Page(self.__ERROR_PAGE) 
        pass

    def show(self):
        return self.__cookie

    def login_status(self):
        self.__visted.append('login status %s'%self.__logged_in)
        if self.__logged_in:
            return 'Currently Logged in | %s'%self.__logout_link
        else:
            return 'Not logged in | %s'%self.__login_link

    def get_cookie_header(self):
        #self.__cookie['pysocks_id'] = self.__auth_id
        return str(self.__cookie)

#------------------------    CODE    ------------------------------------


#class The_Form:
#    __attributes = {'username':None, 'passwd':None, 'function':'default',
#        'action':None}
#    __keys = __attributes.keys()
#    
#    def __init__(self, vals=None, extra_attrs=None):
#        '''\
#        init object
#            has two optional parameters both dictionaries
#            vals is a set of vals to put into the object and 
#            extra_attrs is a list of attributes with defaults that can be
#            added
#        '''
#        
#        if extra_attrs:
#            for i in extra_attrs.keys():
#                self.__attributes[i] = extra_attrs[i]
#            self.__keys = self.__attributes.keys()
#            
#        if vals:
#            for i in vals.keys():
#                if i in self.__keys:
#                    self.__attributes[i] = vals[i]
#                else:
#                    self.__invalid_item = 1
#
#    def error(self):
#        if self.__invalid_item:
#            return 1
#        else:
#            return 0
#
#                    
#    def get_values_from_form(self, form):
#        for i in self.__keys:
#            if form.has_key(i):
#                self.__attributes[i] = form[i].value
#
#    def __setattr__(self, attr, val):
#        if attr in self.__keys:
#            self.__attributes[attr] = val
#
#    
#    def __getattr__(self, attr):
#        if attr in self.__keys:
#            return self.__attributes[attr]

class Page:
    __attributes = {'login':None}
    __keys = __attributes.keys()

    def __init__(self, auth):
        self.__auth = auth
        pass

    def __set_cookie(self):
        pass

    def __show_header(self):
        print 'Content-type: text/html'
        print self.__auth.get_cookie_header()
        print

    def __show_body(self):
        self.__attributes['login'] = self.__auth.login_status()
        print  self.__template%self.__attributes

    def load_template(self, template):
        self.__template = get_file_as_string(template)

    def show(self):
        self.__show_header()
        self.__show_header()
        self.__show_body()

def main():

    form = cgi.FieldStorage()
    form_data = The_Form()
    form_data.get_values_from_form(form)
    db = access.Access(dbname='pysocks', user='crypt')
    
    auth = Auth(db, form_data)
    
    page = Page(auth)

#    print 'Content-type: text/html'
#    print
    page.load_template('/home/crypt/Work/pysocks/simple.html')


    page.show()

    auth.test()

#    print os.environ['cookie']
#    print cgi.print_environ()



#------------------------------------------------------------------------

if  __name__ == '__main__':
    main()

#------------------------     END    ------------------------------------
