def validate_registration(self, req): if req.path_info == '/prefs': return acctmgr = AccountManager(self.env) username = acctmgr.handle_username_casing( req.args.get('username', '').strip()) if not username: raise RegistrationError(N_("Username cannot be empty.")) # Always exclude some special characters, i.e. # ':' can't be used in HtPasswdStore # '[' and ']' can't be used in SvnServePasswordStore blacklist = acctmgr.username_char_blacklist if contains_any(username, blacklist): pretty_blacklist = '' for c in blacklist: if pretty_blacklist == '': pretty_blacklist = tag(' \'', tag.b(c), '\'') else: pretty_blacklist = tag(pretty_blacklist, ', \'', tag.b(c), '\'') raise RegistrationError(N_( "The username must not contain any of these characters: %s"), tag.b(pretty_blacklist) ) # All upper-cased names are reserved for permission action names. if username.isupper(): raise RegistrationError(N_("A username with only upper-cased " "characters is not allowed.")) # Prohibit some user names, that are important for Trac and therefor # reserved, even if not in the permission store for some reason. if username.lower() in ['anonymous', 'authenticated']: raise RegistrationError(N_("Username %s is not allowed."), tag.b(username)) # NOTE: A user may exist in a password store but not in the permission # store. I.e. this happens, when the user (from the password store) # never logged in into Trac. So we have to perform this test here # and cannot just check for the user being in the permission store. # And better obfuscate whether an existing user or group name # was responsible for rejection of this user name. for store_user in acctmgr.get_users(): # Do it carefully by disregarding case. if store_user.lower() == username.lower(): raise RegistrationError(tag_( "Another account or group already exists, who's name " "differs from %(username)s only by case or is identical.", username=tag.b(username))) # Password consistency checks follow. password = req.args.get('password') if not password: raise RegistrationError(N_("Password cannot be empty.")) elif password != req.args.get('password_confirm'): raise RegistrationError(N_("The passwords must match."))
def render_registration_fields(self, req, data): """Add a hidden text input field to the registration form, and a visible one with mandatory input as well, if token is configured. """ if self.reg_basic_token: # Preserve last input for editing on failure instead of typing # everything again. old_value = req.args.get('basic_token', '') if self.reg_basic_question: # TRANSLATOR: Question-style hint for visible bot trap # registration input field. hint = tag.p(_("Please answer above: %(question)s", question=self.reg_basic_question), class_='hint') else: # TRANSLATOR: Verbatim token hint for visible bot trap # registration input field. hint = tag.p(tag_( "Please type [%(token)s] as verification token, " "exactly replicating everything within the braces.", token=tag.b(self.reg_basic_token)), class_='hint') insert = tag( tag.label(_("Parole:"), tag.input(type='text', name='basic_token', size=20, class_='textwidget', value=old_value)), hint) else: insert = None # TRANSLATOR: Registration form hint for hidden bot trap input field. insert = tag(insert, tag.input(type='hidden', name='sentinel', title=_("Better do not fill this field."))) return insert, data
def _do_account(self, req): assert (req.authname and req.authname != 'anonymous') action = req.args.get('action') delete_enabled = self.acctmgr.supports('delete_user') and \ self.acctmgr.allow_delete_account data = { 'delete_enabled': delete_enabled, 'delete_msg_confirm': _("Are you sure you want to delete your account?"), } force_change_password = req.session.get('force_change_passwd', False) if req.method == 'POST': if action == 'save': if self._do_change_password(req) and force_change_password: del req.session['force_change_passwd'] req.session.save() add_notice(req, _("Thank you for taking the time to " "update your password.")) force_change_password = False elif action == 'delete' and delete_enabled: self._do_delete(req) if force_change_password: add_warning(req, tag_( "You are required to change password because of a recent " "password change request. %(invitation)s", invitation=tag.b(_("Please change your password now.")))) return data
def expand_macro(self, formatter, name, content): arguments = content.split(',') error_hash = arguments[0] peer = SymfonyErrorPeer(self.env) msg = peer.retrieve_by_hash(error_hash) if msg: html_msg_h3 = html.h3('Komunikat') html_msg = html.p(html.b(msg[0])) html_uri_h3 = html.h3('Adres strony') html_uri = html.p(msg[1]) html_symfony_action = html.h3(html.span('Modul: ') + html.b(msg[2]) + html.span(' Akcja: ') + html.b(msg[3])) html_delete_link = html.a('Usun podobne bledy', href='/trac/bugs?delete_bug_id=' + arguments[0]) html_error = html.div(html_msg_h3 + html_msg + html_uri_h3 + html_uri + html_symfony_action + html_delete_link, class_='ticket_symfony_box') return html_error else: return 'Brak bledu o podanym identyfikatorze: ' + arguments[0] return html_url
def validate_registration(self, req): acctmgr = AccountManager(self.env) username = acctmgr.handle_username_casing( req.args.get('username', '').strip()) if req.path_info != '/prefs' and self.username_regexp != '' and \ not re.match(self.username_regexp.strip(), username): raise RegistrationError(N_( "Username %s doesn't match local naming policy."), tag.b(username) ) email = req.args.get('email', '').strip() if self.env.is_enabled(EmailCheck) and \ self.env.is_enabled(EmailVerificationModule) and \ EmailVerificationModule(self.env).verify_email: if self.email_regexp.strip() != '' and \ not re.match(self.email_regexp.strip(), email) and \ not req.args.get('active'): raise RegistrationError(N_( "The email address specified appears to be invalid. " "Please specify a valid email address."))
def validate_registration(self, req): if req.authname and req.authname != 'anonymous': return username = AccountManager(self.env).handle_username_casing( req.args.get('username', '').strip()) # NOTE: We can't use 'get_user_permissions(username)' here # as this always returns a list - even if the user doesn't exist. # In this case the permissions of "anonymous" are returned. # # Also note that we can't simply compare the result of # 'get_user_permissions(username)' to some known set of permission, # i.e. "get_user_permissions('authenticated') as this is always # false when 'username' is the name of an existing permission group. # # And again obfuscate whether an existing user or group name # was responsible for rejection of this username. for (perm_user, perm_action) in \ perm.PermissionSystem(self.env).get_all_permissions(): if perm_user.lower() == username.lower(): raise RegistrationError(tag_( "Another account or group already exists, who's name " "differs from %(username)s only by case or is identical.", username=tag.b(username)))
def process_request(self, req): acctmgr = self.acctmgr if req.authname != 'anonymous': req.redirect(req.href.prefs('account')) action = req.args.get('action') name = req.args.get('name', '') if isinstance(name, list): raise HTTPBadRequest(_("Invalid request arguments.")) name = name.strip() username = req.args.get('username', '') if isinstance(username, list): raise HTTPBadRequest(_("Invalid request arguments.")) username = acctmgr.handle_username_casing(username.strip()) data = { '_dgettext': dgettext, 'acctmgr': {'name': name, 'username': username}, 'ignore_auth_case': self.config.getbool('trac', 'ignore_auth_case') } verify_enabled = self.env.is_enabled(EmailVerificationModule) and \ EmailVerificationModule(self.env).verify_email data['verify_account_enabled'] = verify_enabled if req.method == 'POST' and action == 'create': try: try: # Check request and prime account on success. acctmgr.validate_account(req, True) except NotificationError, e: chrome.add_warning(req, _( "Error raised while sending a change notification." ) + _("You should report that issue to a Trac admin.")) self.log.error( 'Unable to send registration notification: %s', exception_to_unicode(e, traceback=True)) except RegistrationError, e: chrome.add_warning(req, e) else: if self.require_approval: set_user_attribute(self.env, username, 'approval', N_('pending')) # Notify admin user about registration pending for review. try: acctmgr._notify('registration_approval_required', username) except NotificationError, e: chrome.add_warning(req, _( "Error raised while sending a change " "notification.") + _( "You should report that issue to a Trac admin.")) self.log.error( 'Unable to send admin notification: %s', exception_to_unicode(e, traceback=True)) else: chrome.add_notice(req, tag_( "Your username has been registered successfully, " "but your account requires administrative " "approval. Please proceed according to local " "policy.")) if verify_enabled: chrome.add_notice(req, tag_( "Your username has been successfully registered but " "your account still requires activation. Please " "login as user %(user)s, and follow the " "instructions.", user=tag.b(username))) req.redirect(req.href.login()) chrome.add_notice(req, tag_( "Registration has been finished successfully. " "You may log in as user %(user)s now.", user=tag.b(username))) req.redirect(req.href.login())
if data.has_key('messages'): um_data['messages'].extend(data.pop('messages')) # adding user list um_data.update(users = UserManager(self.env).get_active_users()) # additional cells um_data.update(cells=list(self._get_cells(um_data['users']))) # adding usernamager's data to the data dict data.update(user_manager = um_data) # checking for external users trac_managed_users_out = self._do_import_current_users(req, dry_run=True) if len(trac_managed_users_out)>0: um_data['errors'].append(html.form(html.b(_("WARNING: ")),_(" [%s] users are not added to the team.")%(', '.join(trac_managed_users_out)),html.input(type="submit", name="um_import_current_users", value=_("Add Users")), action=req.href.admin('accounts/users'), method="post") ) try: from acct_mgr.api import AccountManager data.update(account_manager = AccountManager(self.env)) except Exception, e: data.update(account_manager = {'has_user':lambda x: False}) self.log.error('Account manager not loaded') # adding stylesheets add_stylesheet(req, 'tracusermanager/css/admin_um.css') add_script(req, 'tracusermanager/js/admin_um.js') return 'admin_um.html', data # Internal methods
# additional cells um_data.update(cells=list(self._get_cells(um_data['users']))) # adding usernamager's data to the data dict data.update(user_manager=um_data) data['sort'] = req.args.get('sort') or 'name' data['asc'] = req.args.get('asc') or '1' # checking for external users trac_managed_users_out = self._do_import_current_users(req, dry_run=True) if len(trac_managed_users_out) > 0: um_data['errors'].append( html.form(html.b(_("WARNING: ")), _(" [%s] users are not added to the team.") % (', '.join(trac_managed_users_out)), html.input(type="submit", name="um_import_current_users", value=_("Add Users")), action=req.href.admin('accounts/users'), method="post")) try: from acct_mgr.api import AccountManager data.update(account_manager=AccountManager(self.env)) except Exception, e: data.update(account_manager={'has_user': lambda x: False}) self.log.error('Account manager not loaded')
class MultiLangTitleIndex(WikiMacroBase): """Inserts an alphabetic list of all wiki pages cosidering suffixes. This macro is similar to TitleIndex macro but differ in two points. * All the variants are displayed in one line. * Displayed in two columns. One is for the pages made for the project. One is for the pages provided by Trac. `WikiStart` and `SandBox` are grouped in project pages as default. This is configurable via `_explicit_user_pages` option. One entry displayed by this macro has a format like this: {{{ WikiStart (en, fr, ja, default) }}} Left most page name is for usual access with negotiation. Items in paren are existing language variants for the page. System pages are decided by listing files in wiki-default directory. As described before, you can exclude some pages as user page by spcifying `_explicit_user_pages`. Likewise, you can specify the system pages via `_explicit_system_pages` option. These two options are list of page names separated by comma. If the page name ends with '*' character, it works as prefix for matching. For exmaple, 'Trac*' means "page names staring with 'Trac'". """ _explicit_user_pages = ListOption('multi-lang-title-index', 'explicit_user_pages', 'WikiStart, SandBox', doc="List of page names to be grouped" " in user page. If the name ends" " with '*', it works as prefix.") _explicit_system_pages = ListOption('multi-lang-title-index', 'explicit_system_pages', '', #'GraphViz*', doc="List of page names to be grouped" " in system page. If the name ends" " with '*', it works as prefix.") _wiki_default_pages = _list_wiki_default_pages() SPLIT_RE = re.compile(r"( |/|[0-9])") PAGE_SPLIT_RE = re.compile(r"([a-z])([A-Z])(?=[a-z])") # macro entry point for Trac 0.11 def expand_macro(self, formatter, name, content): args, kw = util.parse_args(content) prefix = args and args[0] or None format = kw.get('format', '') minsize = max(int(kw.get('min', 2)), 2) depth = int(kw.get('depth', -1)) start = prefix and prefix.count('/') or 0 wiki = formatter.wiki pages = sorted([page for page in wiki.get_pages(prefix) \ if 'WIKI_VIEW' in formatter.perm('wiki', page)]) pagelangs = {} for page in pages: name, lang = util.split_lang(page, '') langs = pagelangs.get(name, []) if lang not in langs: langs.append(lang) pagelangs[name] = langs pages = sorted(pagelangs.keys()) # collection of default pages upages, spages = self.split_pages(pages) def format_page_name(page, split=False): try: # for trac 0.11 return wiki.format_page_name(page, split=split) except: # for trac 0.10 if split: return self.PAGE_SPLIT_RE.sub(r"\1 \2", page) return page def split(page): if format != 'group': return [format_page_name(page)] else: return self.SPLIT_RE.split(format_page_name(page, split=True)) # Group by Wiki word and/or Wiki hierarchy upages, spages = [[(split(page), page) for page in pages if depth < 0 or depth >= page.count('/') - start] for pages in (upages, spages)] def split_in_groups(group): """Return list of pagename or (key, sublist) elements""" groups = [] for key, subgrp in groupby(group, lambda (k,p): k and k[0] or ''): subgrp = [(k[1:],p) for k,p in subgrp] if key and len(subgrp) >= minsize: sublist = split_in_groups(sorted(subgrp)) if len(sublist) == 1: elt = (key+sublist[0][0], sublist[0][1]) else: elt = (key, sublist) groups.append(elt) else: for elt in subgrp: groups.append(elt[1]) return groups def render_one(page, langs): result = [tag.a(wiki.format_page_name(page), href=formatter.href.wiki(page))] if langs: for lang in sorted(langs): result.append(', ') p = '%s.%s' % (page, lang) result.append(tag.a(lang or 'default', style='color:#833', href=formatter.href.wiki(p))) result[1] = ' (' result.append(')') return result def render_groups(groups): return tag.ul( [tag.li(isinstance(elt, tuple) and tag(tag.strong(elt[0]), render_groups(elt[1])) or render_one(elt, pagelangs.get(elt))) for elt in groups]) #return render_groups(split_in_groups(pages)) return tag.table(tag.tr([tag.td([tag.b(title + ' pages:'), render_groups(split_in_groups(pages))]) for title, pages in [('User', upages), ('System', spages)]], valign='top'))