def callProcInternal(self, oCursor, sProcedure, aoArgs, sCallerName): """ Call a stored procedure. Mostly a wrapper around the psycopg2 cursor method 'callproc', but collect data for traceback. """ if aoArgs is None: aoArgs = list(); nsStart = utils.timestampNano(); try: oRc = oCursor.callproc(sProcedure, aoArgs); except Exception as oXcpt: cNsElapsed = utils.timestampNano() - nsStart; self._aoTraceBack.append([nsStart, 'oXcpt=%s; Calling: %s(%s)' % (oXcpt, sProcedure, aoArgs), cNsElapsed, 0, sCallerName, None]); if self._fnDPrint is not None: self._fnDPrint('db::callproc %u ns, caller %s: oXcpt=%s; Calling: %s(%s)' % (cNsElapsed, sCallerName, oXcpt, sProcedure, aoArgs)); raise; cNsElapsed = utils.timestampNano() - nsStart; if self._fTransaction is False and not self.isAutoCommitting(): # Even SELECTs starts transactions with psycopg2, see FAQ. self._aoTraceBack.append([nsStart, '[START TRANSACTION]', 0, 0, sCallerName, None]); self._startedTransaction(); self._aoTraceBack.append([nsStart, '%s(%s)' % (sProcedure, aoArgs), cNsElapsed, oCursor.rowcount, sCallerName, None]); if self._fnDPrint is not None: self._fnDPrint('db::callproc %u ns, caller %s: "%s(%s)"' % (cNsElapsed, sCallerName, sProcedure, aoArgs)); if self.isAutoCommitting(): self._aoTraceBack.append([nsStart, '[AUTO COMMIT]', 0, 0, sCallerName, sCallerName, None]); return oRc;
def rollback(self): """ Wrapper around Psycopg2.connection.rollback.""" nsStart = utils.timestampNano(); oRc = self._oConn.rollback(); cNsElapsed = utils.timestampNano() - nsStart; self._aoTraceBack.append([nsStart, 'ROLLBACK', cNsElapsed, 0, utils.getCallerName(), None]); self._endedTransaction(); return oRc;
def executeInternal(self, oCursor, sOperation, aoArgs, sCallerName): """ Execute a query or command. Mostly a wrapper around the psycopg2 cursor method with the same name, but collect data for traceback. """ if aoArgs is not None: sBound = oCursor.mogrify(unicode(sOperation), aoArgs); elif sOperation.find('%') < 0: sBound = oCursor.mogrify(unicode(sOperation), list()); else: sBound = unicode(sOperation); if sys.version_info[0] >= 3 and not isinstance(sBound, str): sBound = sBound.decode('utf-8'); aasExplain = None; if self._oExplainCursor is not None and not sBound.startswith('DROP'): try: if config.g_kfWebUiSqlTraceExplainTiming: self._oExplainCursor.execute('EXPLAIN (ANALYZE, BUFFERS, COSTS, VERBOSE, TIMING) ' + sBound); else: self._oExplainCursor.execute('EXPLAIN (ANALYZE, BUFFERS, COSTS, VERBOSE) ' + sBound); except Exception as oXcpt: aasExplain = [ ['Explain exception: '], [str(oXcpt)]]; try: self._oExplainConn.rollback(); except: pass; else: aasExplain = self._oExplainCursor.fetchall(); nsStart = utils.timestampNano(); try: oRc = oCursor.execute(sBound); except Exception as oXcpt: cNsElapsed = utils.timestampNano() - nsStart; self._aoTraceBack.append([nsStart, 'oXcpt=%s; Statement: %s' % (oXcpt, sBound), cNsElapsed, 0, sCallerName, None]); if self._fnDPrint is not None: self._fnDPrint('db::execute %u ns, caller %s: oXcpt=%s; Statement: %s' % (cNsElapsed, sCallerName, oXcpt, sBound)); raise; cNsElapsed = utils.timestampNano() - nsStart; if self._fTransaction is False and not self.isAutoCommitting(): # Even SELECTs starts transactions with psycopg2, see FAQ. self._aoTraceBack.append([nsStart, '[START TRANSACTION]', 0, 0, sCallerName, None]); self._startedTransaction(); self._aoTraceBack.append([nsStart, sBound, cNsElapsed, oCursor.rowcount, sCallerName, aasExplain]); if self._fnDPrint is not None: self._fnDPrint('db::execute %u ns, caller %s: "\n%s"' % (cNsElapsed, sCallerName, sBound)); if self.isAutoCommitting(): self._aoTraceBack.append([nsStart, '[AUTO COMMIT]', 0, 0, sCallerName, None]); return oRc;
def commit(self, sCallerName = None): """ Wrapper around Psycopg2.connection.commit.""" assert self._fTransaction is True; nsStart = utils.timestampNano(); oRc = self._oConn.commit(); cNsElapsed = utils.timestampNano() - nsStart; if sCallerName is None: sCallerName = utils.getCallerName(); self._aoTraceBack.append([nsStart, 'COMMIT', cNsElapsed, 0, sCallerName, None]); self._endedTransaction(); return oRc;
def commit(self, sCallerName=None): """ Wrapper around Psycopg2.connection.commit.""" assert self._fTransaction is True nsStart = utils.timestampNano() oRc = self._oConn.commit() cNsElapsed = utils.timestampNano() - nsStart if sCallerName is None: sCallerName = utils.getCallerName() self._aoTraceBack.append( [nsStart, 'COMMIT', cNsElapsed, 0, sCallerName, None]) self._endedTransaction() return oRc
def executeInternal(self, oCursor, sOperation, aoArgs, sCallerName): """ Execute a query or command. Mostly a wrapper around the psycopg2 cursor method with the same name, but collect data for traceback. """ if aoArgs is None: aoArgs = list(); sBound = oCursor.mogrify(unicode(sOperation), aoArgs); if sys.version_info[0] >= 3 and not isinstance(sBound, str): sBound = sBound.decode('utf-8'); aasExplain = None; if self._oExplainCursor is not None: try: if config.g_kfWebUiSqlTraceExplainTiming: self._oExplainCursor.execute('EXPLAIN (ANALYZE, BUFFERS, COSTS, VERBOSE, TIMING) ' + sBound); else: self._oExplainCursor.execute('EXPLAIN (ANALYZE, BUFFERS, COSTS, VERBOSE) ' + sBound); except Exception as oXcpt: aasExplain = [ ['Explain exception: '], [str(oXcpt)]]; try: self._oExplainConn.rollback(); except: pass; else: aasExplain = self._oExplainCursor.fetchall(); nsStart = utils.timestampNano(); try: oRc = oCursor.execute(sBound); except Exception as oXcpt: cNsElapsed = utils.timestampNano() - nsStart; self._aoTraceBack.append([nsStart, 'oXcpt=%s; Statement: %s' % (oXcpt, sBound), cNsElapsed, 0, sCallerName, None]); if self._fnDPrint is not None: self._fnDPrint('db::execute %u ns, caller %s: oXcpt=%s; Statement: %s' % (cNsElapsed, sCallerName, oXcpt, sBound)); raise; cNsElapsed = utils.timestampNano() - nsStart; if self._fTransaction is False and not self.isAutoCommitting(): # Even SELECTs starts transactions with psycopg2, see FAQ. self._aoTraceBack.append([nsStart, '[START TRANSACTION]', 0, 0, sCallerName, None]); self._startedTransaction(); self._aoTraceBack.append([nsStart, sBound, cNsElapsed, oCursor.rowcount, sCallerName, aasExplain]); if self._fnDPrint is not None: self._fnDPrint('db::execute %u ns, caller %s: "\n%s"' % (cNsElapsed, sCallerName, sBound)); if self.isAutoCommitting(): self._aoTraceBack.append([nsStart, '[AUTO COMMIT]', 0, 0, sCallerName, None]); return oRc;
def __init__(self, sValidationKitDir, fHtmlDebugOutput=True): self._sValidationKitDir = sValidationKitDir # Debug self.tsStart = utils.timestampNano() self._fHtmlDebugOutput = fHtmlDebugOutput # For trace self._oDbgFile = sys.stderr if config.g_ksSrcGlueDebugLogDst is not None and config.g_kfSrvGlueDebug is True: self._oDbgFile = open(config.g_ksSrcGlueDebugLogDst, 'a') self._afnDebugInfo = [] # HTTP header. self._fHeaderWrittenOut = False self._dHeaderFields = \ { \ 'Content-Type': 'text/html; charset=utf-8', } # Body. self._sBodyType = None self._dParams = dict() self._sHtmlBody = '' self._cchCached = 0 self._cchBodyWrittenOut = 0 # Output. self.oOutputRaw = sys.stdout self.oOutputText = codecs.getwriter('utf-8')(sys.stdout)
def __init__(self, sValidationKitDir, fHtmlDebugOutput = True): self._sValidationKitDir = sValidationKitDir; # Debug self.tsStart = utils.timestampNano(); self._fHtmlDebugOutput = fHtmlDebugOutput; # For trace self._oDbgFile = sys.stderr; if config.g_ksSrcGlueDebugLogDst is not None and config.g_kfSrvGlueDebug is True: self._oDbgFile = open(config.g_ksSrcGlueDebugLogDst, 'a'); self._afnDebugInfo = []; # HTTP header. self._fHeaderWrittenOut = False; self._dHeaderFields = \ { \ 'Content-Type': 'text/html; charset=utf-8', }; # Body. self._sBodyType = None; self._dParams = dict(); self._sHtmlBody = ''; self._cchCached = 0; self._cchBodyWrittenOut = 0; # Output. self.oOutputRaw = sys.stdout; self.oOutputText = codecs.getwriter('utf-8')(sys.stdout);
def __init__(self, sValidationKitDir, fHtmlDebugOutput = True): self._sValidationKitDir = sValidationKitDir; # Debug self.tsStart = utils.timestampNano(); self._fHtmlDebugOutput = fHtmlDebugOutput; # For trace self._oDbgFile = sys.stderr; if config.g_ksSrcGlueDebugLogDst is not None and config.g_kfSrvGlueDebug is True: self._oDbgFile = open(config.g_ksSrcGlueDebugLogDst, 'a'); self._afnDebugInfo = []; # HTTP header. self._fHeaderWrittenOut = False; self._dHeaderFields = \ { \ 'Content-Type': 'text/html; charset=utf-8', }; # Body. self._sBodyType = None; self._dParams = dict(); self._sHtmlBody = ''; self._cchCached = 0; self._cchBodyWrittenOut = 0; # Output. if sys.version_info[0] >= 3: self.oOutputRaw = sys.stdout.detach(); # pylint: disable=no-member sys.stdout = None; # Prevents flush_std_files() from complaining on stderr during sys.exit(). else: self.oOutputRaw = sys.stdout; self.oOutputText = codecs.getwriter('utf-8')(self.oOutputRaw);
def callProcInternal(self, oCursor, sProcedure, aoArgs, sCallerName): """ Call a stored procedure. Mostly a wrapper around the psycopg2 cursor method 'callproc', but collect data for traceback. """ if aoArgs is None: aoArgs = list() nsStart = utils.timestampNano() try: oRc = oCursor.callproc(sProcedure, aoArgs) except Exception as oXcpt: cNsElapsed = utils.timestampNano() - nsStart self._aoTraceBack.append([ nsStart, 'oXcpt=%s; Calling: %s(%s)' % (oXcpt, sProcedure, aoArgs), cNsElapsed, 0, sCallerName, None ]) if self._fnDPrint is not None: self._fnDPrint( 'db::callproc %u ns, caller %s: oXcpt=%s; Calling: %s(%s)' % (cNsElapsed, sCallerName, oXcpt, sProcedure, aoArgs)) raise cNsElapsed = utils.timestampNano() - nsStart if self._fTransaction is False and not self.isAutoCommitting( ): # Even SELECTs starts transactions with psycopg2, see FAQ. self._aoTraceBack.append( [nsStart, '[START TRANSACTION]', 0, 0, sCallerName, None]) self._startedTransaction() self._aoTraceBack.append([ nsStart, '%s(%s)' % (sProcedure, aoArgs), cNsElapsed, oCursor.rowcount, sCallerName, None ]) if self._fnDPrint is not None: self._fnDPrint('db::callproc %u ns, caller %s: "%s(%s)"' % (cNsElapsed, sCallerName, sProcedure, aoArgs)) if self.isAutoCommitting(): self._aoTraceBack.append([ nsStart, '[AUTO COMMIT]', 0, 0, sCallerName, sCallerName, None ]) return oRc
def begin(self): """ Currently just for marking where a transaction starts in the code. """ assert self._oConn is not None; assert self.isAutoCommitting() is False; self._aoTraceBack.append([utils.timestampNano(), 'START TRANSACTION', 0, 0, utils.getCallerName(), None]); self._startedTransaction(); return True;
def __init__(self, sValidationKitDir, fHtmlDebugOutput=True): self._sValidationKitDir = sValidationKitDir # Debug self.tsStart = utils.timestampNano() self._fHtmlDebugOutput = fHtmlDebugOutput # For trace self._oDbgFile = sys.stderr if config.g_ksSrvGlueDebugLogDst is not None and config.g_kfSrvGlueDebug is True: self._oDbgFile = open(config.g_ksSrvGlueDebugLogDst, 'a') # pylint: disable=consider-using-with if config.g_kfSrvGlueCgiDumpArgs: self._oDbgFile.write('Arguments: %s\nEnvironment:\n' % (sys.argv, )) if config.g_kfSrvGlueCgiDumpEnv: for sVar in sorted(os.environ): self._oDbgFile.write(' %s=\'%s\' \\\n' % ( sVar, os.environ[sVar], )) self._afnDebugInfo = [] # HTTP header. self._fHeaderWrittenOut = False self._dHeaderFields = \ { \ 'Content-Type': 'text/html; charset=utf-8', } # Body. self._sBodyType = None self._dParams = dict() self._sHtmlBody = '' self._cchCached = 0 self._cchBodyWrittenOut = 0 # Output. if sys.version_info[0] >= 3: self.oOutputRaw = sys.stdout.detach() # pylint: disable=no-member sys.stdout = None # Prevents flush_std_files() from complaining on stderr during sys.exit(). else: self.oOutputRaw = sys.stdout self.oOutputText = codecs.getwriter('utf-8')(self.oOutputRaw)
def _generatePage(self): """ Generates the page using _sTemplate, _sPageTitle, _aaoMenus, and _sPageBody. """ assert self._sRedirectTo is None; # # Build the replacement string dictionary. # # Provide basic auth log out for browsers that supports it. sUserAgent = self._oSrvGlue.getUserAgent(); if (sUserAgent.startswith('Mozilla/') and sUserAgent.find('Firefox') > 0) \ or False: # Log in as the logout user in the same realm, the browser forgets # the old login and the job is done. (see apache sample conf) sLogOut = ' (<a href="%s://logout:logout@%s%slogout.py">logout</a>)' \ % (self._oSrvGlue.getUrlScheme(), self._oSrvGlue.getUrlNetLoc(), self._oSrvGlue.getUrlBasePath()); elif (sUserAgent.startswith('Mozilla/') and sUserAgent.find('Safari') > 0) \ or False: # For a 401, causing the browser to forget the old login. Works # with safari as well as the two above. Since safari consider the # above method a phishing attempt and displays a warning to that # effect, which when taken seriously aborts the logout, this method # is preferable, even if it throws logon boxes in the user's face # till he/she/it hits escape, because it always works. sLogOut = ' (<a href="logout2.py">logout</a>)' elif (sUserAgent.startswith('Mozilla/') and sUserAgent.find('MSIE') > 0) \ or (sUserAgent.startswith('Mozilla/') and sUserAgent.find('Chrome') > 0) \ or False: ## There doesn't seem to be any way to make IE really log out # without using a cookie and systematically 401 accesses based on # some logout state associated with it. Not sure how secure that # can be made and we really want to avoid cookies. So, perhaps, # just avoid IE for now. :-) ## Chrome/21.0 doesn't want to log out either. sLogOut = '' else: sLogOut = '' # Prep Menus. (sTopMenuItems, sSideMenuItems) = self._generateMenus(); # The dictionary (max variable length is 28 chars (see further down)). dReplacements = { '@@PAGE_TITLE@@': self._sPageTitle, '@@LOG_OUT@@': sLogOut, '@@TESTMANAGER_VERSION@@': config.g_ksVersion, '@@TESTMANAGER_REVISION@@': config.g_ksRevision, '@@BASE_URL@@': self._oSrvGlue.getBaseUrl(), '@@TOP_MENU_ITEMS@@': sTopMenuItems, '@@SIDE_MENU_ITEMS@@': sSideMenuItems, '@@SIDE_FILTER_CONTROL@@': self._sPageFilter, '@@SIDE_MENU_FORM_ATTRS@@': '', '@@PAGE_BODY@@': self._sPageBody, '@@DEBUG@@': '', }; # Side menu form attributes. if self._dSideMenuFormAttrs: dReplacements['@@SIDE_MENU_FORM_ATTRS@@'] = ' '.join(['%s="%s"' % (sKey, webutils.escapeAttr(sValue)) for sKey, sValue in self._dSideMenuFormAttrs.items()]); # Special current user handling. if self._oCurUser is not None: dReplacements['@@USER_NAME@@'] = self._oCurUser.sUsername; else: dReplacements['@@USER_NAME@@'] = 'unauthorized user "' + self._oSrvGlue.getLoginName() + '"'; # Prep debug section. if self._sDebug == '': if config.g_kfWebUiSqlTrace or self._fDbgSqlTrace or self._fDbgSqlExplain: self._sDebug = '<h3>Processed in %s ns.</h3>\n%s\n' \ % ( utils.formatNumber(utils.timestampNano() - self._oSrvGlue.tsStart,), self._oDb.debugHtmlReport(self._oSrvGlue.tsStart)); elif config.g_kfWebUiProcessedIn: self._sDebug = '<h3>Processed in %s ns.</h3>\n' \ % ( utils.formatNumber(utils.timestampNano() - self._oSrvGlue.tsStart,), ); if config.g_kfWebUiDebugPanel: self._sDebug += self._debugRenderPanel(); if self._sDebug != '': dReplacements['@@DEBUG@@'] = u'<div id="debug"><br><br><hr/>' \ + (utils.toUnicode(self._sDebug, errors='ignore') if isinstance(self._sDebug, str) else self._sDebug) \ + u'</div>\n'; # # Load the template. # oFile = open(os.path.join(self._oSrvGlue.pathTmWebUI(), self._sTemplate)); sTmpl = oFile.read(); oFile.close(); # # Process the template, outputting each part we process. # offStart = 0; offCur = 0; while offCur < len(sTmpl): # Look for a replacement variable. offAtAt = sTmpl.find('@@', offCur); if offAtAt < 0: break; offCur = offAtAt + 2; if sTmpl[offCur] not in string.ascii_uppercase: continue; offEnd = sTmpl.find('@@', offCur, offCur+28); if offEnd <= 0: continue; offCur = offEnd; sReplacement = sTmpl[offAtAt:offEnd+2]; if sReplacement in dReplacements: # Got a match! Write out the previous chunk followed by the replacement text. if offStart < offAtAt: self._oSrvGlue.write(sTmpl[offStart:offAtAt]); self._oSrvGlue.write(dReplacements[sReplacement]); # Advance past the replacement point in the template. offCur += 2; offStart = offCur; else: assert False, 'Unknown replacement "%s" at offset %s in %s' % (sReplacement, offAtAt, self._sTemplate ); # The final chunk. if offStart < len(sTmpl): self._oSrvGlue.write(sTmpl[offStart:]); return True;
def _generatePage(self): """ Generates the page using _sTemplate, _sPageTitle, _aaoMenus, and _sPageBody. """ assert self._sRedirectTo is None; # # Build the replacement string dictionary. # # Provide basic auth log out for browsers that supports it. sUserAgent = self._oSrvGlue.getUserAgent(); if (sUserAgent.startswith('Mozilla/') and sUserAgent.find('Firefox') > 0) \ or False: # Log in as the logout user in the same realm, the browser forgets # the old login and the job is done. (see apache sample conf) sLogOut = ' (<a href="%s://logout:logout@%s%slogout.py">logout</a>)' \ % (self._oSrvGlue.getUrlScheme(), self._oSrvGlue.getUrlNetLoc(), self._oSrvGlue.getUrlBasePath()); elif (sUserAgent.startswith('Mozilla/') and sUserAgent.find('Safari') > 0) \ or False: # For a 401, causing the browser to forget the old login. Works # with safari as well as the two above. Since safari consider the # above method a phishing attempt and displays a warning to that # effect, which when taken seriously aborts the logout, this method # is preferable, even if it throws logon boxes in the user's face # till he/she/it hits escape, because it always works. sLogOut = ' (<a href="logout2.py">logout</a>)' elif (sUserAgent.startswith('Mozilla/') and sUserAgent.find('MSIE') > 0) \ or (sUserAgent.startswith('Mozilla/') and sUserAgent.find('Chrome') > 0) \ or False: ## There doesn't seem to be any way to make IE really log out # without using a cookie and systematically 401 accesses based on # some logout state associated with it. Not sure how secure that # can be made and we really want to avoid cookies. So, perhaps, # just avoid IE for now. :-) ## Chrome/21.0 doesn't want to log out either. sLogOut = '' else: sLogOut = '' # Prep Menus. (sTopMenuItems, sSideMenuItems) = self._generateMenus(); # The dictionary (max variable length is 28 chars (see further down)). dReplacements = { '@@PAGE_TITLE@@': self._sPageTitle, '@@LOG_OUT@@': sLogOut, '@@TESTMANAGER_VERSION@@': config.g_ksVersion, '@@TESTMANAGER_REVISION@@': config.g_ksRevision, '@@BASE_URL@@': self._oSrvGlue.getBaseUrl(), '@@TOP_MENU_ITEMS@@': sTopMenuItems, '@@SIDE_MENU_ITEMS@@': sSideMenuItems, '@@SIDE_FILTER_CONTROL@@': self._sPageFilter, '@@PAGE_BODY@@': self._sPageBody, '@@DEBUG@@': '', }; # Special current user handling. if self._oCurUser is not None: dReplacements['@@USER_NAME@@'] = self._oCurUser.sUsername; else: dReplacements['@@USER_NAME@@'] = 'unauthorized user "' + self._oSrvGlue.getLoginName() + '"'; # Prep debug section. if self._sDebug == '': if config.g_kfWebUiSqlTrace or self._fDbgSqlTrace or self._fDbgSqlExplain: self._sDebug = '<h3>Processed in %s ns.</h3>\n%s\n' \ % ( utils.formatNumber(utils.timestampNano() - self._oSrvGlue.tsStart,), self._oDb.debugHtmlReport(self._oSrvGlue.tsStart)); elif config.g_kfWebUiProcessedIn: self._sDebug = '<h3>Processed in %s ns.</h3>\n' \ % ( utils.formatNumber(utils.timestampNano() - self._oSrvGlue.tsStart,), ); if config.g_kfWebUiDebugPanel: self._sDebug += self._debugRenderPanel(); if self._sDebug != '': dReplacements['@@DEBUG@@'] = '<div id="debug"><br><br><hr/>' + \ unicode(self._sDebug, errors='ignore') if isinstance(self._sDebug, str) else self._sDebug + '</div>'; # # Load the template. # oFile = open(os.path.join(self._oSrvGlue.pathTmWebUI(), self._sTemplate)); sTmpl = oFile.read(); oFile.close(); # # Process the template, outputting each part we process. # offStart = 0; offCur = 0; while offCur < len(sTmpl): # Look for a replacement variable. offAtAt = sTmpl.find('@@', offCur); if offAtAt < 0: break; offCur = offAtAt + 2; if sTmpl[offCur] not in string.ascii_uppercase: continue; offEnd = sTmpl.find('@@', offCur, offCur+28); if offEnd <= 0: continue; offCur = offEnd; sReplacement = sTmpl[offAtAt:offEnd+2]; if sReplacement in dReplacements: # Got a match! Write out the previous chunk followed by the replacement text. if offStart < offAtAt: self._oSrvGlue.write(sTmpl[offStart:offAtAt]); self._oSrvGlue.write(dReplacements[sReplacement]); # Advance past the replacement point in the template. offCur += 2; offStart = offCur; else: assert False, 'Unknown replacement "%s" at offset %s in %s' % (sReplacement, offAtAt, self._sTemplate ); # The final chunk. if offStart < offCur: self._oSrvGlue.write(sTmpl[offStart:]); return True;
def _generatePage(self): """ Generates the page using _sTemplate, _sPageTitle, _aaoMenus, and _sPageBody. """ assert self._sRedirectTo is None; # Load the template. oFile = open(os.path.join(self._oSrvGlue.pathTmWebUI(), self._sTemplate)); sTmpl = oFile.read(); oFile.close(); # Do replacements. sTmpl = sTmpl.replace('@@PAGE_TITLE@@', self._sPageTitle); sTmpl = sTmpl.replace('@@PAGE_BODY@@', self._sPageBody); if self._oCurUser is not None: sTmpl = sTmpl.replace('@@USER_NAME@@', self._oCurUser.sUsername); else: sTmpl = sTmpl.replace('@@USER_NAME@@', 'unauthorized user "' + self._oSrvGlue.getLoginName() + '"'); sTmpl = sTmpl.replace('@@TESTMANAGER_VERSION@@', config.g_ksVersion); sTmpl = sTmpl.replace('@@TESTMANAGER_REVISION@@', config.g_ksRevision); sTmpl = sTmpl.replace('@@BASE_URL@@', self._oSrvGlue.getBaseUrl()); (sTopMenuItems, sSideMenuItems) = self._generateMenus(); sTmpl = sTmpl.replace('@@TOP_MENU_ITEMS@@', sTopMenuItems); sTmpl = sTmpl.replace('@@SIDE_MENU_ITEMS@@', sSideMenuItems); # Provide basic auth log out for browsers that supports it. sUserAgent = self._oSrvGlue.getUserAgent(); if (sUserAgent.startswith('Mozilla/') and sUserAgent.find('Firefox') > 0) \ or False: # Log in as the logout user in the same realm, the browser forgets # the old login and the job is done. (see apache sample conf) sLogOut = ' (<a href="%s://logout:logout@%s%slogout.py">logout</a>)' \ % (self._oSrvGlue.getUrlScheme(), self._oSrvGlue.getUrlNetLoc(), self._oSrvGlue.getUrlBasePath()); elif (sUserAgent.startswith('Mozilla/') and sUserAgent.find('Safari') > 0) \ or False: # For a 401, causing the browser to forget the old login. Works # with safari as well as the two above. Since safari consider the # above method a phishing attempt and displays a warning to that # effect, which when taken seriously aborts the logout, this method # is preferable, even if it throws logon boxes in the user's face # till he/she/it hits escape, because it always works. sLogOut = ' (<a href="logout2.py">logout</a>)' elif (sUserAgent.startswith('Mozilla/') and sUserAgent.find('MSIE') > 0) \ or (sUserAgent.startswith('Mozilla/') and sUserAgent.find('Chrome') > 0) \ or False: ## There doesn't seem to be any way to make IE really log out # without using a cookie and systematically 401 accesses based on # some logout state associated with it. Not sure how secure that # can be made and we really want to avoid cookies. So, perhaps, # just avoid IE for now. :-) ## Chrome/21.0 doesn't want to log out either. sLogOut = '' else: sLogOut = '' sTmpl = sTmpl.replace('@@LOG_OUT@@', sLogOut) # Debug section. if self._sDebug == '': if config.g_kfWebUiSqlTrace or self._fDbgSqlTrace or self._fDbgSqlExplain: self._sDebug = '<h3>Processed in %s ns.</h3>\n%s\n' \ % ( utils.formatNumber(utils.timestampNano() - self._oSrvGlue.tsStart,), self._oDb.debugHtmlReport(self._oSrvGlue.tsStart)); elif config.g_kfWebUiProcessedIn: self._sDebug = '<h3>Processed in %s ns.</h3>\n' \ % ( utils.formatNumber(utils.timestampNano() - self._oSrvGlue.tsStart,), ); if config.g_kfWebUiDebugPanel: self._sDebug += self._debugRenderPanel(); if self._sDebug != '': sTmpl = sTmpl.replace('@@DEBUG@@', '<div id="debug"><br><br><hr/>' + \ unicode(self._sDebug, errors='ignore') if isinstance(self._sDebug, str) else self._sDebug + '</div>'); else: sTmpl = sTmpl.replace('@@DEBUG@@', ''); # Output the result. self._oSrvGlue.write(sTmpl); return True;
def _generatePage(self): """ Generates the page using _sTemplate, _sPageTitle, _aaoMenus, and _sPageBody. """ assert self._sRedirectTo is None # Load the template. oFile = open( os.path.join(self._oSrvGlue.pathTmWebUI(), self._sTemplate)) sTmpl = oFile.read() oFile.close() # Do replacements. sTmpl = sTmpl.replace('@@PAGE_TITLE@@', self._sPageTitle) sTmpl = sTmpl.replace('@@PAGE_BODY@@', self._sPageBody) if self._oCurUser is not None: sTmpl = sTmpl.replace('@@USER_NAME@@', self._oCurUser.sUsername) else: sTmpl = sTmpl.replace( '@@USER_NAME@@', 'unauthorized user "' + self._oSrvGlue.getLoginName() + '"') sTmpl = sTmpl.replace('@@TESTMANAGER_VERSION@@', config.g_ksVersion) sTmpl = sTmpl.replace('@@TESTMANAGER_REVISION@@', config.g_ksRevision) sTmpl = sTmpl.replace('@@BASE_URL@@', self._oSrvGlue.getBaseUrl()) (sTopMenuItems, sSideMenuItems) = self._generateMenus() sTmpl = sTmpl.replace('@@TOP_MENU_ITEMS@@', sTopMenuItems) sTmpl = sTmpl.replace('@@SIDE_MENU_ITEMS@@', sSideMenuItems) # Provide basic auth log out for browsers that supports it. sUserAgent = self._oSrvGlue.getUserAgent() if (sUserAgent.startswith('Mozilla/') and sUserAgent.find('Firefox') > 0) \ or False: # Log in as the logout user in the same realm, the browser forgets # the old login and the job is done. (see apache sample conf) sLogOut = ' (<a href="%s://logout:logout@%s%slogout.py">logout</a>)' \ % (self._oSrvGlue.getUrlScheme(), self._oSrvGlue.getUrlNetLoc(), self._oSrvGlue.getUrlBasePath()) elif (sUserAgent.startswith('Mozilla/') and sUserAgent.find('Safari') > 0) \ or False: # For a 401, causing the browser to forget the old login. Works # with safari as well as the two above. Since safari consider the # above method a phishing attempt and displays a warning to that # effect, which when taken seriously aborts the logout, this method # is preferable, even if it throws logon boxes in the user's face # till he/she/it hits escape, because it always works. sLogOut = ' (<a href="logout2.py">logout</a>)' elif (sUserAgent.startswith('Mozilla/') and sUserAgent.find('MSIE') > 0) \ or (sUserAgent.startswith('Mozilla/') and sUserAgent.find('Chrome') > 0) \ or False: ## There doesn't seem to be any way to make IE really log out # without using a cookie and systematically 401 accesses based on # some logout state associated with it. Not sure how secure that # can be made and we really want to avoid cookies. So, perhaps, # just avoid IE for now. :-) ## Chrome/21.0 doesn't want to log out either. sLogOut = '' else: sLogOut = '' sTmpl = sTmpl.replace('@@LOG_OUT@@', sLogOut) # Debug section. if self._sDebug == '': if config.g_kfWebUiSqlTrace or self._fDbgSqlTrace or self._fDbgSqlExplain: self._sDebug = '<h3>Processed in %s ns.</h3>\n%s\n' \ % ( utils.formatNumber(utils.timestampNano() - self._oSrvGlue.tsStart,), self._oDb.debugHtmlReport(self._oSrvGlue.tsStart)) elif config.g_kfWebUiProcessedIn: self._sDebug = '<h3>Processed in %s ns.</h3>\n' \ % ( utils.formatNumber(utils.timestampNano() - self._oSrvGlue.tsStart,), ) if config.g_kfWebUiDebugPanel: self._sDebug += self._debugRenderPanel() if self._sDebug != '': sTmpl = sTmpl.replace('@@DEBUG@@', '<div id="debug"><br><br><hr/>' + \ unicode(self._sDebug, errors='ignore') if isinstance(self._sDebug, str) else self._sDebug + '</div>') else: sTmpl = sTmpl.replace('@@DEBUG@@', '') # Output the result. self._oSrvGlue.write(sTmpl) return True