def boil_out(): # TODO: Log errors and inform administrator. Only inform user that this # should not happen and a bug report has been filed. Encourage user to # offer assistance (contact administrator, describe problem). import sys exc = sys.exc_info()[1] print '<B>Unhandled Exception:</B> <I>%s</I>' % exc if isinstance(exc, error): print ' (%s)' % error.lvl_txt(exc.lvl()) else: error(error.error, str(exc)) print '<BR />\n' from germ.txt import errmsg print errmsg.failure print "<PRE>" import traceback import sys traceback.print_exc(file = sys.stdout) print "</PRE>" import cf print '<HR>Webmaster: ' \ '<A href="mailto:%s">%s</A>' % (cf.admin_email, cf.admin_email) from pso.service import OK return OK
def post(self, act_str): if act_str == 'edit': if self.__prev_phase == 1 and self.__next_phase == 2: attr = self.get_attr_nocheck('mode') mode = attr.get() if mode == 0: # TODO: Create ranking table if necessary. pass elif mode == 1: from germ.error.error import error raise error(error.error, 'Not yet implemented: %s' % str(attr)) elif mode == 2: # double elimination party = self.get_attr_nocheck('party').get() tourney = self.get_attr_nocheck('name').get() from double_elimination import double_elimination double_elimination.start(party, tourney, self.__teams, self._session, self._globals) else: from germ.error.error import error raise error(error.error, 'Unknown mode %i' % mode)
def attr_iter(self, action): for aid in self._attr_ids: attr = self._attr_map[aid] from germ.error.error import error error(error.debug, 'checking attribute', aid) if attr.dyn_perm(action): yield attr else: from germ.attr.dummy import dummy yield dummy()
def query(cls, query): from germ.error.error import error error(error.debug, 'db_iface query', query) if cls.__type == 'mysql': rset = cls.__sql_query_mysql(query) else: from germ.error.error import error from germ.txt import errmsg raise error(error.fail, errmsg.unknown_db_type, 'db_type: %s' % __type) return rset
def pre(self, act_str): if act_str == 'submit': self._attr_map['phase'].set_mask([0]) elif act_str == 'edit': phase = self.get_cur_attr('phase') mask = [] if phase == 0: mask = [phase, phase + 1] elif phase == 1: from team_members import team_members party = self.get_attr_nocheck('party').get() tourney = self.get_attr_nocheck('name').get() size = self.get_attr_nocheck('teamsize').get() self.__teams = team_members.get_teams(party, tourney, size, self._session, self._globals) if len(self.__teams) >= 2: mask = [phase, phase + 1] else: mask = [phase] else: from germ.error.error import error raise error(error.error, 'Attempt to edit tourney in ' \ 'phase %i' % phase) attr = self.get_attr_nocheck('phase') attr.set_mask(mask) self.__prev_phase = phase self.__next_phase = attr.get()
def start_item(self, attrs): if self._hide > 0: self._hide += 1 return attr_map = dict(attrs) ent_str = attr_map.get('entity') act_str = attr_map.get('action') if ent_str is None or act_str is None: from germ.error.error import error raise error(error.warn, 'Invalid item', 'entity: %s, action: %s' \ % (ent_str, act_str)) entity = self.__check_item(ent_str, act_str) for k in attr_map.keys(): import re attr_map[k] = re.sub(r'\$([A-Za-z_][A-Za-z0-9_]*)', self.__variable, attr_map[k]) if self.__unknown_variable: attr_map.pop(k) self.__unknown_variable = False if entity is not None: self.__item_stack.append((attr_map, entity, act_str))
def check_pwd(self, aid): from germ.erm.helper import sql_query rset = sql_query("SELECT %s FROM %s WHERE username = '******'" % \ (cf.pwd_str, self.__user_table, self._attr_map['username'].sql_str()), self._session, self._globals) if len(rset) > 1: # TODO: Make this an invalid_key exception. This could very well # occur by a user 'mistake'. On the other hand, can it still occur # if ref_group.generate_keylist did not complain? from germ.error.error import error raise error(error.fail, "Ambiguous primary key: result has " + \ "multiple records", "number of records: %s" % \ len(rset)) if len(rset) == 0: invalid_auth = True else: passwd = rset[0][0] invalid_auth = not self._attr_map[aid].check(passwd) if invalid_auth: from germ.error.invalid_parm import invalid_parm raise invalid_parm('Wrong username/password')
def get_entity(ent_str, session, glob = globals()): try: mod = __import__('entity.' + ent_str, glob, locals(), [ent_str]) except ImportError, e: from germ.error.error import error raise error(error.fail, "Could not find entity. " + \ "ImportError: " + str(e), "entity: " + ent_str)
def get(self): val = self._val if val not in self.__mask: from germ.error.error import error raise error(error.error, "Choice does not heed masking", "key: %s, mask: %s" % (val, self.__mask)) return val
def __init__(self, label, options, perm = [], default = 0, chk_func_vec = []): attribute.__init__(self, label, perm, default, chk_func_vec) if len(options) == 0: raise error(error.fail, errmsg.attr_choice_nooptions) self.__options = options self.__mask = range(len(options))
def action_txt(self, act_str): from germ.txt import misc text = self.__action_txt.get(act_str, misc.action.get(act_str)) if text is None: from germ.error.error import error raise error(error.warn, 'No action description', 'action: %s' % \ act_str) return text
def get_action(act_str, do_exec): action_class_str = 'act_' + act_str try: mod = __import__('germ.erm.' + action_class_str, globals(), locals(), [action_class_str]) except ImportError, e: from germ.error.error import error raise error(error.fail, "Could not perform action. " + \ "ImportError: " + str(e), "action: " + act_str)
def sql_str(self): from germ.lib.db_iface import db_iface string = self._sql_str() if string is None: from germ.error.error import error raise error(error.error, 'Invalid SQL String', 'attr: %s' % \ self.__class__.__name__) return db_iface.escape_string(string)
def get_missing_table(cls, e): if cls.__type == 'mysql': from MySQLdb.constants.ER import NO_SUCH_TABLE if e.args[0] == NO_SUCH_TABLE: import cf, re return re.match("^Table '%s\.([a-z_]*)'" % cf.db_database, e.args[1]).group(1) else: from germ.error.error import error raise error(error.fail, errmsg.unimplemented) return None
def __session_val(self, match): if match.group(2) is not None: varname = match.group(2)[1:] ent_str = match.group(1) from helper import get_entity entity = get_entity(ent_str, self.__session, self.__ent.get_globals()) val = entity.magic_var(varname) if val is None: from germ.error.error import error raise error(error.error, 'Invalid magic variable', 'entity: %s, varname: %s' % (ent_str, varname)) return str(val) varname = match.group(1) val = self.__ent.magic_var(varname) if val is not None: return val if not self.__session.has_key(varname): # this will evaluate all comparisons to NULL, i.e. false return 'NULL' val = self.__session[varname] if not isinstance(val, str): from germ.error.error import error raise error(error.fail, "Session variables for use in an " \ "SQL condition must be strings", "variable: %s, type: %s" % (varname, type(val))) from germ.lib.db_iface import db_iface return "'%s'" % db_iface.escape_string(val)
def get_rec_explicit(self, table, key, attrs="*"): from germ.erm.helper import sql_query rset = sql_query("SELECT %s FROM %s WHERE %s" % (attrs, table, key), self._session, self._globals) if len(rset) != 1: # TODO: Make this an invalid_key exception. This could very well # occur by a user 'mistake'. On the other hand, can it still occur # if ref_group.generate_keylist did not complain? from germ.error.error import error raise error(error.fail, "Invalid key", "number of records: %s" % len(rset)) return rset[0]
def get_cond(cond, act_str): if not isinstance(cond, dict): from germ.error.error import error raise error(error.error, 'Invalid condition type', 'cond: %s, type: %s' % (cond, type(cond))) cond_act = cond.get(act_str) cond_all = cond.get('all') if cond_act is None: return cond_all elif cond_all is None: return cond_act else: return '(%s) AND (%s)' % (cond_all, cond_act)
def startend_attr(self, attrs): attr_map = dict(attrs) aid = attr_map.get('id') if aid is None: from germ.error.error import error raise error(error.warn, 'Invalid attr tag', 'id: %s' % (aid)) attr = self.__rec.get_attr(aid, 'view') from attr_act_view import attr_act_view act_view = attr_act_view() attr.accept(act_view) return act_view.get_text()
def has_paid(self): # TODO: This is very similar to ent_table.get_rec(). from germ.erm.helper import sql_query rset = sql_query("SELECT paid FROM %s WHERE %s" % \ (self._name, self.get_attr_sql_pk()), self._session, self._globals) if len(rset) != 1: from germ.error.error import error raise error(error.fail, "Invalid primary key: result is empty " + \ "or has multiple records", "number of records: %s" % \ len(rset)) return rset[0][0] == 1
def __variable(self, match): varname = match.group(1) if not self._session.has_key(varname): self.__unknown_variable = True return '' val = self._session[varname] if not isinstance(val, str): from germ.error.error import error raise error(error.fail, "Session variables for use in a " \ "URL must be strings", "variable: %s, type: %s" % (varname, type(val))) import urllib return urllib.quote_plus(val, '')
def handler(req): from log_file import log_file error.log_file = log_file() from germ.lib import misc misc.txt_lang_convert.append(convert_html) try: import cf prevent_caching(req) req.pso().send_http_header() import cgi form = cgi.FieldStorage(keep_blank_values = True) # Get index. wholename = cf.ht_docpath + '/index.html' index = None try: index = file(wholename) except IOError, e: raise error(error.fail, e, 'Could not open index file "%s"' % \ wholename) #try: # req.pso().session['reloads'] += 1 #except: # req.pso().session['reloads'] = 1 #session = req.pso().session from pso.session import CookieFileImpl session = req.pso().getSession(CookieFileImpl, PSOSessionFileLoader_Path=cf.ht_tmp_path) ret = get_content(form, session) if isinstance(ret, bool): return ret content = ret from ht_parser import ht_parser parser = ht_parser() parser.set_params(content, session) while True: text = index.read() if not len(text) > 0: break parser.feed(text) parser.close() print parser.output()
def to_lock(self): if not self.is_set(): from germ.error.error import error raise error(error.fail, errmsg.tried_locking_unset_attr) else: self.__to_lock = True
def print_form(entity, act_str, page, prompt_pk_only, display_errors): import cf formtext = '<FORM method="GET" action="%s" autocomplete="off">\n' % cf.ht_index # Give form again until user has seen all the fields, except for a view. if not prompt_pk_only or act_str == "view": formtext += '<INPUT type="hidden" name="do_exec">\n' formtext += '<INPUT type="hidden" name="entity" value="%s">\n' % entity.get_name() formtext += '<INPUT type="hidden" name="action" value="%s">\n' % act_str if page is not None: formtext += '<INPUT type="hidden" name="page" value="%s">\n' % page formtext += "<TABLE>\n" error_vec = [] from attr_act_form_field import attr_act_form_field act_form_field = attr_act_form_field() from attr_act_form_key import attr_act_form_key act_form_key = attr_act_form_key() attr_vec = entity.get_attr_vec(act_str) pk_set = entity.get_pk_set() prev_was_key = False prev_group = None cnt = 0 while len(attr_vec) > 0: group = entity.get_ref_group(attr_vec[0]) from germ.error.error import error error(error.debug, "printing attribute", "aid: %s, group: %s" % (attr_vec[0], group)) if group is None: aid = attr_vec.pop(0) if prompt_pk_only: continue prev_was_key = False attr = entity.get_attr_nocheck(aid) formtext += '<TR><TD colspan="2">%s:</TD><TD>' % attr.label() # This can happen if the attribute is already locked for the first # request. if attr.is_locked(): formtext += '<INPUT type="hidden" name="lock" ' 'value="%s">' % aid parm_name = cf.ht_parm_prefix_attr + aid act_form_field.set_parm_name(parm_name) attr.accept(act_form_field) formtext += act_form_field.get_text() if display_errors: formtext += get_error(attr, error_vec) formtext += "</TD></TR>\n" else: cnt += 1 j = 0 first = True # Also display remaining attributes of the same reference group. while j < len(attr_vec): if not group.has_key(attr_vec[j]): j += 1 continue aid = attr_vec.pop(j) attr = entity.get_attr_nocheck(aid) if prompt_pk_only and aid not in pk_set: continue if prev_group != group and prev_was_key: formtext += '<TR><TD colspan="2"></TD><TD><HR></TD></TR>\n' prev_group = group prev_was_key = True from sets import Set as set keyset = group.has_fk(aid) and set(group.get_keys(aid)) or set() locked = attr.is_locked() lock = locked or len(keyset) == 1 formtext += ( '<TR><TD>%s:</TD><TD align="right"><INPUT ' 'type="radio" name="to_lock%u" ' 'value="%s"%s%s></TD><TD>' % (attr.label(), cnt, aid, (lock) and " disabled" or "", (not lock and first) and " checked" or "") ) if lock: formtext += '<INPUT type="hidden" name="lock" ' 'value="%s">' % aid elif first: first = False parm_name = cf.ht_parm_prefix_attr + aid change_handler = ( "var radios = this.form.elements['to_lock%u']; " "for (var i = 0; i < radios.length; i++) {" " if (radios[i].value == '%s') {" " radios[i].checked = true; " " break; " " }" "}" % (cnt, aid) ) if group.has_fk(aid): formtext += '<SELECT name="%s" onchange="%s"%s>' % ( parm_name, change_handler, locked and " disabled" or "", ) if attr.is_set(): cur_key = attr.sql_str() else: cur_key = None tmp_attr = attr.copy() prev_key = None for key in keyset: formtext += '\t<OPTION value="%s"%s>' % (key, key == cur_key and " selected" or "") tmp_attr.set_sql(key) tmp_attr.accept(act_form_key) formtext += act_form_key.get_text() formtext += "</OPTION>\n" prev_key = key formtext += "</SELECT>" if attr.is_locked(): formtext += '<INPUT type="hidden" name="%s" ' 'value="%s">' % (parm_name, attr.get()) else: act_form_field.set_parm_name(parm_name) act_form_field.set_handler("change", change_handler) attr.accept(act_form_field) formtext += act_form_field.get_text() if display_errors: formtext += get_error(attr, error_vec) formtext += "</TD></TR>\n" from germ.lib.misc import txt_lang formtext += ( '<TR><TD colspan="2"></TD>' '<TD><INPUT type="submit" value="%s"></TD>' "</TR>\n" % txt_lang(entity.action_txt(act_str)) ) formtext += "</TABLE>\n</FORM>" from germ.txt import errmsg errortext = len(error_vec) > 0 and txt_lang(errmsg.attr_error) + ":<BR />\n" or "" for i, e_vec in enumerate(error_vec): err_str = "" for e in e_vec: err_str += "%s<BR />\n" % e errortext += '<SPAN style="color: red">%s</SPAN>: %s' % (i + 1, err_str) errortext += len(error_vec) > 0 and "<BR />\n" or "" return (formtext, errortext)
def _do_set(self, val): from germ.error.error import error raise error(error.fail, errmsg.abstract_func, 'class: %s' % self.__class__)
def do_accept(self, action): raise error(error.fail, errmsg.abstract_func)
def _get_sql_query(self, table, sql_str): raise error(error.error, errmsg.abstract_func)
def get_content(form, session): import cf # First we get the action object and an entity, then the parameters. # No action means 'just display the page', i.e. we need the 'page' # parameter. p_action = form.getfirst('action', None) p_entity = form.getfirst('entity', None) p_page = form.getfirst('page', None) fullpage = form.has_key('fullpage') if p_action is None: if p_entity is not None: raise error(error.fail, "Request for an entity without an " + "action to act on it", "entity: %s" % p_entity) if p_page is None: p_page = cf.ht_default_page p_action = cf.ht_default_action p_entity = cf.ht_default_entity elif p_entity is None: raise error(error.fail, "Request for an action without an " \ "entity to act on", "action: %s" % p_action) # Get page. page = None if p_page is not None: page = get_page(p_page) if page is None and p_entity is not None: page = get_page(p_entity) if p_action is None: pagetext = '' if page is not None: while True: text = page.read() if not len(text) > 0: break pagetext += text return pagetext # Parse GET parameters. from sets import Set attr_map = {} attr_locks = Set() attr_to_lock = Set() do_exec = False for name, val in [(parm.name, parm_val(parm)) for parm in form.list]: if name.startswith(cf.ht_parm_prefix_attr): # Handle multivalued parameters. pos = name.find('__', len(cf.ht_parm_prefix_attr)) if pos < 0: attr = name[len(cf.ht_parm_prefix_attr):] if attr_map.has_key(attr): if isinstance(attr_map[attr], dict): raise error(error.error, "Multi-valued parameter " \ "overwritten with single-valued parameter", "attribute: %s" % attr) else: # If a single-valued parameter is specified multiple # times, the last occurence counts. pass attr_map[attr] = val else: attr = name[len(cf.ht_parm_prefix_attr):pos] if not attr_map.has_key(attr): attr_map[attr] = {} elif not isinstance(attr_map[attr], dict): raise error(error.error, "Single-valued parameter " \ "overwritten with multi-valued parameter", "attribute: %s" % attr) attr_map[attr][name[pos+2:]] = val elif name == 'lock': attr_locks.add(val) elif name.startswith('to_lock'): attr_to_lock.add(val) elif name == 'do_exec': do_exec = True from germ.erm.helper import get_entity entity = get_entity(p_entity, session, globals()) found_invalid_parm = False for attr, value in attr_map.iteritems(): from germ.error.invalid_parm import invalid_parm try: a = entity.get_attr(attr, p_action) from attr_act_set import attr_act_set a.accept(attr_act_set(value)) except invalid_parm, e: found_invalid_parm = True if attr in attr_locks: raise error(error.fail, "Locked attribute has invalid value", "attr: %s, error: %s" % (attr, e)) elif attr in attr_to_lock: attr_to_lock.remove(attr)
from germ.error.perm_denied import perm_denied from germ.error.do_not_exec import do_not_exec from germ.error.missing_lock import missing_lock from germ.error.missing_pk_lock import missing_pk_lock if isinstance(e, no_valid_keys) or isinstance(e, perm_denied): self._hide += 1 return None elif not (isinstance(e, do_not_exec) or \ isinstance(e, missing_lock) or \ isinstance(e, missing_pk_lock)): import sys exctype, exc, tb = sys.exc_info() raise exctype, exc, tb else: raise error(error.error, 'action succeeded without do_exec', 'entity: %s, action: %s' % (ent_str, act_str)) return entity def __variable(self, match): varname = match.group(1) if not self._session.has_key(varname): self.__unknown_variable = True return '' val = self._session[varname] if not isinstance(val, str): from germ.error.error import error raise error(error.fail, "Session variables for use in a " \
and (not do_exec or found_invalid_parm): display_errors = False error_str = str(e) + "<BR />\n<BR />\n" if isinstance(e, missing_lock): if not do_exec: error_str = str(do_not_exec()) + "<BR />\n<BR />\n" elif isinstance(e, invalid_parm): pass elif isinstance(e, do_not_exec): pass elif isinstance(e, missing_pk_lock): prompt_pk_only = True elif isinstance(e, no_valid_keys) or isinstance(e, perm_denied): error(error.warn, e, "action: %s, entity: %s" % \ (p_action, p_entity)) return error_str else: import sys exctype, exc, tb = sys.exc_info() raise exctype, exc, tb print_parm = { 'handler': print_handler, 'entity': entity, 'action': p_action, 'page': p_page, 'prompt_pk_only': prompt_pk_only, 'display_errors': display_errors, 'error_str': error_str }
def check(self, crypted_pwd): from crypt import crypt from germ.error.error import error error(error.debug, 'checking password %s (%s)' % (self._val, crypted_pwd)) return crypted_pwd == crypt(self._val, crypted_pwd)