Guest User

Untitled

a guest
Jan 14th, 2018
169
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 8.09 KB | None | 0 0
  1. '''Staff management.'''
  2.  
  3. import time
  4. from sqlalchemy.sql import case, or_, and_, select, func, null
  5.  
  6. import strings
  7. import model
  8. import misc
  9. import staff_interface
  10. import config, config_defaults
  11. from util import WakaError, local
  12. from template import Template
  13.  
  14. # TODO: Synchronized cache of staff personnel objects.
  15. # _staff = {}
  16.  
  17. # Staff class types.
  18. ADMIN = 'admin'
  19. GLOBAL_MOD = 'globmod'
  20. MODERATOR = 'mod'
  21. CLASSES = (ADMIN, GLOBAL_MOD, MODERATOR)
  22.  
  23. # Login cookie expire times (in seconds).
  24. SAVED_LOGIN_EXPIRE = 365 * 24 * 3600
  25. UNSAVED_LOGIN_EXPIRE = 3600
  26.  
  27. # Staff Accounts and Logins
  28. class LoginData(object):
  29.     '''Class for interfacing with prefetched login data.'''
  30.  
  31.     def ___init___(self, user, addr):
  32.         self.addr = addr
  33.         self.crypt = misc.hide_critical_data\
  34.                        (','.join((user.password, remote)), config.SECRET)
  35.         self.username = user.username
  36.         self.cookie_str = ','.join((self.username, self.crypt))
  37.  
  38.     def make_cookie(self, save_login=False):
  39.         misc.make_cookies(admin=self._cstring)
  40.  
  41.         if save_login:
  42.             misc.make_cookies(wakaadminsave='1', wakaadmin=self.crypt,
  43.                               expires=time.time()+SAVED_LOGIN_EXPIRE)
  44.         else:
  45.             misc.make_cookies(wakaadminsave='0', wakaadmin=self.crypt,
  46.                               expires=time.time()+UNSAVED_LOGIN_EXPIRE)
  47.  
  48. # Class for representing staff
  49.  
  50. class StaffMember(object):
  51.     '''A staff object for acquiring and updating personnel account
  52.    information. Use the class factory method to initialize:
  53.    
  54.    >> StaffMember.get('SirDerpDeeDoo')
  55.    
  56.    To create new staff accounts, use the add_staff() method instead.'''
  57.  
  58.     def __init__(self, username):
  59.         session = model.Session()
  60.         table = model.account
  61.         table.create(bind=model.engine, checkfirst=True)
  62.         sql = table.select().where(table.c.username == username)
  63.         row = session.execute(sql).fetchone()
  64.         self._table = table
  65.  
  66.         if row is None:
  67.             WakaError('Staff not found.')
  68.  
  69.         # Grab parameters from database. Password is pre-encrypted.
  70.         self.username = username
  71.         self._password = row.password
  72.         self._class = row.account
  73.         self._reign = row.reign.split(',')
  74.         self._disabled = row.disabled
  75.         self._update_dict = {}
  76.  
  77.         # Not logged in yet.
  78.         self._login_data = None
  79.  
  80.     def _update_db(self, **kwargs):
  81.         self._update_dict += kwargs
  82.  
  83.     @property
  84.     def password(self):
  85.         return self._password
  86.  
  87.     @password.setter
  88.     def password(self, new):
  89.         table = self._table
  90.         # TODO: Sanity checks
  91.  
  92.         kwargs = {'password' : new}
  93.         self._update_db(**kwargs)
  94.         self._password = new
  95.  
  96.     @property
  97.     def reign(self):
  98.         return self._reign
  99.  
  100.     @reign.setter
  101.     def reign(self, board_list):
  102.         reign_str = ','.join(board_list)
  103.         kwargs = {'reign' : reign_str}
  104.         self._update_db(**kwargs)
  105.  
  106.         self._reign = board_list
  107.  
  108.     @property
  109.     def account(self):
  110.         return self._class
  111.  
  112.     @account.setter
  113.     def account(self, new):
  114.         if new in CLASSES:
  115.             kwargs = {'account' : new}
  116.             self._update_db(**kwargs)
  117.             self._class = new
  118.         else:
  119.             raise WakaError('Invalid class name %s' % new)
  120.  
  121.     @property
  122.     def login_data(self):
  123.         return self._login_data
  124.  
  125.     @property
  126.     def disabled(self):
  127.         return self._disabled
  128.  
  129.     @disabled.setter
  130.     def disabled(self, disable):
  131.         if disable:
  132.             kwargs = {'disabled' : 1}
  133.         else:
  134.             kwargs = {'disabled' : 0}
  135.         self._disabled = disable
  136.  
  137.         self._update_db(**kwargs)
  138.  
  139.     def login_host(self, ip):
  140.         login_data = LoginData(self.username, ip)
  141.         self._login_data = login_data
  142.         return login_data
  143.  
  144.     def logout_user(self):
  145.         self._login_data = None
  146.  
  147.     def flush_db(self):
  148.         session = model.Session()
  149.         table = self._table
  150.  
  151.         if len(self._update_dict) > 0:
  152.             db_update = table.update().where(self.username == username)\
  153.                              .values(**self._update_dict)
  154.  
  155.     @classmethod
  156.     def get(cls, username):
  157. #        if username in _staff:
  158. #            return _staff[username]
  159.  
  160.         staff_obj = cls(username)
  161. #       _staff[username] = staff_obj
  162.         return staff_obj
  163.  
  164. def add_staff(username, pt_password, account, reign):
  165.     session = model.Session()
  166.     table = model.account
  167.     password = misc.hide_critical_data(pt_password, config.SECRET)
  168.     reign_str = ','.join(reign)
  169.  
  170.     sql = table.insert().values(username=username, password=password,
  171.                                 account=account, reign=reign_str,
  172.                                 disabled=0)
  173.     session.execute(sql)
  174.  
  175. def del_staff(username):
  176.     session = model.Session()
  177.     table = model.account
  178.     sql = table.delete(table.c.username == username)
  179.     session.execute(sql)
  180.  
  181. #    try:
  182. #        del _staff[username]
  183. #    except AttributeError:
  184. #        pass
  185.  
  186. def edit_staff(mpass, username, clear_pass=None, new_class=None,
  187.                reign=None):
  188.  
  189.     staff_obj = get_staff(username)
  190.    
  191.     if clear_pass:
  192.         staff_obj.password = misc.hide_critical_data(clear_pass,
  193.                                                      config.SECRET)
  194.  
  195.     if new_class and new_class in CLASSES:
  196.         staff_obj.account = new_class
  197.  
  198.     if reign:
  199.         staff_obj.reign = reign
  200.  
  201.     staff_obj.flush_db()
  202.  
  203. def staff_exist():
  204.     session = model.Session()
  205.     table = model.account
  206.     table.create(bind=model.engine, checkfirst=True)
  207.     sql = select([func.count()], table)
  208.     row = session.execute(sql).fetchone()
  209.  
  210.     if row[0] == 0:
  211.         return False
  212.     else:
  213.         return True
  214.  
  215.  
  216. def do_login(username=None, password=None, save_login=False,
  217.              admin_cookie=None, nexttask='mpanel'):
  218.  
  219.     bad_pass = False
  220.     staff_entry = None
  221.  
  222.     if len(_staff) == 0 and not staff_exist():
  223.         return staff_interface.make_first_time_setup_gateway()
  224.     elif username and password:
  225.         # Login via login form entry.
  226.         try:
  227.             staff_entry = get_staff(username)
  228.         except WakaError:
  229.             # Bad username.
  230.             bad_pass = True
  231.         else:
  232.             crypt_pass = misc.hide_critical_data(staff_entry.password,
  233.                                                  config.SECRET)
  234.             if crypt_pass == staff_entry.password:
  235.                 staff_entry.login_host(remote)
  236.             else:
  237.                 bad_pass = True
  238.     elif admin_cookie:
  239.         # Attempt automatic login.
  240.         staff_entry = check_password(admin_cookie, nexttask)
  241.     else:
  242.         # No login credentials given.
  243.         bad_pass = True
  244.  
  245.     if bad_pass:
  246.         return staff_interface.make_login_panel()
  247.     else:
  248.         login = staff_entry.login_data
  249.         login.make_cookie(save_login=save_login)
  250.         return staff_interface.make_admin_panel(login.cookie, nexttask)
  251.  
  252. def do_logout(admin):
  253.     # Clear login cache.
  254.     try:
  255.         user = check_password(admin)
  256.         user.logout_user()
  257.     except WakaError:
  258.         pass
  259.  
  260.     # Clear login cookies.
  261.     misc.make_cookies(wakaadmin='', wakaadminsave='0', expires=0)
  262.  
  263. def check_password(cookie_str, editing=None):
  264.     (username, crypt) = cookie_str.split(',')
  265.     staff_entry = get_staff(username)
  266.     cache = staff_entry.login_data
  267.  
  268.     if cache and cache.addr == remote:
  269.         # The host is already logged in.
  270.         pass
  271.     elif crypt != misc.hide_critical_data(','.join([staff_entry.password,
  272.                                                     remote]), config.SECRET):
  273.         WakaError(S_WRONGPASS)
  274.     else:
  275.         # NOTE: This will overwrite the current network address login.
  276.         staff_entry.login_host(remote)
  277.  
  278.     return staff_entry
  279.  
  280. def crypt_pass(cleartext):
  281.     remote = local.environ['REMOTE_ADDR']
  282.     return misc.hide_critical_data(','.join((cleartext, remote)),
  283.                                             config.SECRET)
Add Comment
Please, Sign In to add comment