# extends 'admin.html' # block admintitle ${dgettext("acct_mgr", "Accounts: Configuration")} # endblock admintitle # block adminpanel

${dgettext("acct_mgr", "Accounts: Configuration")}

${jmacros.form_token_input()} ## Top navigation
# if active > 0 # if active < len(steps) - 1 # else # endif # endif # if active < len(steps) - 1 # endif ## Last value cache for stepping through pages back and forth
# if active == 0 ## Page 1
${ dgettext("acct_mgr", "Step %(step)s: %(label)s", step=active + 1, label=steps[active].label) }

${dgettext('acct_mgr', 'Objective for setting Authentication Options')}

${ dgettext("acct_mgr", "Decide, whether to use HTTP authentication (Trac default) or " "a HTML login form provided by AccountManagerPlugin.") }

${ dgettext("acct_mgr", "After initial login Trac sessions are authenticated per request " "based on browser cookies. Therefore a number of options provide " "control over some critical browser cookie properties.") }

${dgettext('acct_mgr', 'Provider-agnostic Authentication Options')}

${ i18n_tag( dgettext("acct_mgr", "Adapt to careless username typing, where casing does not matter, like" " on Windows. Potentially troublesome, because [1:case matters for " "Trac permission assignment lookup] anyway."), 'tt') }

${ dgettext("acct_mgr", "Potentially troublesome for users with dynamic IP " "address, but disregarded for persistent sessions.") }

${ dgettext('acct_mgr', 'Required, if the Trac instance is only accessible through HTTPS.') }

## Last value cache for JS code # set lifetime_value = (auth_cookie_lifetime or 2592000) if acctmgr_login else auth_cookie_lifetime

${ dgettext("acct_mgr", "Determines how long the browser will cache authentication " "information, and therefore, after how much inactivity a user will " "have to log in again. Default (0 s) makes cookie expire at " "browsing sessions end.") }

${dgettext('acct_mgr', 'Authentication Front-end')}

${ dgettext("acct_mgr", "You can still manage some password stores with " "AccountManagerPlugin, if you configure them in the next step.") }

${ i18n_tag( dgettext( "acct_mgr", "AccountManagerPlugin provides a custom version of the [1:LoginModule]" " accompanied by a form-based HTML login page."), 'strong') }

${ i18n_tag( dgettext( "acct_mgr", "If you enable this feature, you'll want to review and adjust some " "more options related to session authentication. Note, that " "AccountManagerPlugin's LoginModule [1:changes the default lifetime of" " authentication cookies to 30 days]."), 'tt') }

${dgettext('acct_mgr', 'AccountManagerPlugin Authentication Options')}

${ i18n_tag( dgettext( "acct_mgr", "[1:If enabled, links to][2:[3:[4:Lost password/Password " "reset]][5:[6:Registration for new users]]][7:that normally reside in " "Trac's meta-navigation bar, will appear inside the login form. CSS " "styling allows further customization of the login prompt.]" ), tag.p(class_='hint'), 'ul', 'li', tag.span(class_='hint'), 'li', tag.span(class_='hint'), tag.p(class_='hint'), ) }

${ i18n_tag( dgettext( "acct_mgr", "This is, user checks a \"Remember Me\" [1:checkbox] in the " "AccountManagerPlugin login form and, next time he visits the site " "within 30 days, he'll be remembered and authenticated automatically."), 'tt') }

${ i18n_tag( dgettext( "acct_mgr", "Driving a refresh process to decrease vulnerability of long-lasting " "sessions. Zero means [1:never]."), 'tt') }

${ i18n_tag( dgettext( "acct_mgr", "This enables AccountManagerPlugin's authentication data distribution " "to Trac instances with matching cookie path. Set this to a common " "base path of several Trac instances to share the cookie, providing a " "cheap [1:Single-Sign-On] experience."), 'tt') }

# elif active == 1 ## Page 2
${ dgettext("acct_mgr", "Step %(step)s: %(label)s", step=active + 1, label=steps[active].label) } ${dgettext('acct_mgr', 'Password store')}

${dgettext('acct_mgr', 'Objective for configuring a Password Store')}

${ dgettext("acct_mgr", "AccountManagerPlugin manages user credentials in a modular " "back-end providing access to at least one password store.") }

# if len(password_store) == 0

${dgettext('acct_mgr', 'Initial Authentication Back-end selection')}

## Initial setup content

${ i18n_tag( dgettext( "acct_mgr", "The [1:SessionStore] implements password storage in Trac db table " "'session_attribute'. Its the default choice mainly for avoiding " "additional dependencies like directory and file permissions."), 'strong') }

${ dgettext("acct_mgr", "While great to resolve some concurrent access issues too, this " "password store has shortcomings as well. Notably it does not " "support seamless hash type migration, and its no candidate for " "shared use by multiple Trac instances or even by applications " "beyond Trac.") }

${ dgettext("acct_mgr", "Details (Preview)") }
${init_store_hint.db}

${ dgettext("acct_mgr", "Please apply these default options first. " "You'll be able to change values afterwards.") }

${ dgettext("acct_mgr", "AccountManagerPlugin includes native support for common Apache " "file formats 'htpasswd' and 'htdigest' as well as support for " "reading svnserve's password file format.") }

dgettext("acct_mgr", "You may use the same file for several Trac environments. Note " "that setting appropriate directory and file permissions is " "crucial for these stores, but not covered by this configuration " "wizard.") }

${dgettext("acct_mgr", "Details (Preview)")}
${init_store_hint.htdigest}

${ dgettext("acct_mgr", "Please apply these default options first. " "You'll be able to change values afterwards.") }

${dgettext("acct_mgr", "Details (Preview)")}
${init_store_hint.htpasswd}

${ dgettext("acct_mgr", "Please apply these default options first. " "You'll be able to change values afterwards.") }

${dgettext("acct_mgr", "Details (Preview)")}
${init_store_hint.svn_file}

${ dgettext("acct_mgr", "Please apply these default options first. " "You'll be able to change values afterwards.") }

${ i18n_tag( dgettext( "acct_mgr", "AccountManagerPlugin enables use of standard HTTP-Auth by its " "[1:HttpAuthStore] component. Both Basic and Digest authentication " "challenges are supported."), 'strong') }

${ dgettext("acct_mgr", "In addition to being read-only this password store does " "not even support listing users for obvious reasons.") }

${dgettext("acct_mgr", "Details (Preview)")}
${init_store_hint.http}

${ dgettext("acct_mgr", "Please apply these default options first. " "You'll be able to change values afterwards.") }

${ dgettext("acct_mgr", "AccountManagerPlugin's modular password store concept " "encourages creation of more ways to provide user credential " "beyond the natively supported stores. While a specific setup " "assistance for these 3rd-party authentication providers is not " "implemented, you may fill-in appropriate configuration details " "for an already installed component below.") }

${dgettext('acct_mgr', 'Configuration')}

${ dgettext("acct_mgr", "Type the custom configuration options as provided " "by that components documentation and apply it.") }

# else
## Standard page content

${dgettext('acct_mgr', 'Password Store Configuration')}

${ i18n_tag( dgettext( "acct_mgr", "All enabled stores are listed below, but most won't work at all " "without additional configuration.[1:]Currently configured: " "[2:%(store_list)s]"), 'br', tag.em(title='[account-manager] password_store'), store_list=', '.join(password_store)) }

# if len(password_store) > 1

${ dgettext('acct_mgr', 'This is an experts-only type of store configuration.') }

# endif # if disabled_store

${ i18n_tag(dgettext("acct_mgr", "Required disabled component(s): [1:%(components)s]"), 'em', components=', '.join(disabled_store)) }

# endif

${ dgettext("acct_mgr", "Select one or more stores and configure related options. " "Concurrent use of multiple password stores is supported too.") }

${ dgettext('acct_mgr', 'Password stores are queried in turn, so order matters.') }

# for section in store_list
# for option in section.options
# if option.doc

${option.doc}

# endif
# endfor
# endfor

${ dgettext("acct_mgr", "Use it after changing hash type or to migrate to a " "new primary password store.") }

${ dgettext("acct_mgr", "The update will run only once. Restarting the procedure " "for all accounts allows to propagate subsequent changes.") }

# endif
# elif active == 2 ## Page 3
${ dgettext("acct_mgr", "Step %(step)s: %(label)s", step=active + 1, label=steps[active].label) } ${dgettext('acct_mgr', 'Password refresh')}

${dgettext('acct_mgr', 'Objective for Password Policy rules')}

${ dgettext("acct_mgr", "While AccountManagerPlugin does not enforce password rules in " "general, there are some other ways to alter password handling.") }

${ dgettext("acct_mgr", "It relies on a working email sender for Trac, " "supporting both TracAnnouncer and TracNotification.") }

${ dgettext("acct_mgr", "These passwords are used as alternative passwords on request.") }

# elif active == 3
${ dgettext("acct_mgr", "Step %(step)s: %(label)s", step=active + 1, label=steps[active].label) } ${dgettext('acct_mgr', 'Account approval')}

${ dgettext('acct_mgr', 'Objective for Account Registration and Verification rules') }

${ dgettext("acct_mgr", "You may require administrative approval of new accounts for the " "user registration process. The ability to immediately ban existing " "accounts is another, related but independent feature.") }

${ dgettext('acct_mgr', 'Checks to use for validating Registration requests') }

${ i18n_tag( dgettext( "acct_mgr", "All checks provided by AccountManagerPlugin are enabled per default, " "but some are configurable on their own.[1:]Currently configured: " "[2:%(check_list)s]"), 'br', tag.em(title='[account-manager] register_check'), check_list=', '.join(register_check), ) }

${ i18n_tag( dgettext( "acct_mgr", "Checks like [1:BotTrapCheck] won't work at all without additional " "configuration."), 'strong') }

# if disabled_check

${ i18n_tag( dgettext("acct_mgr", "Required disabled component(s): [1:%(components)s]"), 'em', components=', '.join(disabled_check)) }

# endif

${ dgettext("acct_mgr", "Select one or more checks and configure related options. " "Concurrent use of multiple registration checks is encouraged.") }

${ dgettext("acct_mgr", "Checks are applied in turn, so order matters. Note that " "some checks are used to validate admin user actions too.") }

# for section in check_list
# if section.doc
${safe_wiki_to_html(context, section.doc)}
# endif # for option in section.options
# if option.doc

${option.doc}

# endif
# endfor
# endfor

${dgettext('acct_mgr', 'Other Account Policy options')}

${ dgettext("acct_mgr", "For admin notification on registration time it " "relies on a working email sender for Trac, " "supporting both TracAnnouncer and TracNotification.") }

${ dgettext("acct_mgr", "For sending a verification token to the user it relies " "on a working email sender for Trac, supporting both " "TracAnnouncer and TracNotification.") }

# elif active == 4 ## Page 5
${ dgettext("acct_mgr", "Step %(step)s: %(label)s", step=active + 1, label=steps[active].label) } ${dgettext('acct_mgr', 'Account guard')}

${dgettext('acct_mgr', 'Objective for Account Protection rules')}

${ dgettext( "acct_mgr", "Passwords are often not constructed as carefully as they should be. " "And even a strong passphrase could be sift out, if an attacker is " "able to test millions of variants in hours, if not seconds. " "Firewalls and full-featured web-servers already offer sophisticated " "protection, if one can afford them, handle their installation, " "configuration and maintenance.") }

${ i18n_tag( dgettext( "acct_mgr", "The [1:AccountGuard] component is another option. It is an add-on to " "AccountManagerPlugin's own [2:LoginModule] and provides account " "protection by discouraging brute-force login attempts."), 'strong', 'strong') }

# if not acctmgr_login

${dgettext('acct_mgr', "AccountManagerPlugin's LoginModule is disabled.")}

# endif

${ i18n_tag( dgettext( "acct_mgr", "Lock user account after the specified number of failed attempts. " "Value zero means [1:no limit]."), 'strong') }

${ i18n_tag( dgettext("acct_mgr", "Zero means [1:unlimited] lock time here."), 'strong') }

${ dgettext("acct_mgr", "Extend user account lock duration incrementally. " "It uses logarithmic calculation with the factor " "as exponent, accepting decimal numbers >= 1.") }

${ i18n_tag( dgettext( "acct_mgr", "[1:Lock time will grow for any value > 1, if the failure " "happens before lock expiration. I.e. value '2' means][2:" "[3:[4:double lock time after 2nd failure,]]" "[5:[6:four times the initial lock time after 3rd,]]" "[7:[8:eight times as long after 4th failure, etc.]]" "]", ), tag.p(class_='hint'), 'ul', 'li', tag.span(class_='hint'), 'li', tag.span(class_='hint'), 'li', tag.span(class_='hint'), ) }

${ dgettext("acct_mgr", "At any time after lock expiration a login failure " "will just trigger a lock and set a new lock timeout, " "but not extend the total lock duration.") }

## Last value cache for JS code

${ dgettext('acct_mgr', 'This is relevant only with a progression factor > 1.') }

# else ## Page 6
${ dgettext("acct_mgr", "Step %(step)s: %(label)s", step=active + 1, label=steps[active].label) } # if not admin_available

${dgettext('acct_mgr', 'Objective for additional preparation')}

${ dgettext('acct_mgr', 'Enable yourself to proceed beyond this initial setup.') }

${dgettext('acct_mgr', 'Initial Admin Account')}

${dgettext('acct_mgr', 'Add Admin Account:')}

${ i18n_tag( dgettext( "acct_mgr", "The user will get [1:TRAC_ADMIN] assigned, that inherits all " "available permissions. One such account is required to configure Trac" " via the admin web-UI. Create and manage more limited admin accounts " "as well as actual user accounts on your own later via the Accounts " "admin panel."), 'strong') }

${ i18n_tag( dgettext( "acct_mgr", "In detail: AccountManagerPlugin requires [1:ACCTMGR_USER_ADMIN] for " "regular user administration, [2:ACCTMGR_CONFIG_ADMIN] for viewing " "these pages and changing the configuration later. Both are inherited " "by [3:ACCTMGR_ADMIN] permission. To assign permissions you'll need " "[4:PERMISSION_GRANT] inherited by [5:PERMISSION_ADMIN] too."), 'strong', 'strong', 'strong', 'strong', 'strong') }

# if ignore_auth_case

${ dgettext('acct_mgr', 'Only lowercase usernames allowed') }

# endif
# if not password_store

${ dgettext("acct_mgr", "Please take care, that the username is known by the " "HTTP authentication provider.") }

# elif not set_password

${ dgettext("acct_mgr", "Please take care for a valid username, because no configured " "password store supports creating a new account.") }

# endif
# endif

${dgettext('acct_mgr', 'Check-up')}

    # for goal in completion.details
  • # if goal.step ${goal.desc} # else ${goal.desc} # endif
  • # endfor
# if admin_available and not completion.ready

${ dgettext('acct_mgr', 'Please resolve all issues marked as critical.') }

# endif # if completion.ready

${ i18n_tag( dgettext( "acct_mgr", "By now you did almost finish AccountManagerPlugin configuration, but " "any changes are temporary yet. Please test and adjust the " "configuration as required, or cancel to revert all changes. Apply " "settings to [1:trac.ini] only if you really want to preserve them " "permanently."), 'em') }

## Final configuration preview listing
${dgettext('acct_mgr', 'Details (Preview)')}
# for section, options in roundup|dictsort [${section}]
# for option, value in options|sort(attribute=0) ${option} = ${value}
# endfor
# endfor
# endif
# endif ## Bottom navigation
# if active > 0 # if active < len(steps) - 1 # else # endif # endif # if active < len(steps) - 1 # else # endif
# endblock adminpanel