cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync# -*- coding: utf-8 -*-
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncTest Manager Web-UI - Base Classes.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncCopyright (C) 2012-2014 Oracle Corporation
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncThis file is part of VirtualBox Open Source Edition (OSE), as
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncavailable from http://www.virtualbox.org. This file is free software;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncyou can redistribute it and/or modify it under the terms of the GNU
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncGeneral Public License (GPL) as published by the Free Software
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncFoundation, in version 2 as it comes in the "COPYING" file of the
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncVirtualBox OSE distribution. VirtualBox OSE is distributed in the
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsynchope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncThe contents of this file may alternatively be used under the terms
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncof the Common Development and Distribution License Version 1.0
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync(CDDL) only, as it comes in the "COPYING.CDDL" file of the
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncVirtualBox OSE distribution, in which case the provisions of the
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncCDDL are applicable instead of those of the GPL.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncYou may elect to license modified versions of this file under the
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncterms and conditions of either the GPL or the CDDL or both.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync# Standard python imports.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync# Validation Kit imports.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncfrom testmanager.core.base import ModelDataBase, TMExceptionBase;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncfrom testmanager.core.db import TMDatabaseConnection;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncfrom testmanager.core.systemlog import SystemLogLogic, SystemLogData;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncfrom testmanager.core.useraccount import UserAccountLogic
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync For exceptions raised by Web UI code.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Base class for the Web User Interface (WUI) dispatchers.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync The dispatcher class defines the basics of the page (like base template,
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync menu items, action). It is also responsible for parsing requests and
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync dispatching them to action (POST) or/and content generators (GET+POST).
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync The content returned by the generator is merged into the template and sent
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync back to the webserver glue.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ## @todo possible that this should all go into presentation.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ## The action parameter.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ## The name of the default action.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ## The name of the current page number parameter used when displaying lists.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ## The name of the page length (list items) parameter when displaying lists.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ## The name of the effective date (timestamp) parameter.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ## The name of the list-action parameter (WuiListContentWithActionBase).
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ## The name of the change log enabled/disabled parameter.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ## The name of the parmaeter indicating the change log page number.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ## The name of the parameter indicate number of change log entries per page.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ksParamChangeLogEntriesPerPage = 'ChangeLogEntriesPerPage';
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ## @name Dispatcher debugging parameters.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ## List of all debugging parameters.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync kasDbgParams = (ksParamDbgSqlTrace, ksParamDbgSqlExplain,);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ## Special action return code for skipping _generatePage. Useful for
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # download pages and the like that messes with the HTTP header and more.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ksDispatchRcAllDone = 'Done - Page has been rendered already';
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self._oDb = TMDatabaseConnection(self.dprint if config.g_kfWebUiSqlDebug else None, oSrvGlue = oSrvGlue);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self._dDispatch = { self.ksActionDefault: self._actionDefault, };
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # Template bits.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self._aaoMenus = []; # List of [sName, sLink, [ [sSideName, sLink], .. ] tuples.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # Debugger bits.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync for sKey, sValue in oSrvGlue.getParameters().iteritems():
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync from testmanager.webui.wuicontentbase import WuiTmLink;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # Determine currently logged in user credentials
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self._oCurUser = UserAccountLogic(self._oDb).tryFetchAccountByLoginName(oSrvGlue.getLoginName());
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # Calc a couple of URL base strings for this dispatcher.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self._sUrlBase += webutils.encodeUrlParams(self._dDbgParams) + '&';
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self._sActionUrlBase = self._sUrlBase + self.ksParamAction + '=';
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Redirects the page to the URL given in self._sRedirectTo.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Generates the two menus, returning them as (sTopMenuItems, sSideMenuItems).
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # We use the action to locate the side menu.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync sActionParam = '%s=%s' % (self.ksParamAction, self._sAction[:cchAction]);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if aasSideMenu is not None:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # Top menu first.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync sTopMenuItems += '<a href="' + webutils.escapeAttr(aoItem[1]) + '">' \
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # Side menu (if found).
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync sActionParam = '%s=%s' % (self.ksParamAction, self._sAction);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if aasSideMenu is not None:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync sSideMenuItems += '<li class="current_page_item">';
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync sSideMenuItems += '<a href="' + webutils.escapeAttr(asSubItem[1]) + '">' \
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync + webutils.escapeElem(asSubItem[0]) + '</a></li>\n';
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Generates the page using _sTemplate, _sPageTitle, _aaoMenus, and _sPageBody.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # Load the template.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync oFile = open(os.path.join(self._oSrvGlue.pathTmWebUI(), self._sTemplate));
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # Do replacements.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync sTmpl = sTmpl.replace('@@PAGE_TITLE@@', self._sPageTitle);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync sTmpl = sTmpl.replace('@@PAGE_BODY@@', self._sPageBody);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync sTmpl = sTmpl.replace('@@USER_NAME@@', self._oCurUser.sUsername);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync sTmpl = sTmpl.replace('@@USER_NAME@@', 'unauthorized user "' + self._oSrvGlue.getLoginName() + '"');
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync sTmpl = sTmpl.replace('@@TESTMANAGER_VERSION@@', config.g_ksVersion);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync sTmpl = sTmpl.replace('@@TESTMANAGER_REVISION@@', config.g_ksRevision);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync sTmpl = sTmpl.replace('@@BASE_URL@@', self._oSrvGlue.getBaseUrl());
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync (sTopMenuItems, sSideMenuItems) = self._generateMenus();
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync sTmpl = sTmpl.replace('@@TOP_MENU_ITEMS@@', sTopMenuItems);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync sTmpl = sTmpl.replace('@@SIDE_MENU_ITEMS@@', sSideMenuItems);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # Provide basic auth log out for browsers that supports it.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if (sUserAgent.startswith('Mozilla/') and sUserAgent.find('Firefox') > 0) \
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # Log in as the logout user in the same realm, the browser forgets
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # the old login and the job is done. (see apache sample conf)
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync sLogOut = ' (<a href="%s://logout:logout@%s%slogout.py">logout</a>)' \
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync % (self._oSrvGlue.getUrlScheme(), self._oSrvGlue.getUrlNetLoc(), self._oSrvGlue.getUrlBasePath());
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync elif (sUserAgent.startswith('Mozilla/') and sUserAgent.find('Safari') > 0) \
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # For a 401, causing the browser to forget the old login. Works
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # with safari as well as the two above. Since safari consider the
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # above method a phishing attempt and displays a warning to that
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # effect, which when taken seriously aborts the logout, this method
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # is preferable, even if it throws logon boxes in the user's face
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # till he/she/it hits escape, because it always works.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync elif (sUserAgent.startswith('Mozilla/') and sUserAgent.find('MSIE') > 0) \
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync or (sUserAgent.startswith('Mozilla/') and sUserAgent.find('Chrome') > 0) \
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ## There doesn't seem to be any way to make IE really log out
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # without using a cookie and systematically 401 accesses based on
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # some logout state associated with it. Not sure how secure that
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # can be made and we really want to avoid cookies. So, perhaps,
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # just avoid IE for now. :-)
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ## Chrome/21.0 doesn't want to log out either.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # Debug section.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if config.g_kfWebUiSqlTrace or self._fDbgSqlTrace or self._fDbgSqlExplain:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self._sDebug = '<h3>Processed in %s ns.</h3>\n%s\n' \
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync % ( utils.formatNumber(utils.timestampNano() - self._oSrvGlue.tsStart,),
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self._oDb.debugHtmlReport(self._oSrvGlue.tsStart));
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync % ( utils.formatNumber(utils.timestampNano() - self._oSrvGlue.tsStart,), );
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync sTmpl = sTmpl.replace('@@DEBUG@@', '<div id="debug"><br><br><hr/>' + \
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync unicode(self._sDebug, errors='ignore') if isinstance(self._sDebug, str) else self._sDebug + '</div>');
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # Output the result.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # Interface for WuiContentBase classes.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Returns a (shallow) copy of the request parameter dictionary.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Returns the database connection.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # Parameter handling.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync def getStringParam(self, sName, asValidValues = None, sDefault = None):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Gets a string parameter.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Raises exception if not found and sDefault is None.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync raise WuiException('%s parameter "%s" is given multiple times: "%s"' % (self._sAction, sName, sValue));
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync elif sDefault is None:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync raise WuiException('%s is missing parameters: "%s"' % (self._sAction, sName,));
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if asValidValues is not None and sValue not in asValidValues:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync raise WuiException('%s parameter %s value "%s" not in %s '
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Gets a boolean parameter.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Raises exception if not found and fDefault is None, or if not a valid boolean.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync sValue = self.getStringParam(sName, [ 'True', 'true', '1', 'False', 'false', '0'],
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # HACK: Checkboxes doesn't return a value when unchecked, so we always
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # provide a default when dealing with boolean parameters.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return sValue == 'True' or sValue == 'true' or sValue == '1';
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync def getIntParam(self, sName, iMin = None, iMax = None, iDefault = None):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Gets a integer parameter.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Raises exception if not found and iDefault is None, if not a valid int,
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync or if outside the range defined by iMin and iMax.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if iDefault is not None and sName not in self._dParams:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync sValue = self.getStringParam(sName, None, None if iDefault is None else str(iDefault));
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync raise WuiException('%s parameter %s value "%s" cannot be convert to an integer'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync raise WuiException('%s parameter %s value %d is out of range [%s..%s]'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync def getLongParam(self, sName, lMin = None, lMax = None, lDefault = None):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Gets a long integer parameter.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Raises exception if not found and lDefault is None, if not a valid long,
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync or if outside the range defined by lMin and lMax.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if lDefault is not None and sName not in self._dParams:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync sValue = self.getStringParam(sName, None, None if lDefault is None else str(lDefault));
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync raise WuiException('%s parameter %s value "%s" cannot be convert to an integer'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync raise WuiException('%s parameter %s value %d is out of range [%s..%s]'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync def getTsParam(self, sName, tsDefault = None, fRequired = True):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Gets a timestamp parameter.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Raises exception if not found and fRequired is True.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if fRequired is False and sName not in self._dParams:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync sValue = self.getStringParam(sName, None, None if tsDefault is None else str(tsDefault));
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync (sValue, sError) = ModelDataBase.validateTs(sValue);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if sError is not None:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync raise WuiException('%s parameter %s value "%s": %s'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync def getListOfIntParams(self, sName, iMin = None, iMax = None, aiDefaults = None):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Gets parameter list.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Raises exception if not found and aiDefaults is None, or if any of the
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync values are not valid integers or outside the range defined by iMin and iMax.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync raise WuiException('%s parameter %s value "%s" cannot be convert to an integer'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync raise WuiException('%s parameter %s value %d is out of range [%s..%s]'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync def getListOfStrParams(self, sName, asDefaults = None):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Gets parameter list.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Raises exception if not found and asDefaults is None.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync asValues = [str(s).strip() for s in self._dParams[sName]];
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync elif asDefaults is None:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync raise WuiException('%s is missing parameters: "%s"' % (self._sAction, sName,));
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync def getListOfTestCasesParam(self, sName, asDefaults = None): # too many local vars - pylint: disable=R0914
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """Get list of test cases and their parameters"""
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync aiSelectedTestCaseIds = self.getListOfIntParams('%s[asCheckedTestCases]' % sName, aiDefaults=[])
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync aiAllTestCases = self.getListOfIntParams('%s[asAllTestCases]' % sName, aiDefaults=[])
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync '%s[%d][asCheckedTestCaseArgs]' % (sName, idTestCase),
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync fArgsChecked = True if idTestCaseArgs in aiCheckedTestCaseArgs else False
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync sPrefix = '%s[%d][%d]' % (sName, idTestCase, idTestCaseArgs,);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.getIntParam(sPrefix + '[idTestCaseArgs]', iDefault = -1,)
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync sArgs = self.getStringParam(sPrefix + '[sArgs]', sDefault = '')
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync cSecTimeout = self.getStringParam(sPrefix + '[cSecTimeout]', sDefault = '')
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync cGangMembers = self.getStringParam(sPrefix + '[cGangMembers]', sDefault = '')
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync cGangMembers = self.getStringParam(sPrefix + '[cGangMembers]', sDefault = '')
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync oListEntryTestCaseArgs.append((fArgsChecked, idTestCaseArgs, sArgs, cSecTimeout, cGangMembers))
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync sTestCaseName = self.getStringParam('%s[%d][sName]' % (sName, idTestCase), sDefault='')
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync True if idTestCase in aiSelectedTestCaseIds else False,
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync raise WuiException('%s is missing parameters: "%s"' % (self._sAction, sName))
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Gets the effective date parameter.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Returns a timestamp suitable for database and url parameters.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Returns None if not found or empty.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync sName = sParamName if sParamName is not None else WuiDispatcherBase.ksParamEffectiveDate
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return None;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync raise WuiException('%s parameter "%s" is given multiple times: %s' % (self._sAction, sName, sValue));
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return None;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # Timestamp, just validate it and return.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync (sValue, sError) = ModelDataBase.validateTs(sValue);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if sError is not None:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync raise WuiException('%s parameter "%s" ("%s") is invalid: %s' % (self._sAction, sName, sValue, sError));
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # Relative timestamp. Validate and convert it to a fixed timestamp.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync (sValue, sError) = ModelDataBase.validateTs(sValue[1:]);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if sError is not None:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync raise WuiException('%s parameter "%s" ("%s") is invalid: %s' % (self._sAction, sName, sValue, sError));
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync raise WuiException('%s parameter "%s" ("%s") is a relative timestamp but incorrectly includes a time zone.'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync raise WuiException('%s parameter "%s" ("%s") incorrect format.' % (self._sAction, sName, sValue));
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync sInterval = 'P' + sValue[:(offTime - 1)] + 'T' + sValue[offTime:];
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self._oDb.execute('SELECT CURRENT_TIMESTAMP ' + chSign + ' \'' + sInterval + '\'::INTERVAL');
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Check if we've handled all parameters, raises exception if anything
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync unknown was found.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if len(self._asCheckedParams) != len(self._dParams):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync sUnknownParams += ' ' + sKey + '=' + str(self._dParams[sKey]);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync raise WuiException('Unknown parameters: ' + sUnknownParams);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Makes sure that the request we're dispatching is a POST request.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Raises an exception of not.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync raise WuiException('Expected "POST" request, got "%s"' % (self._oSrvGlue.getMethod(),))
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # Client browser type.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ## @name Browser types.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ## @name Browser types.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ksBrowserType_Firefox = (1 << 8) | ksBrowserFamily_Gecko;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ksBrowserType_Chrome = (2 << 8) | ksBrowserFamily_Webkit;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ksBrowserType_Safari = (3 << 8) | ksBrowserFamily_Webkit;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ksBrowserType_IE = (4 << 8) | ksBrowserFamily_Trident;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Gets the browser type.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync The browser family can be extracted from this using ksBrowserType_FamilyMask.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return self.ksBrowserType_Unknown | self.ksBrowserFamily_Webkit;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return self.ksBrowserType_Unknown | self.ksBrowserFamily_Gecko;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return self.ksBrowserType_Unknown | self.ksBrowserFamily_Unknown;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """ Returns true if it's a gecko based browser. """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if (self.getBrowserType() & self.ksBrowserType_FamilyMask) != self.ksBrowserFamily_Gecko:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if sMinVersion is not None:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync sVersion = sAgent[sAgent.find('Gecko/')+6:].split()[0];
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # Debugging
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Processes any debugging parameters in the request and adds them to
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync _asCheckedParams so they won't cause trouble in the action handler.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self._fDbgSqlTrace = self.getBoolParam(self.ksParamDbgSqlTrace, False);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self._fDbgSqlExplain = self.getBoolParam(self.ksParamDbgSqlExplain, False);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Renders a simple form for controlling WUI debugging.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Returns the HTML for it.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ' <form id="debug-panel-form" type="get" action="#">\n';
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync sHtml += ' <input type="hidden" name="%s" value="%s"/>\n' \
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync % (webutils.escapeAttr(sKey), webutils.escapeAttrToStr(oValue),);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync [self.ksParamDbgSqlTrace, self._fDbgSqlTrace, 'SQL trace'],
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync [self.ksParamDbgSqlExplain, self._fDbgSqlExplain, 'SQL explain'], ):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync sHtml += ' <input type="checkbox" name="%s" value="1"%s>%s</input>\n' \
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync % (aoCheckBox[0], ' checked' if aoCheckBox[1] else '', aoCheckBox[2]);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync sHtml += ' <button type="submit">Apply</button>\n';
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync '</div>\n';
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Gets a dictionary with the debug parameters.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync For use when links are constructed from scratch instead of self._dParams.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # Dispatching
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """The default action handler, always overridden. """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync raise WuiException('The child class shall override WuiBase.actionDefault().')
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync def _actionGenericListing(self, oLogicType, oListContentType):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Generic listing action.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync oLogicType implements fetchForListing.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync oListContentType is a child of WuiListContentBase.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync cItemsPerPage = self.getIntParam(self.ksParamItemsPerPage, iMin = 2, iMax = 9999, iDefault = 300);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync iPage = self.getIntParam(self.ksParamPageNo, iMin = 0, iMax = 999999, iDefault = 0);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync aoEntries = oLogicType(self._oDb).fetchForListing(iPage * cItemsPerPage, cItemsPerPage + 1, tsEffective);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync oContent = oListContentType(aoEntries, iPage, cItemsPerPage, tsEffective,
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync (self._sPageTitle, self._sPageBody) = oContent.show();
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync def _actionGenericFormAdd(self, oDataType, oFormType):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Generic add something form display request handler.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync oDataType is a ModelDataBase child class.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync oFormType is a WuiFormContentBase child class.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync oData = oDataType().initFromParams(oDisp = self, fStrict = False);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync oForm = oFormType(oData, oFormType.ksMode_Add, oDisp = self);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync (self._sPageTitle, self._sPageBody) = oForm.showForm();
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync def _actionGenericFormDetails(self, oDataType, oLogicType, oFormType, sIdAttr, sGenIdAttr = None): # pylint: disable=R0914
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Generic handler for showing a details form/page.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync oDataType is a ModelDataBase child class.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync oLogicType may implement fetchForChangeLog.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync oFormType is a WuiFormContentBase child class.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync sIdParamName is the name of the ID parameter (not idGen!).
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # Parameters.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if sGenIdAttr is not None:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync idGenObject = self.getIntParam(getattr(oDataType, 'ksParam_' + sGenIdAttr), 0, 0x7ffffffe, -1);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync idObject = self.getIntParam(getattr(oDataType, 'ksParam_' + sIdAttr), 0, 0x7ffffffe, -1);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync fChangeLog = self.getBoolParam(WuiDispatcherBase.ksParamChangeLogEnabled, True);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync iChangeLogPageNo = self.getIntParam(WuiDispatcherBase.ksParamChangeLogPageNo, 0, 9999, 0);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync cChangeLogEntriesPerPage = self.getIntParam(WuiDispatcherBase.ksParamChangeLogEntriesPerPage, 2, 9999, 4);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # Fetch item and display it.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync oData = oDataType().initFromDbWithId(self._oDb, idObject, tsNow);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync oData = oDataType().initFromDbWithGenId(self._oDb, idGenObject);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync oContent = oFormType(oData, oFormType.ksMode_Show, oDisp = self);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync (self._sPageTitle, self._sPageBody) = oContent.showForm();
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # Add change log if supported.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if fChangeLog and hasattr(oLogicType, 'fetchForChangeLog'):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync (aoEntries, fMore) = oLogicType(self._oDb).fetchForChangeLog(getattr(oData, sIdAttr),
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self._sPageBody += oContent.showChangeLog(aoEntries, fMore, iChangeLogPageNo, cChangeLogEntriesPerPage, tsNow);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync def _actionGenericFormEdit(self, oDataType, oFormType, sIdParamName):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Generic edit something form display request handler.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync oDataType is a ModelDataBase child class.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync oFormType is a WuiFormContentBase child class.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync sIdParamName is the name of the ID parameter (not idGen!).
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync idObject = self.getIntParam(sIdParamName, 0, 0x7ffffffe);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync oData = oDataType().initFromDbWithId(self._oDb, idObject);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync oContent = oFormType(oData, oFormType.ksMode_Edit, oDisp = self);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync (self._sPageTitle, self._sPageBody) = oContent.showForm();
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync def _actionGenericFormEditL(self, oCoreObjectLogic, sCoreObjectIdFieldName, oWuiObjectLogic):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Generic modify something form display request handler.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync @param oCoreObjectLogic A *Logic class
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync @param sCoreObjectIdFieldName Name of HTTP POST variable that
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync contains object ID information
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync @param oWuiObjectLogic Web interface renderer class
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync iCoreDataObjectId = self.getIntParam(sCoreObjectIdFieldName, 0, 0x7ffffffe, -1)
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ## @todo r=bird: This will return a None object if the object wasn't found... Crash bang in the content generator
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # code (that's not logic code btw.).
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync oData = oCoreObjectLogic(self._oDb).getById(iCoreDataObjectId)
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # Instantiate and render the MODIFY dialog form
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync oContent = oWuiObjectLogic(oData, oWuiObjectLogic.ksMode_Edit, oDisp=self)
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync (self._sPageTitle, self._sPageBody) = oContent.showForm()
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync def _actionGenericFormClone(self, oDataType, oFormType, sIdAttr, sGenIdAttr = None):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Generic clone something form display request handler.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync oDataType is a ModelDataBase child class.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync oFormType is a WuiFormContentBase child class.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync sIdParamName is the name of the ID parameter.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync sGenIdParamName is the name of the generation ID parameter, None if not applicable.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # Parameters.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if sGenIdAttr is not None:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync idGenObject = self.getIntParam(getattr(oDataType, 'ksParam_' + sGenIdAttr), 0, 0x7ffffffe, -1);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync idObject = self.getIntParam(getattr(oDataType, 'ksParam_' + sIdAttr), 0, 0x7ffffffe, -1);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # Fetch data and clear identifying attributes not relevant to the clone.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync oData = oDataType().initFromDbWithGenId(self._oDb, idGenObject);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync oData = oDataType().initFromDbWithId(self._oDb, idObject, tsNow);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if sGenIdAttr is not None:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # Display form.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync oContent = oFormType(oData, oFormType.ksMode_Add, oDisp = self);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync (self._sPageTitle, self._sPageBody) = oContent.showForm()
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync def _actionGenericFormPost(self, sMode, fnLogicAction, oDataType, oFormType, sRedirectTo, fStrict=True):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Generic POST request handling from a WuiFormContentBase child.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync oDataType is a ModelDataBase child class.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync oFormType is a WuiFormContentBase child class.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync fnLogicAction is a method taking a oDataType instance and uidAuthor as arguments.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # Read and validate parameters.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync oData = oDataType().initFromParams(oDisp = self, fStrict = fStrict);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # Try do the job.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync fnLogicAction(oData, self._oCurUser.uid, fCommit = True);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync sErrorMsg = str(oXcpt) if not config.g_kfDebugDbXcpt else '\n'.join(utils.getXcptInfo(4));
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync (self._sPageTitle, self._sPageBody) = oForm.showForm(sErrorMsg = sErrorMsg);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # Worked, redirect to the specified page.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync (self._sPageTitle, self._sPageBody) = oForm.showForm(dErrors = dErrors);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync def _actionGenericFormAddPost(self, oDataType, oLogicType, oFormType, sRedirAction, fStrict=True):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Generic add entry POST request handling from a WuiFormContentBase child.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync oDataType is a ModelDataBase child class.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync oLogicType is a class that implements addEntry.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync oFormType is a WuiFormContentBase child class.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync sRedirAction is what action to redirect to on success.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync from testmanager.webui.wuicontentbase import WuiFormContentBase;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return self._actionGenericFormPost(WuiFormContentBase.ksMode_Add, oLogic.addEntry, oDataType, oFormType,
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync '?' + webutils.encodeUrlParams({self.ksParamAction: sRedirAction}), fStrict=fStrict)
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync def _actionGenericFormEditPost(self, oDataType, oLogicType, oFormType, sRedirAction, fStrict = True):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Generic edit POST request handling from a WuiFormContentBase child.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync oDataType is a ModelDataBase child class.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync oLogicType is a class that implements addEntry.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync oFormType is a WuiFormContentBase child class.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync sRedirAction is what action to redirect to on success.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync from testmanager.webui.wuicontentbase import WuiFormContentBase;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return self._actionGenericFormPost(WuiFormContentBase.ksMode_Edit, oLogic.editEntry, oDataType, oFormType,
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync '?' + webutils.encodeUrlParams({self.ksParamAction: sRedirAction}),
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Displays the unauthorized user message (corresponding record is not
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync present in DB).
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # Report to system log
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync oSystemLogLogic.addEntry(SystemLogData.ksEvent_UserAccountUnknown,
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync 'Unknown user (%s) attempts to access from %s'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # Display message.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync <p>Access denied for user <b>%s</b>.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Please contact an admin user to set up your access.</p>
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Dispatches a request.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # Get the parameters and checks for duplicates.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync raise WuiException('Error retriving parameters: %s' % (oXcpt,));
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # Take care about strings which may contain unicode characters: convert percent-encoded symbols back to unicode.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync dParams[sKey][idxItem] = dParams[sKey][idxItem].decode('utf-8')
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # Figure out the requested action and validate it.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync raise WuiException('Unknown action "%s" requested' % (self._sAction,));
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # Call action handler and generate the page (if necessary).
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if self._dDispatch[self._sAction]() is self.ksDispatchRcAllDone:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """ Debug printing. """