Guest User

Untitled

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