Changeset 5087


Ignore:
Timestamp:
10/03/09 13:31:56 (10 years ago)
Author:
pjkersha
Message:

Moved DemoRenderingInterface? from ndg.security.server.wsgi.openid.provider into it's own module ndg.security.server.wsgi.openid.provider.renderinginterface.demo

Location:
TI12-security/trunk/python
Files:
15 added
6 edited

Legend:

Unmodified
Added
Removed
  • TI12-security/trunk/python/ndg.security.common/ndg/security/common/authz/pdp/xacml.py

    r5005 r5087  
    5151        raise NotImplementedError() 
    5252        
    53 class DenyEffect(object): 
     53class DenyEffect(Effect): 
    5454    def __str__(self): 
    5555        return 'deny' 
    5656         
    57 class PermitEffect(object): 
     57class PermitEffect(Effect): 
    5858    def __str__(self): 
    5959        return 'permit' 
  • TI12-security/trunk/python/ndg.security.server/ndg/security/server/wsgi/openid/provider/__init__.py

    r5084 r5087  
    1414import httplib 
    1515import sys 
    16 import cgi 
    1716import os 
    1817import logging 
     
    3130 
    3231from ndg.security.server.wsgi import NDGSecurityMiddlewareBase 
    33  
    34 quoteattr = lambda s: '"%s"' % cgi.escape(s, 1) 
    3532 
    3633 
     
    14811478        return response 
    14821479         
    1483      
    1484 class DemoRenderingInterface(RenderingInterface): 
    1485     """Example rendering interface class for demonstration purposes""" 
    1486     
    1487     def identityPage(self, environ, start_response): 
    1488         """Render the identity page. 
    1489          
    1490         @type environ: dict 
    1491         @param environ: dictionary of environment variables 
    1492         @type start_response: callable 
    1493         @param start_response: WSGI start response function.  Should be called 
    1494         from this method to set the response code and HTTP header content 
    1495         @rtype: basestring 
    1496         @return: WSGI response 
    1497         """ 
    1498         path = environ.get('PATH_INFO').rstrip('/') 
    1499         userIdentifier = path.split('/')[ - 1] 
    1500          
    1501         link_tag = '<link rel="openid.server" href="%s">' % \ 
    1502               self.urls['url_openidserver'] 
    1503                
    1504         yadis_loc_tag = '<meta http-equiv="x-xrds-location" content="%s">' % \ 
    1505             (self.urls['url_yadis'] + '/' + userIdentifier) 
    1506              
    1507         disco_tags = link_tag + yadis_loc_tag 
    1508         ident = self.base_url + path 
    1509  
    1510         response = self._showPage(environ, 
    1511                                   'Identity Page', 
    1512                                   head_extras=disco_tags, 
    1513                                   msg='<p>This is the identity page for %s.' 
    1514                                       '</p>' % ident) 
    1515          
    1516         start_response("200 OK", 
    1517                        [('Content-type', 'text/html' + self.charset), 
    1518                         ('Content-length', str(len(response)))]) 
    1519         return response 
    1520      
    1521          
    1522     def login(self, environ, start_response, 
    1523               success_to=None, fail_to=None, msg=''): 
    1524         """Render the login form. 
    1525          
    1526         @type environ: dict 
    1527         @param environ: dictionary of environment variables 
    1528         @type success_to: basestring 
    1529         @param success_to: URL put into hidden field telling   
    1530         OpenIDProviderMiddleware.do_loginsubmit() where to forward to on  
    1531         successful login 
    1532         @type fail_to: basestring 
    1533         @param fail_to: URL put into hidden field telling   
    1534         OpenIDProviderMiddleware.do_loginsubmit() where to forward to on  
    1535         login error 
    1536         @type msg: basestring 
    1537         @param msg: display (error) message below login form e.g. following 
    1538         previous failed login attempt. 
    1539         @rtype: basestring 
    1540         @return: WSGI response 
    1541         """ 
    1542          
    1543         if success_to is None: 
    1544             success_to = self.urls['url_mainpage'] 
    1545              
    1546         if fail_to is None: 
    1547             fail_to = self.urls['url_mainpage'] 
    1548          
    1549         form = '''\ 
    1550 <h2>Login</h2> 
    1551 <form method="GET" action="%s"> 
    1552   <input type="hidden" name="success_to" value="%s" /> 
    1553   <input type="hidden" name="fail_to" value="%s" /> 
    1554   <table cellspacing="0" border="0" cellpadding="5"> 
    1555     <tr> 
    1556         <td>Username:</td>  
    1557         <td><input type="text" name="username" value=""/></td> 
    1558     </tr><tr> 
    1559         <td>Password:</td> 
    1560         <td><input type="password" name="password"/></td> 
    1561     </tr><tr> 
    1562         <td colspan="2" align="right"> 
    1563             <input type="submit" name="submit" value="Login"/> 
    1564             <input type="submit" name="cancel" value="Cancel"/> 
    1565         </td> 
    1566     </tr> 
    1567   </table> 
    1568 </form> 
    1569 %s 
    1570 ''' % (self.urls['url_loginsubmit'], success_to, fail_to, msg) 
    1571  
    1572         response = self._showPage(environ, 'Login Page', form=form) 
    1573         start_response('200 OK', 
    1574                        [('Content-type', 'text/html' + self.charset), 
    1575                         ('Content-length', str(len(response)))]) 
    1576         return response 
    1577  
    1578  
    1579     def mainPage(self, environ, start_response): 
    1580         """Rendering the main page. 
    1581          
    1582         @type environ: dict 
    1583         @param environ: dictionary of environment variables 
    1584         @type start_response: callable 
    1585         @param start_response: WSGI start response function.  Should be called 
    1586         from this method to set the response code and HTTP header content 
    1587         @rtype: basestring 
    1588         @return: WSGI response 
    1589         """ 
    1590          
    1591         yadis_tag = '<meta http-equiv="x-xrds-location" content="%s">' % \ 
    1592                     self.urls['url_serveryadis'] 
    1593         username = environ['beaker.session'].get('username')     
    1594         if username: 
    1595             openid_url = self.urls['url_id'] + '/' + username 
    1596             user_message = """\ 
    1597             <p>You are logged in as %s. Your OpenID identity URL is 
    1598             <tt><a href=%s>%s</a></tt>. Enter that URL at an OpenID 
    1599             consumer to test this server.</p> 
    1600             """ % (username, quoteattr(openid_url), openid_url) 
    1601         else: 
    1602             user_message = "<p>You are not <a href='%s'>logged in</a>.</p>" % \ 
    1603                             self.urls['url_login'] 
    1604  
    1605         msg = '''\ 
    1606 <p>OpenID server</p> 
    1607  
    1608 %s 
    1609  
    1610 <p>The URL for this server is <a href=%s><tt>%s</tt></a>.</p> 
    1611 ''' % (user_message, quoteattr(self.base_url), self.base_url) 
    1612         response = self._showPage(environ, 
    1613                                   'Main Page', 
    1614                                   head_extras=yadis_tag, 
    1615                                   msg=msg) 
    1616      
    1617         start_response('200 OK', 
    1618                        [('Content-type', 'text/html' + self.charset), 
    1619                         ('Content-length', str(len(response)))]) 
    1620         return response 
    1621      
    1622  
    1623     def decidePage(self, environ, start_response, oidRequest): 
    1624         """Show page giving the user the option to approve the return of their 
    1625         credentials to the Relying Party.  This page is also displayed for 
    1626         ID select mode if the user is already logged in at the OpenID Provider. 
    1627         This enables them to confirm the OpenID to be sent back to the  
    1628         Relying Party 
    1629          
    1630         @type environ: dict 
    1631         @param environ: dictionary of environment variables 
    1632         @type start_response: callable 
    1633         @param start_response: WSGI start response function.  Should be called 
    1634         from this method to set the response code and HTTP header content 
    1635         @type oidRequest: openid.server.server.CheckIDRequest 
    1636         @param oidRequest: OpenID Check ID Request object 
    1637         @rtype: basestring 
    1638         @return: WSGI response 
    1639         """ 
    1640         idURLBase = self.urls['url_id'] + '/' 
    1641          
    1642         # XXX: This may break if there are any synonyms for idURLBase, 
    1643         # such as referring to it by IP address or a CNAME. 
    1644          
    1645         # TODO: OpenID 2.0 Allows oidRequest.identity to be set to  
    1646         # http://specs.openid.net/auth/2.0/identifier_select.  See, 
    1647         # http://openid.net/specs/openid-authentication-2_0.html.  This code 
    1648         # implements this overriding the behaviour of the example code on 
    1649         # which this is based.  - Check is the example code based on OpenID 1.0 
    1650         # and therefore wrong for this behaviour? 
    1651 #        assert oidRequest.identity.startswith(idURLBase), \ 
    1652 #               repr((oidRequest.identity, idURLBase)) 
    1653         userIdentifier = oidRequest.identity[len(idURLBase):] 
    1654         username = environ['beaker.session']['username'] 
    1655          
    1656         if oidRequest.idSelect(): # We are being asked to select an ID 
    1657             userIdentifier = self._authN.username2UserIdentifiers(environ, 
    1658                                                                   username)[0] 
    1659             identity = idURLBase + userIdentifier 
    1660              
    1661             msg = '''\ 
    1662             <p>A site has asked for your identity.  You may select an 
    1663             identifier by which you would like this site to know you. 
    1664             On a production site this would likely be a drop down list 
    1665             of pre-created accounts or have the facility to generate 
    1666             a random anonymous identifier. 
    1667             </p> 
    1668             ''' 
    1669             fdata = { 
    1670                 'pathAllow': self.urls['url_allow'], 
    1671                 'identity': identity, 
    1672                 'trust_root': oidRequest.trust_root, 
    1673                 } 
    1674             form = '''\ 
    1675 <form method="POST" action="%(pathAllow)s"> 
    1676 <table> 
    1677   <tr><td>Identity:</td> 
    1678      <td>%(identity)s</td></tr> 
    1679   <tr><td>Trust Root:</td><td>%(trust_root)s</td></tr> 
    1680 </table> 
    1681 <p>Allow this authentication to proceed?</p> 
    1682 <input type="checkbox" id="remember" name="remember" value="Yes" 
    1683     /><label for="remember">Remember this 
    1684     decision</label><br /> 
    1685 <input type="hidden" name="identity" value="%(identity)s" /> 
    1686 <input type="submit" name="Yes" value="Yes" /> 
    1687 <input type="submit" name="No" value="No" /> 
    1688 </form> 
    1689 ''' % fdata 
    1690              
    1691         elif userIdentifier in self._authN.username2UserIdentifiers(environ, 
    1692                                                                     username): 
    1693             msg = '''\ 
    1694             <p>A new site has asked to confirm your identity.  If you 
    1695             approve, the site represented by the trust root below will 
    1696             be told that you control identity URL listed below. (If 
    1697             you are using a delegated identity, the site will take 
    1698             care of reversing the delegation on its own.)</p>''' 
    1699  
    1700             fdata = { 
    1701                 'pathAllow': self.urls['url_allow'], 
    1702                 'identity': oidRequest.identity, 
    1703                 'trust_root': oidRequest.trust_root, 
    1704                 } 
    1705             form = '''\ 
    1706 <table> 
    1707   <tr><td>Identity:</td><td>%(identity)s</td></tr> 
    1708   <tr><td>Trust Root:</td><td>%(trust_root)s</td></tr> 
    1709 </table> 
    1710 <p>Allow this authentication to proceed?</p> 
    1711 <form method="POST" action="%(pathAllow)s"> 
    1712   <input type="checkbox" id="remember" name="remember" value="Yes" 
    1713       /><label for="remember">Remember this 
    1714       decision</label><br /> 
    1715   <input type="submit" name="Yes" value="Yes" /> 
    1716   <input type="submit" name="No" value="No" /> 
    1717 </form>''' % fdata 
    1718         else: 
    1719             mdata = { 
    1720                 'userIdentifier': userIdentifier, 
    1721                 'username': username, 
    1722                 } 
    1723             msg = '''\ 
    1724             <p>A site has asked for an identity belonging to 
    1725             %(userIdentifier)s, but you are logged in as %(username)s.  To 
    1726             log in as %(userIdentifier)s and approve the login oidRequest, 
    1727             hit OK below.  The "Remember this decision" checkbox 
    1728             applies only to the trust root decision.</p>''' % mdata 
    1729  
    1730             fdata = { 
    1731                 'pathAllow': self.urls['url_allow'], 
    1732                 'identity': oidRequest.identity, 
    1733                 'trust_root': oidRequest.trust_root, 
    1734                 'username': username, 
    1735                 } 
    1736             form = '''\ 
    1737 <table> 
    1738   <tr><td>Identity:</td><td>%(identity)s</td></tr> 
    1739   <tr><td>Trust Root:</td><td>%(trust_root)s</td></tr> 
    1740 </table> 
    1741 <p>Allow this authentication to proceed?</p> 
    1742 <form method="POST" action="%(pathAllow)s"> 
    1743   <input type="checkbox" id="remember" name="remember" value="Yes" 
    1744       /><label for="remember">Remember this 
    1745       decision</label><br /> 
    1746   <input type="hidden" name="login_as" value="%(username)s"/> 
    1747   <input type="submit" name="Yes" value="Yes" /> 
    1748   <input type="submit" name="No" value="No" /> 
    1749 </form>''' % fdata 
    1750  
    1751         response = self._showPage(environ, 'Approve OpenID request?', 
    1752                                   msg=msg, form=form)             
    1753         start_response('200 OK', 
    1754                        [('Content-type', 'text/html' + self.charset), 
    1755                         ('Content-length', str(len(response)))]) 
    1756         return response 
    1757      
    1758  
    1759     def _showPage(self, 
    1760                   environ, 
    1761                   title, 
    1762                   head_extras='', 
    1763                   msg=None, 
    1764                   err=None, 
    1765                   form=None): 
    1766         """Generic page rendering method.  Derived classes may ignore this. 
    1767          
    1768         @type environ: dict 
    1769         @param environ: dictionary of environment variables 
    1770         @type title: basestring 
    1771         @param title: page title 
    1772         @type head_extras: basestring 
    1773         @param head_extras: add extra HTML header elements 
    1774         @type msg: basestring 
    1775         @param msg: optional message for page body 
    1776         @type err: basestring 
    1777         @param err: optional error message for page body 
    1778         @type form: basestring 
    1779         @param form: optional form for page body         
    1780         @rtype: basestring 
    1781         @return: WSGI response 
    1782         """ 
    1783          
    1784         username = environ['beaker.session'].get('username') 
    1785         if username is None: 
    1786             user_link = '<a href="/login">not logged in</a>.' 
    1787         else: 
    1788             user_link = 'logged in as <a href="%s/%s">%s</a>.<br />'\ 
    1789                         '<a href="%s?submit=true&'\ 
    1790                         'success_to=%s">Log out</a>' % \ 
    1791                         (self.urls['url_id'], username, username, 
    1792                          self.urls['url_loginsubmit'], 
    1793                          self.urls['url_login']) 
    1794  
    1795         body = '' 
    1796  
    1797         if err is not None: 
    1798             body += '''\ 
    1799             <div class="error"> 
    1800               %s 
    1801             </div> 
    1802             ''' % err 
    1803  
    1804         if msg is not None: 
    1805             body += '''\ 
    1806             <div class="message"> 
    1807               %s 
    1808             </div> 
    1809             ''' % msg 
    1810  
    1811         if form is not None: 
    1812             body += '''\ 
    1813             <div class="form"> 
    1814               %s 
    1815             </div> 
    1816             ''' % form 
    1817  
    1818         contents = { 
    1819             'title': 'Python OpenID Provider - ' + title, 
    1820             'head_extras': head_extras, 
    1821             'body': body, 
    1822             'user_link': user_link, 
    1823             } 
    1824  
    1825         response = '''<html> 
    1826   <head> 
    1827     <title>%(title)s</title> 
    1828     %(head_extras)s 
    1829   </head> 
    1830   <style type="text/css"> 
    1831       h1 a:link { 
    1832           color: black; 
    1833           text-decoration: none; 
    1834       } 
    1835       h1 a:visited { 
    1836           color: black; 
    1837           text-decoration: none; 
    1838       } 
    1839       h1 a:hover { 
    1840           text-decoration: underline; 
    1841       } 
    1842       body { 
    1843         font-family: verdana,sans-serif; 
    1844         width: 50em; 
    1845         margin: 1em; 
    1846       } 
    1847       div { 
    1848         padding: .5em; 
    1849       } 
    1850       table { 
    1851         margin: none; 
    1852         padding: none; 
    1853       } 
    1854       .banner { 
    1855         padding: none 1em 1em 1em; 
    1856         width: 100%%; 
    1857       } 
    1858       .leftbanner { 
    1859         text-align: left; 
    1860       } 
    1861       .rightbanner { 
    1862         text-align: right; 
    1863         font-size: smaller; 
    1864       } 
    1865       .error { 
    1866         border: 1px solid #ff0000; 
    1867         background: #ffaaaa; 
    1868         margin: .5em; 
    1869       } 
    1870       .message { 
    1871         border: 1px solid #2233ff; 
    1872         background: #eeeeff; 
    1873         margin: .5em; 
    1874       } 
    1875       .form { 
    1876         border: 1px solid #777777; 
    1877         background: #ddddcc; 
    1878         margin: .5em; 
    1879         margin-top: 1em; 
    1880         padding-bottom: 0em; 
    1881       } 
    1882       dd { 
    1883         margin-bottom: 0.5em; 
    1884       } 
    1885   </style> 
    1886   <body> 
    1887     <table class="banner"> 
    1888       <tr> 
    1889         <td class="leftbanner"> 
    1890           <h1><a href="/">Python OpenID Provider</a></h1> 
    1891         </td> 
    1892         <td class="rightbanner"> 
    1893           You are %(user_link)s 
    1894         </td> 
    1895       </tr> 
    1896     </table> 
    1897 %(body)s 
    1898   </body> 
    1899 </html> 
    1900 ''' % contents 
    1901  
    1902         return response 
    1903  
    1904     def errorPage(self, environ, start_response, msg, code=500): 
    1905         """Display error page  
    1906          
    1907         @type environ: dict 
    1908         @param environ: dictionary of environment variables 
    1909         @type start_response: callable 
    1910         @param start_response: WSGI start response function.  Should be called 
    1911         from this method to set the response code and HTTP header content 
    1912         @type msg: basestring 
    1913         @param msg: optional message for page body 
    1914         @rtype: basestring 
    1915         @return: WSGI response 
    1916         """ 
    1917          
    1918         response = self._showPage(environ, 'Error Processing Request', err='''\ 
    1919         <p>%s</p> 
    1920         <!-- 
    1921  
    1922         This is a large comment.  It exists to make this page larger. 
    1923         That is unfortunately necessary because of the "smart" 
    1924         handling of pages returned with an error code in IE. 
    1925  
    1926         ************************************************************* 
    1927         ************************************************************* 
    1928         ************************************************************* 
    1929         ************************************************************* 
    1930         ************************************************************* 
    1931         ************************************************************* 
    1932         ************************************************************* 
    1933         ************************************************************* 
    1934         ************************************************************* 
    1935         ************************************************************* 
    1936         ************************************************************* 
    1937         ************************************************************* 
    1938         ************************************************************* 
    1939         ************************************************************* 
    1940         ************************************************************* 
    1941         ************************************************************* 
    1942         ************************************************************* 
    1943         ************************************************************* 
    1944         ************************************************************* 
    1945         ************************************************************* 
    1946         ************************************************************* 
    1947         ************************************************************* 
    1948         ************************************************************* 
    1949  
    1950         --> 
    1951         ''' % msg) 
    1952          
    1953         start_response('%d %s' % (code, httplib.responses[code]), 
    1954                        [('Content-type', 'text/html' + self.charset), 
    1955                         ('Content-length', str(len(response)))]) 
    1956         return response 
  • TI12-security/trunk/python/ndg.security.server/ndg/security/server/wsgi/openid/provider/authninterface/sessionmanager.py

    r5080 r5087  
    55Manager SOAP interface 
    66 
    7 NERC Data Grid Project 
    8  
     7NERC DataGrid Project 
    98""" 
    109__author__ = "P J Kershaw" 
    1110__date__ = "01/08/08" 
    1211__copyright__ = "(C) 2009 Science and Technology Facilities Council" 
     12__license__ = "BSD - see LICENSE file in top-level directory" 
    1313__contact__ = "Philip.Kershaw@stfc.ac.uk" 
    1414__revision__ = "$Id$" 
  • TI12-security/trunk/python/ndg.security.server/ndg/security/server/wsgi/pep/__init__.py

    r5037 r5087  
    8888            url = 'http://' + serverName + self.mountPath + self.pathInfo 
    8989            return self._redirect(start_response, url) 
    90          
    91          
    92     def _redirect(self, start_response, url): 
    93         """Do a HTTP 302 redirect 
    94          
    95         @type start_response: callable following WSGI start_response convention 
    96         @param start_response: WSGI start response callable 
    97         @type url: basestring 
    98         @param url: URL to redirect to 
    99         @rtype: list 
    100         @return: empty HTML body 
    101         """ 
    102         start_response('302 %s' % httplib.responses[302],  
    103                        [('Content-type', 'text/html'+self.charset), 
    104                         ('Location', url)]) 
    105         return [] 
    10690 
  • TI12-security/trunk/python/ndg.security.test/ndg/security/test/integration/authz/securedapp.ini

    r5086 r5087  
    2727#beaker.session.key = sso 
    2828beaker.session.secret = somesecret 
     29beaker.session.type = cookie 
     30beaker.session.validate_key = 0123456789abcdef 
     31beaker.session.encrypt_key = fedcba9876543210 
    2932 
    3033# If you'd like to fine-tune the individual locations of the cache data dirs 
  • TI12-security/trunk/python/ndg.security.test/ndg/security/test/integration/authz/securityservices.ini

    r5086 r5087  
    180180#beaker.session.key = sso 
    181181beaker.session.secret = somesecret 
     182beaker.session.type = cookie 
     183beaker.session.validate_key = 0123456789abcdef 
     184beaker.session.encrypt_key = fedcba9876543210 
    182185 
    183186# If you'd like to fine-tune the individual locations of the cache data dirs 
Note: See TracChangeset for help on using the changeset viewer.