Author: rjollos
Date: Wed Jun 12 03:34:33 2013
New Revision: 1492038

URL: http://svn.apache.org/r1492038
Log:
Refs #201: Added bootstrap templates for AccountManagerPlugin's Users and 
Account Details views. Based on a patch from Olemis, with modifications for 
version 0.4.3 of AccountManagerPlugin.

Added:
    bloodhound/trunk/bloodhound_theme/bhtheme/templates/bh_account_details.html
    bloodhound/trunk/bloodhound_theme/bhtheme/templates/bh_admin_users.html
Modified:
    
bloodhound/trunk/bloodhound_theme/bhtheme/templates/bh_admin_accountsconfig.html
    bloodhound/trunk/bloodhound_theme/bhtheme/theme.py

Added: 
bloodhound/trunk/bloodhound_theme/bhtheme/templates/bh_account_details.html
URL: 
http://svn.apache.org/viewvc/bloodhound/trunk/bloodhound_theme/bhtheme/templates/bh_account_details.html?rev=1492038&view=auto
==============================================================================
--- bloodhound/trunk/bloodhound_theme/bhtheme/templates/bh_account_details.html 
(added)
+++ bloodhound/trunk/bloodhound_theme/bhtheme/templates/bh_account_details.html 
Wed Jun 12 03:34:33 2013
@@ -0,0 +1,199 @@
+<!DOCTYPE html
+    PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd";>
+<html xmlns="http://www.w3.org/1999/xhtml";
+      xmlns:xi="http://www.w3.org/2001/XInclude";
+      xmlns:py="http://genshi.edgewall.org/"; 
+      xmlns:i18n="http://genshi.edgewall.org/i18n";
+      i18n:domain="acct_mgr">
+  <xi:include href="admin.html" />
+  <?python
+    if _dgettext:
+        dgettext = _dgettext ?>
+  <head>
+    <title>Account Details</title>
+  </head>
+
+  <body>
+    <div id="account_details">
+      <div id="header">
+        <h2>Review User Account Details</h2>
+        <py:choose>
+          <p py:when="name" i18n:msg="name, user">
+            for <b>${name}</b> (<em>${user}</em>)
+          </p>
+          <p py:otherwise="" i18n:msg="user">
+            for <b>${user}</b>
+          </p>
+        </py:choose>
+      </div>
+
+      <form method="get" action="${url}">
+      <div class="row">
+        <div class="span4">
+          <fieldset>
+            <legend>
+              <label><span class="label">Account Status</span></label>
+            </legend>
+            <py:choose>
+              <div id="user_store" py:when="user_store">
+                <p i18n:msg="order_num,store">
+                  Credentials for this user are stored in AuthStore number
+                  <em>${store_order_num}</em> (${user_store}).</p>
+                <py:choose>
+                  <p class="hint" py:when="ignore_auth_case" i18n:msg="bool">
+                    Username matching is set to <b>not case-sensitive</b>.</p>
+                  <p class="hint" py:otherwise="" i18n:msg="bool">
+                    Username matching is set to <em>case-sensitive</em>.</p>
+                </py:choose>
+              </div>
+              <div id="no_user_store" py:otherwise="">
+                <p i18n:msg="">No store provides credentials for this user,
+                  so the user currently can't be authenticated and
+                  access to this <b>account is effectively blocked</b>,
+                  while account details may still be available.</p>
+              </div>
+            </py:choose>
+    
+            <hr py:if="pretty_lock_time or (lock_count > 0)" />
+    
+            <div id="user_locked" py:if="user_locked is True">
+              <p>
+                <py:choose>
+                  <span py:when="release_time" i18n:msg="time">
+                    <img src="${href.chrome('/acct_mgr/time-locked.png')}" />
+                    This account has been locked until ${release_time}<br />
+                    and even valid login attempts are rejected 
meanwhile.</span>
+                  <span py:otherwise="">
+                    <img src="${href.chrome('/acct_mgr/locked.png')}" />
+                    This account has been locked permanently.</span>
+                </py:choose>
+                <span class="buttons">
+                  <input type="submit" name="release"
+                         alt="Release account lock"
+                         title="Release account lock"
+                         value="${dgettext('acct_mgr', 'Unlock')}" />
+                </span>
+              </p>
+            </div>
+    
+            <py:choose>
+              <div id="restricted" py:when="pretty_lock_time">
+                <py:choose>
+                  <div py:when="lock_count > 0">
+                    <i18n:choose numeral="lock_count" params="count"
+                                 py:if="not _dgettext">
+                      <p i18n:singular="">Lock condition has been met
+                        ${lock_count} time by now.</p>
+                      <p i18n:plural="">Lock condition has been met
+                        ${lock_count} times by now.</p>
+                    </i18n:choose>
+                    <!--! i18n:choose doesn't play nicely with Trac releases
+                      before Trac 0.12, so we provide an alternative message
+                      that is excluded from extraction and translation. -->
+                    <p py:if="_dgettext" xml:lang="en">Lock condition has been 
met
+                      ${lock_count} time(s) by now.</p>
+                    <p i18n:msg="time">
+                      Therefore after another failed login attempt 
authentication
+                      for this account would be retarded by 
${pretty_lock_time}.
+                    </p>
+                  </div>
+    
+                  <div py:otherwise="">
+                    <p>Lock condition has not been met yet.</p>
+                  </div>
+                </py:choose>
+              </div>
+    
+              <div id="unrestricted" py:otherwise="">
+                <p py:if="not user_locked is True">
+                  No constraints are set for this account.</p>
+              </div>
+            </py:choose>
+          </fieldset>
+        </div>
+
+        <div id="verification" py:if="verification" class="span4">
+          <fieldset>
+            <legend>
+              <label><span class="label">Verification</span></label>
+            </legend>
+            <py:choose>
+              <div py:when="email">
+                <p i18n:msg="email">
+                  Current email address: &lt;${email}&gt;</p>
+                <py:choose>
+                  <p py:when="email_verified is True">
+                    This address has been verified successfully.</p>
+                  <p py:when="not email_verified is None" i18n:msg="token">
+                    Verification is pending
+                    (<span class="hint">token: '${email_verified}' 
</span>).</p>
+                  <p py:otherwise="">
+                    This address has not been verified yet.</p>
+                </py:choose>
+              </div>
+              <div py:otherwise="">
+                <p>No email address is registered for this account.</p>
+              </div>
+            </py:choose>
+          </fieldset>
+        </div>
+      </div>
+
+      <div class="row">
+        <div class="span4">
+          <fieldset>
+            <legend>
+              <label><span class="label">Access History</span></label>
+            </legend>
+            <py:choose>
+              <p py:when="last_visit" i18n:msg="time">
+                Last login: ${last_visit}</p>
+              <p py:otherwise="">The user has not logged in before.</p>
+            </py:choose>
+            <py:choose>
+              <div id="failed_attempts" py:when="attempts_count > 0">
+                <p i18n:msg="count">Total failed attempts: 
${attempts_count}</p> 
+                <p class="tableheader">
+                  Table: Last failed login attempts log view</p>
+                <table class="listing" id="login_attempts">
+                  <thead>
+                    <tr>
+                      <th>IP address</th>
+                      <th>Log time</th>
+                    </tr>
+                  </thead>
+                  <tbody>
+                    <tr py:for="attempt in attempts">
+                      <td>${attempt.ipnr}</td>
+                      <td>${attempt.time}</td>
+                    </tr>
+                  </tbody>
+                </table>
+                <div class="buttons" py:if="not user_locked is True">
+                  <input type="submit" name="delete"
+                         alt="Delete login failure log"
+                         title="Delete login failure log"
+                         value="${dgettext('acct_mgr', 'Delete Log')}" />
+                </div>
+              </div>
+              <div id="no_failed_attempts" py:otherwise="">
+                <p>There is currently no failed login attempt logged.</p>
+              </div>
+            </py:choose>
+          </fieldset>
+        </div>
+      </div>
+
+      <div class="buttons">
+        <input type="hidden" name="user" value="${user}" />
+        <input type="submit" name="list" class="btn"
+               value="${dgettext('acct_mgr', 'Back to accounts')}" />
+        <input type="submit" name="update" class="btn"
+               value="${dgettext('acct_mgr', 'Update')}" />
+      </div>
+      </form>
+    </div>
+
+  </body>
+</html>

Modified: 
bloodhound/trunk/bloodhound_theme/bhtheme/templates/bh_admin_accountsconfig.html
URL: 
http://svn.apache.org/viewvc/bloodhound/trunk/bloodhound_theme/bhtheme/templates/bh_admin_accountsconfig.html?rev=1492038&r1=1492037&r2=1492038&view=diff
==============================================================================
--- 
bloodhound/trunk/bloodhound_theme/bhtheme/templates/bh_admin_accountsconfig.html
 (original)
+++ 
bloodhound/trunk/bloodhound_theme/bhtheme/templates/bh_admin_accountsconfig.html
 Wed Jun 12 03:34:33 2013
@@ -25,7 +25,7 @@
       xmlns:xi="http://www.w3.org/2001/XInclude";
       xmlns:py="http://genshi.edgewall.org/"; 
       xmlns:i18n="http://genshi.edgewall.org/i18n";
-      i18n:domain="bloodhound">
+      i18n:domain="acct_mgr">
   <xi:include href="admin.html" />
   <?python
     if _dgettext is not None:
@@ -100,7 +100,7 @@
             <p class="help-block" i18n:msg="">
               <span class="label label-info">Details</span>
               This is, user checks a "Remember Me"
-              <tt>checkbox</tt> and, next time he visits the site,
+              <code>checkbox</code> and, next time he visits the site,
               he'll be remembered and automatically authenticated.
             </p>
           </fieldset>

Added: bloodhound/trunk/bloodhound_theme/bhtheme/templates/bh_admin_users.html
URL: 
http://svn.apache.org/viewvc/bloodhound/trunk/bloodhound_theme/bhtheme/templates/bh_admin_users.html?rev=1492038&view=auto
==============================================================================
--- bloodhound/trunk/bloodhound_theme/bhtheme/templates/bh_admin_users.html 
(added)
+++ bloodhound/trunk/bloodhound_theme/bhtheme/templates/bh_admin_users.html Wed 
Jun 12 03:34:33 2013
@@ -0,0 +1,190 @@
+<!DOCTYPE html
+    PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd";>
+
+<!--!
+  Licensed to the Apache Software Foundation (ASF) under one
+  or more contributor license agreements.  See the NOTICE file
+  distributed with this work for additional information
+  regarding copyright ownership.  The ASF licenses this file
+  to you under the Apache License, Version 2.0 (the
+  "License"); you may not use this file except in compliance
+  with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing,
+  software distributed under the License is distributed on an
+  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+  KIND, either express or implied.  See the License for the
+  specific language governing permissions and limitations
+  under the License.
+-->
+
+<html xmlns="http://www.w3.org/1999/xhtml";
+      xmlns:xi="http://www.w3.org/2001/XInclude";
+      xmlns:py="http://genshi.edgewall.org/"; 
+      xmlns:i18n="http://genshi.edgewall.org/i18n";
+      i18n:domain="acct_mgr">
+  <xi:include href="admin.html" />
+  <?python
+    if _dgettext is not None:
+        dgettext = _dgettext ?>
+  <head>
+    <title>Accounts</title>
+  </head>
+
+  <body>
+    <h2>Manage User Accounts</h2>
+
+    <div class="row">
+      <div class="system-message" py:if="editor_error">
+        <xi:include href="widget_alert.html"
+                    py:with="msgtype = 'error'; msglabel = 'Error';
+                             msgbody = editor_error" />
+      </div>
+      <div class="notice system-message" py:if="success">
+        <xi:include href="widget_alert.html"
+                    py:with="msgtype = 'success'; msglabel = 'Successfully 
updated';
+                             msgbody = ', '.join(success)" />
+      </div>
+      <div class="system-message" py:if="deletion_error">
+        <xi:include href="widget_alert.html"
+                    py:with="msgtype = 'error'; msglabel = 'Error';
+                             msgbody = deletion_error" />
+      </div>
+
+      <div class="span9">
+        <div class="well">
+          <form id="account-editor" class="addnew" method="post">
+            <fieldset>
+              <legend>Add/Edit Account:</legend>
+              <div class="field">
+                <label>Username:<br />
+                  <input id="username" type="text"
+                         class="textwidget input-medium no-add-on"
+                         name="username"
+                         value="${acctmgr.username}" placeholder="e.g. myuser" 
/>
+                </label>
+              </div>
+              <div class="field">
+                <label py:choose="">Password:<br />
+                  <div class="input-prepend">
+                    <span class="add-on">
+                      <i class="icon-lock"></i>
+                    </span>
+                    <input py:when="create_enabled or password_change_enabled"
+                           type="password" class="textwidget input-medium"
+                           name="password" placeholder="Type your password" />
+                    <input py:otherwise=""
+                           type="password" class="textwidget input-medium"
+                           name="password" placeholder="Type your password"
+                           disabled="disabled" />
+                  </div>
+                </label>
+              </div>
+              <div class="field">
+                <label py:choose="">Confirm Password:<br />
+                  <div class="input-prepend">
+                    <span class="add-on">
+                      <i class="icon-lock"></i>
+                    </span>
+                    <input py:when="create_enabled or password_change_enabled"
+                           type="password" class="textwidget input-medium"
+                           name="password_confirm" placeholder="Must match 
password" />
+                    <input py:otherwise=""
+                           type="password" class="textwidget input-medium"
+                           name="password_confirm" placeholder="Must match 
password"
+                           disabled="disabled" />
+                  </div>
+                </label>
+              </div>
+              <div class="field">
+                <label>Pre-/Surname (Nickname):<br />
+                  <input type="text" class="textwidget input-medium no-add-on"
+                         name="name" value="${acctmgr.name}"
+                         placeholder="e.g. John Smith" />
+                </label>
+              </div>
+              <div class="field">
+                <label>Email Address:<br />
+                  <div class="input-prepend">
+                    <span class="add-on">
+                      <i class="icon-envelope"></i>
+                    </span>
+                    <input type="text" class="textwidget input-medium"
+                           name="email" value="${acctmgr.email}"
+                           placeholder="[email protected]" />
+                  </div>
+                </label>
+              </div>
+              <p class="help-block">Add a new user account or edit an existing 
one.</p>
+              <div class="buttons">
+                <input py:if="create_enabled"
+                       type="submit" class="btn" name="add"
+                       value="${dgettext('acct_mgr', ' Add ')}" />
+                <input type="submit" class="btn" name="change"
+                       value="${dgettext('acct_mgr', ' Change ')}" />
+              </div>
+            </fieldset>
+          </form>
+        </div>
+      </div>
+
+      <div class="span9">
+        <py:choose>
+        <div py:when="not listing_enabled" class="system-message">
+          <xi:include href="widget_alert.html"
+                      py:with="msglabel = 'Warning';
+                               msgbody = _('This password store does not 
support listing users.')"/>
+        </div>
+        <form py:otherwise="" method="post"  py:strip="not delete_enabled">
+          <div>
+            <table id="accountlist"
+                   class="listing table table-striped table-condensed 
table-bordered" >
+              <thead>
+                <tr>
+                  <th py:if="delete_enabled" class="sel">
+                    <i class="icon-check"></i>
+                  </th>
+                  <th>Account</th><th>Name</th><th>Email</th><th>Last 
Login</th>
+                </tr>
+              </thead>
+              <tbody>
+                <tr py:for="acct in accounts">
+                  <td py:if="delete_enabled">
+                    <input type="checkbox" name="sel" value="${acct.username}" 
/>
+                  </td>
+                  <td>
+                    <a href="${acct.review_url}">$acct.username</a>
+                    <!--! Additional account status icons -->
+                    <py:choose py:if="acct.locked">
+                      <img py:when="acct.release_hint" alt="Account locked"
+                           src="${href.chrome('/acct_mgr/time-locked.png')}"
+                           title="${acct.release_hint}" />
+                      <img py:otherwise="" alt="Permanently locked"
+                           src="${href.chrome('/acct_mgr/locked.png')}"
+                           title="${dgettext('acct_mgr', 'Permanently 
locked')}" />
+                    </py:choose>
+                  </td>
+                  <td>$acct.name</td>
+                  <td>$acct.email</td>
+                  <td>$acct.last_visit</td>
+                </tr>
+              </tbody>
+            </table>
+          </div>
+          <div class="buttons">
+            <input type="submit" name="reset" class="btn"
+                   py:if="password_reset_enabled"
+                   value="${dgettext('acct_mgr', 'Reset passwords')}" />
+            <input type="submit" name="remove" class="btn"
+                   py:if="delete_enabled"
+                   value="${dgettext('acct_mgr', 'Remove selected accounts')}" 
/>
+          </div>
+        </form>
+        </py:choose>
+      </div>
+    </div>
+  </body>
+</html>

Modified: bloodhound/trunk/bloodhound_theme/bhtheme/theme.py
URL: 
http://svn.apache.org/viewvc/bloodhound/trunk/bloodhound_theme/bhtheme/theme.py?rev=1492038&r1=1492037&r2=1492038&view=diff
==============================================================================
--- bloodhound/trunk/bloodhound_theme/bhtheme/theme.py (original)
+++ bloodhound/trunk/bloodhound_theme/bhtheme/theme.py Wed Jun 12 03:34:33 2013
@@ -141,9 +141,11 @@ class BloodhoundTheme(ThemeBase):
         'timeline.html' : ('bh_timeline.html', None),
 
         # Account manager plugin
+        'account_details.html': ('bh_account_details.html', None),
+        'admin_accountsconfig.html': ('bh_admin_accountsconfig.html', None),
+        'admin_users.html': ('bh_admin_users.html', None),
         'login.html' : ('bh_login.html', None),
         'prefs_account.html' : ('bh_prefs_account.html', None),
-        'admin_accountsconfig.html' : ('bh_admin_accountsconfig.html', None),
     }
     BOOTSTRAP_CSS_DEFAULTS = (
         # ('XPath expression', ['default', 'bootstrap', 'css', 'classes'])


Reply via email to