Basic Auth with tabs - jordy33/turbogears_tutorial GitHub Wiki

This is the second part of the Basic Auth Tutorial

From this link Include this directories to the public folder

Update setup.py with the following ti ebavke urllib3:

install_requires = [
    "TurboGears2 >= 2.3.12",
    "Beaker >= 1.8.0",
    "Kajiki >= 0.6.3",
    "Mako",
    "zope.sqlalchemy >= 0.4",
    "sqlalchemy",
    "alembic",
    "repoze.who",
    "tw2.forms",
    "tgext.admin >= 0.6.1",
    "WebHelpers2",
    "urllib3==1.22"
]

Update app_globals with the following:

# -*- coding: utf-8 -*-

"""The application's Globals object"""

__all__ = ['Globals']

import os
import urllib3

class Globals(object):
    """Container for objects available throughout the life of the application.

    One instance of Globals is created during application initialization and
    is available during requests via the 'app_globals' variable.

    """

    def __init__(self):
        """Do nothing, by default."""
        urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)

        # Server parameters

        self.host_secure = os.getenv('MYPROJECT_SECURE')
        if self.host_secure is None:
            self.host_secure="False"

        if self.host_secure=="False":
            host_prefix="http://"
        else:
            host_prefix="https://"

        self.host_prefix=host_prefix

        host_port=os.getenv('MYPROJECT_PORT')
        if host_port is None:
            host_port=""

        if len(host_port)>0:
            self.host_port=":"+host_port
        else:
            self.host_port=""

        self.host=os.getenv('MYPROJECT_HOST')
        if self.host is None:
            self.host=host_prefix+"localhost:8080"
        else:
            self.host=host_prefix+self.host

        self.app_dir = os.getenv('MYPROJECT_DIR')
        if self.app_dir is None:
            self.app_dir=os.getcwd()

        # STOMP parameters
        self.stomp_secure=os.getenv('STOMP_SECURE')
        if self.stomp_secure is None:
            self.stomp_secure="True"

        if self.stomp_secure=="False":
            stomp_prefix="ws://"
        else:
            stomp_prefix="wss://"

        stomp_port=os.getenv('STOMP_PORT')
        if stomp_port is None:
            stomp_port=""
        if len(stomp_port)>1:
            self.stomp_port=":"+stomp_port
        else:
            self.stomp_port=""

        self.stompHost = os.getenv('STOMP_HOST')
        if self.stompHost is None:
            self.stompHost = "stomp.dudewhereismy.mx"

        self.stompUserName = os.getenv('STOMP_MASTER_USER')
        if self.stompUserName is None:
            self.stompUserName = "dwim"

        self.stompPassword = os.getenv('STOMP_MASTER_PASS')
        if self.stompPassword  is None:
            self.stompPassword = "gpscontrol1"

        self.stompServer=stomp_prefix+self.stompHost+':15671'+'/ws'

        # Telefonica Test parameters
        cert_file_path = self.app_dir + "/telefonica.cer"
        key_file_path = self.app_dir + "/telefonica.key"
        self.cert = (cert_file_path, key_file_path)
        self.apiUser="customer-DUDE_WHERE_IS_MY156320dc8168LfDu"
        if os.getenv('SUN_SECURE')=="True":
            self.domainsun="https://"+os.getenv('SUN_HOST')
        else:
            self.domainsun = "http://" + os.getenv('SUN_HOST')

        if os.getenv('PLUTO_SECURE') == "True":
            self.domainpluto="https://"+os.getenv('PLUTO_HOST')
        else:
            self.domainpluto = "http://" + os.getenv('PLUTO_HOST')

        self.sunUsers = os.getenv('SUN_USERS')
        if self.sunUsers is None:
            self.sunUsers=self.domainsun+"/services/users"

        self.sunGroups = os.getenv('SUN_GROUPS')
        if self.sunGroups is None:
            self.sunGroups = self.domainsun+"/services/groups"

        self.sunApplications=self.domainsun+"/services/applications?internal_id=2"
        self.sunapps = self.domainsun + "/services/apps"

        self.telefonicaPosition="https://m2m-api.telefonica.com:8010/services/REST/GlobalM2M/Inventory/v5/r12/sim/icc:"
        self.opencell="http://opencellid.org/cell/get"
        self.opencellkey="2a87df53b26d3e"

Update helpers.py

# -*- coding: utf-8 -*-
"""Template Helpers used in myprojectname."""
import logging
from markupsafe import Markup
from datetime import datetime
from tg import request
from myprojectname.model import DBSession,User, Permission
from tg import app_globals
log = logging.getLogger(__name__)

def current_year():
    now = datetime.now()
    return now.strftime('%Y')

def today():
    now = datetime.now()
    return now.strftime('%d / %m / %y')

def icon(icon_name):
    return Markup('<i class="glyphicon glyphicon-%s"></i>' % icon_name)

def badge():
    if request.identity is None:
        counter = 0
    else:
        identity = request.identity['repoze.who.userid']
        user = DBSession.query(User).filter_by(user_name=identity).first()
        counter = 0
    return '' if counter == 0 else str(counter)

def whoami():
    try:
        ret=request.identity["repoze.who.userid"]
    except:
        return ""
    else:
        return ret

def password():
        return 'gpscontrol1'

def perm(name):
    identity = request.identity['repoze.who.userid']
    user = DBSession.query(User).filter_by(user_name=identity).first()
    perm = Permission.exist(u''+name+'',user.groups)
    if perm == "si":
        return True
    else:
        return False

# def url():
#     return app_globals.host

def url():
    return app_globals.host
    #"https://dispatch.dudewhereismy.mx"

def stompServer():
    return app_globals.stompServer

def stompUser():
    return app_globals.stompUserName

def stompPassword():
    return app_globals.stompPassword

# Import commonly used helpers from WebHelpers2 and TG
from tg.util.html import script_json_encode

try:
    from webhelpers2 import date, html, number, misc, text
except SyntaxError:
    log.error("WebHelpers2 helpers not available with this Python Version")

Update master.mak

<!DOCTYPE html>
<html>
<head>
    ${self.meta()}
    <title>${self.title()}</title>
	<meta name="viewport" content="width=device-width, initial-scale=1.0">
    <script type="text/ecmascript" src="${tg.url('/lib/js/jquery-1.11.0.js')}"></script>
    <script src="${tg.url('/lib/js/bootstrap.min.js')}"></script>
    <script type="text/ecmascript" src="${tg.url('/lib/js/grid.locale-es.js')}"></script>
    <!-- This is the Javascript file of jqGrid -->
    <script type="text/ecmascript" src="${tg.url('/lib/js/jquery.jqgrid.src.js')}"></script>
    <script type="text/ecmascript" src="${tg.url('/lib/js/jquery-ui.min.js')}"></script>
    <link rel="stylesheet" type="text/css" media="screen" href="${tg.url('/lib/css/jquery-ui.css')}" />
    <!-- The link to the CSS that the grid needs -->
    <link rel="stylesheet" type="text/css" media="screen" href="${tg.url('/lib/css/ui.jqgrid.css')}"  />
    <link href="${tg.url('/lib/fonts/font-awesome.min.css')}" rel="stylesheet" />
    <meta charset="utf-8" />
    <title>MyProjectName</title>

    <link href="${tg.url('/lib/css/bootstrap.min.css')}" rel="stylesheet">
    <script src="${tg.url('/lib/stomp/stomp.js')}"></script>
    <script src="${tg.url('/lib/moment/moment.js')}"></script>
    <script src="${tg.url('/lib/js/alert.js')}"></script>
    <script src="${tg.url('/lib/justgage/raphael-2.1.4.min.js')}"></script>
    <script src="${tg.url('/lib/justgage/justgage.js')}"></script>
    <script src="${tg.url('/lib/jqueryrotate/jQueryRotate.js')}"></script>
    <script src="${tg.url('/lib/jquery-validation-1.17.0/dist/jquery.validate.js')}"></script>

    <script src="${tg.url('/lib/timepicker/jquery-ui-timepicker-addon.js')}"></script>

    <style type="text/css">
        input { box-shadow: 0 0 3px #CC0000; margin: 10px }

        .dropdown {
          background: rgba(255, 255, 255, 0.1);
          float: left;
          margin: 10px 8px;
          padding: 0px;
          border-radius: 4px;
          list-style-type: none;}

        .dropdown a.dropdown-toggle {
          height: 40px;
          width: 40px;
          padding-top: 11px;
          padding-left: 9px; }

        .dropdown:hover {
          color: #fff;
          background: rgba(255, 255, 255, 0.2); }

        .dropdown .label {
          top: -4px;
          left: 22px;
          padding-top: 4px;
          padding-bottom: 4px;
          position: absolute;
          border-radius: 9999px; }

            .profile-sidebar {
          padding: 10px 0;
          border-bottom: 1px solid #e9ecf2; }
        .label-success {
          background-color: #8ad919; }
        .label-danger {
          background-color: #f9243f; }
        .profile-userpic img {
          float: left;
          margin: 10px 0px 0px 15px;
          width: 50px;
          height: 50px;
          border-radius: 9999px !important; }

        .profile-usertitle {
          float: left;
          text-align: left;
          margin: 10px 0 0 12px; }

        .profile-usertitle-name {
          font-size: 15px;
          margin-bottom: 0px; }

        .profile-usertitle-status {
          text-transform: uppercase;
          color: #AAA;
          font-size: 10px;
          font-weight: 600;
          margin-bottom: 15px; }
        .indicator {
          width: 10px;
          height: 10px;
          display: inline-block;
          border-radius: 9999px;
          margin-right: 5px; }

        .error { color: #F00; background-color: #f1f4f3; }
        div.dialog-hidden { display:none}
        html, body { margin: 0; padding: 0;}
</style>

    <!-- Global JavaScript -->
    <script type="text/javascript">
    function logout() {
            var i = document.childNodes.length - 1;
            while (i >= 0) {
              console.log(document.childNodes[i]);
              document.removeChild(document.childNodes[i--]);
            }
            jQuery.ajax({
                    type: "GET",
                    url: "/secc",
                    username: "logmeout",
                    password: "123456",
                    headers: { "Authorization": "Basic xxx" }
            })
            .done(function(){
                // If we don't get an error, we actually got an error as we expect an 401!
            })
            .fail(function(){
                // We expect to get an 401 Unauthorized error! In this case we are successfully
                    // logged out and we redirect the user.
                window.location = "/";
            });

            return false;
    }

    var username = 'manager';
    var password = 'managepass';

    function make_base_auth(user, password) {
        var tok = user + ':' + password;
        var hash = btoa(tok);
        return "Basic " + hash;
    }
    function doAjax(pageName,id) {
        $.ajax({
            url:pageName ,
            error: function () {
                alert("Error de credenciales con otro planeta");
            },
            beforeSend: function(xhr){
            xhr.setRequestHeader("Content-Type","application/json");
            xhr.setRequestHeader("Accept","application/json");
            xhr.setRequestHeader( "Authorization", make_base_auth(username,password));
            },
            dataType: 'html',
            data: { user: "${h.whoami()}", id:id } ,
            success: function (data, rq) {
                $("#loader"+id).html('');
                 $("#"+id).html(data);
            },
            error: function (data, rq) {
                $("#"+id).html("<p>Error</p>");
            },
            type: 'GET'
        });
    }
    function openTab(text,url) {
        var num_tabs = $("div#tabs ul.main1 li.main1").length + 1;
        var mytext= text;
        var id = "frame"+num_tabs;
        doAjax(url,id);
        $("div#tabs ul.main1").append(
            "<li class='main1'><a href='#tab"+num_tabs+"'>"+mytext+"</a><span class='ui-icon ui-icon-close' role='presentation'>Remove Tab</span></li>"
        );
        $("div#tabs").append(
            "<div id='tab"+num_tabs+"'> <div class='row'><div class='col-lg-12'><div id='"+id+"' style='margin:10px'></div><div id='loader"+id+"' class='cygnus'><span style='float:left;width: 20%;'><p>Cargando ...</p></span><span style='float:right;width: 80%;'><img src=${tg.url('/img/ajax-loader.gif')}></span></div></div></div></div>"
        );
        var $head = $("#"+id).contents().find("head");

        var ur="${tg.url('/css/theme/jquery-ui1.css')}";
        $head.append($("<link/>",
                { rel: "stylesheet", href:ur, type: "text/css" }
              ));

        $("div#tabs").tabs("refresh").tabs('option', 'active', num_tabs - 1);
    }
    $(document).ready(function() {

        $("div#tabs").tabs();

        $( "#tabs" ).tabs().on( "click", "span.ui-icon-close", function() {
          var num_tabs = $("div#tabs ul li").length + 1;
          var panelId = $( this ).closest( "li" ).remove().attr( "aria-controls" );
          $( "#" + panelId ).remove();
          $("div#tabs").tabs("refresh").tabs('option', 'active', num_tabs - 1);
        });

    });
    </script>
    ${self.head_content()}
</head>

% if tg.auth_stack_enabled:
  % if not request.identity:
       <meta http-equiv="refresh" content="0; url=${tg.url('/main')}" />

  % else:
        <body class="${self.body_class()}">
          ${self.main_menu()}
          ${self.footer()}
        <!-- Insert nice scrool -->
          ${self.bottom_scripts()}
  % endif
% endif

<%def name="meta()">
    <meta charset="${response.charset}" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta name="description" content="Bootstrap 3 App">
    <meta name="author" content="Jorge Macias & Maria Lacayo">
    <meta name="keyword" content="Sun">
    <meta name="viewport" content="initial-scale=1.0">
    <meta charset="utf-8">
</%def>

<%def name="title()">  </%def>

<%def name="head_content()"></%def>

<%def name="body_class()"></%def>

<%def name="main_menu()">
  <!-- INSERT MAIN MENU -->
<nav>
      <table style="width: 100%"  class=" ui-tabs-panel ui-corner-bottom ui-widget-content">
          <td style="width: 5%">
              <table>
                  <tr>
                      <td colspan="2">
                          <div align="center" >
                              <a class="navbar-brand" style="color:#a61a15" href="#"><span>${_('Administration')}</span> <br><div>System</div></a>
                          </div>
                      </td>
                  </tr>
                  <tr>
                      <td>
                          <table>
                              <td>
                                  <li class="dropdown">
                                     <a style="color:#a61a15" class="dropdown-toggle count-info" data-toggle="dropdown" href="#">
                                      <em class="fa fa-bell"></em><span class="label label-info" id="numeric_badge">${h.badge()}</span>

                                     </a>
                                     <ul class="dropdown-menu dropdown-alerts">


                                     </ul>
                                  </li>
                              </td>
                              <td>
                                  <div class="profile-usertitle">

                                      <div class="profile-usertitle-name">${h.whoami()}</div>

                                      <div id="online" class="dialog-hidden">
                                          <div class="profile-usertitle-status"><span class="indicator label-success"></span>Online</div>
                                      </div>
                                      <div id="offline" class="dialog-hidden">
                                          <div class="profile-usertitle-status"><span class="indicator label-danger"></span>Offline</div>
                                      </div>
                                  </div>
                              </td>
                          </table>
                      </td>

                  </tr>
              </table>
          </td>
          <td>
              <ul class="nav nav-tabs ui-widget-header">
                  <li class=active><a href="#pl11" aria-expanded=&#34;true&#34;>MyProjectName</a></li>
                  <li><a href="#" onclick="logout()" style="color:#666"><em class="fa fa-power-off">&nbsp;</em>Logout</a></li>
              </ul>
              <div class="tab-content ui-tabs-panel ui-corner-bottom ui-widget-content">
                      <div class="tab-pane fade in active" id="pl11" style="height:70px;padding: 10px">

                        <button onclick="openTab('JQgrid','${h.url()}/secc/test')" title="home of dispatch">Jqgrid</button>

                      </div>
              </div>
          </td>
      </table>
</nav>
      <div id="tabs">
          <ul class="nav nav-tabs ui-widget-header main1">
            <li class="main1"><a href="#tabs-1" >Inicio</a></li>
          </ul>
          <div id="tabs-1" align="right">
            ${self.content_wrapper()}
          </div>
      </div>
    <!-- End MENU -->
</%def>

<%def name="content_wrapper()">
  <%
    flash=tg.flash_obj.render('flash', use_js=False)
  %>
  % if flash:
    <script>$.alert("${str(tg.flash_obj.pop_payload()['message'])}" ,{autoclose:false,type:'info',title:false});</script>
  % endif
  ${self.body()}
</%def>

<%def name="footer()">
   <!-- INSERT FOOTER -->
    <div class="text-right">
        <div class="credits">
              <p>Copyright &copy; Madd Systems ${h.current_year()}&nbsp;</p>
        </div>
    </div>
</%def>

<%def name="bottom_scripts()">
 <script type="text/javascript">

 </script>
</%def>

Create test.mak inside templates:

<div style="margin-left:20px">
    <table id="jqGrid"></table>
    <div id="jqGridPager"></div>
</div>
    <script type="text/javascript">
        $(document).ready(function () {

            $("#jqGrid").jqGrid({
                url: 'http://trirand.com/blog/phpjqgrid/examples/jsonp/getjsonp.php?callback=?&qwery=longorders',
                mtype: "GET",
				styleUI : 'Bootstrap',
                datatype: "jsonp",
                colModel: [
                    { label: 'OrderID', name: 'OrderID', key: true, width: 75 },
                    { label: 'Customer ID', name: 'CustomerID', width: 150 },
                    { label: 'Order Date', name: 'OrderDate', width: 150 },
                    { label: 'Freight', name: 'Freight', width: 150 },
                    { label:'Ship Name', name: 'ShipName', width: 150 }
                ],
				viewrecords: true,
                height: 250,
                rowNum: 20,
                pager: "#jqGridPager"
            });
        });

   </script>

Update secure.py controller:

# -*- coding: utf-8 -*-
"""Sample controller with all its actions protected."""
from tg import expose, flash
from tg.i18n import ugettext as _, lazy_ugettext as l_
from tg import predicates

from myprojectname.lib.base import BaseController

__all__ = ['SecureController']


class SecureController(BaseController):
    """Sample controller-wide authorization"""

    # The predicate that must be met for all the actions in this controller:
    # allow_only = has_permission(
    #     'manage',
    #     msg=l_('Only for people with the "manage" permission')
    # )
    allow_only = predicates.not_anonymous()
    @expose('myprojectname.templates.index')
    def root(self):
        """Let the user know that's visiting a protected controller."""
        #flash(_("Secure Controller here"))
        return dict(page='index')

    @expose('myprojectname.templates.test')
    def test(self):
        return dict()

Create a Service:

Add in controllers services.py with the following:

# -*- coding: utf-8 -*-
"""Sample controller with all its actions protected."""
from tg import expose
from myprojectname.lib.base import BaseController

__all__ = ['ServicesController']


class ServicesController(BaseController):
    """Sample controller-wide authorization"""

    @expose('json')
    def listjson(self, **kw):
        lista = []
        #http://localhost:8080/secc/test/?user=manager&app_name=Deployment&internal_id=1&application_id=1
        #http://localhost:8080/services/listjson

        lista.append({'id': 400,
                      'name': ('JqGrid Exmaple'),
                      'rows':1,
                      'cols':1,
                      'observations': ('Administración JqGrid'),
                      'perm': 'Admin JqGrid',
                      'open': 'Menu',
                      'url': '',
                      'sons' :[{
                         'id': 401,
                         'name': 'Listado de Clientes',
                         'url': '/sec/test',
                         'perm': 'Administrar Clientes',
                         'observations': ('Customers admin'),
                         'open': 'openTab',
                         'sons': '',
                         'icon': '<span class="glyphicon glyphicon-file"></span>'
                      }
                      ]
                      })


        return dict(list=lista, error="ok", planet_name="dmyprojectname")

Add to root controller at the top:

from myprojectname.controllers.services import ServicesController

Add inside the RootController class:

    services = ServicesController()

Test service:

http://localhost:8080/services/listjson
⚠️ **GitHub.com Fallback** ⚠️