Cross Origin Resource Sharing - jordy33/turbogears_tutorial GitHub Wiki
The following code will be running at https://mercury.dudewhereismy.mx
Insert the following in root.py
@expose('myprojectname.templates.tabs')
def tabs(self):
return dict(uno="")
Create tabs.mak and insert the following:
<!DOCTYPE html>
<html>
<head>
<title></title>
<meta charset="utf-8" />
<link href="${tg.url('/css/bootstrap.min.css')}" rel="stylesheet">
<link href="${tg.url('/css/font-awesome.min.css')}" rel="stylesheet" />
<link href="${tg.url('/css/datepicker3.css')}" rel="stylesheet" />
<link href="${tg.url('/css/styles3.css')}" rel="stylesheet">
<link href="https://fonts.googleapis.com/css?family=Montserrat:300,300i,400,400i,500,500i,600,600i,700,700i" rel="stylesheet">
<!-- jquery and alert -->
<script src="${tg.url('/js/jquery-1.11.1.min.js')}"></script>
<script src="${tg.url('/js/alert.js')}"></script>
<!--[if lt IE 9]>
<script src="${tg.url('/js/html5/html5shiv.js')}"></script>
<script src="${tg.url('/js/html5/respond.min.js')}"></script>
<![endif]-->
<!-- extgrid -->
<!-- jqgrid -->
<script src="${tg.url('/js/jqgrid/jquery.jqgrid.min.js')}"></script>
<script src="${tg.url('/js/jqgrid/i18n/grid.locale-es.js')}"></script>
<!-- Font Size -->
<link rel="stylesheet" href="${tg.url('/css/jqgrid/ui.jqgrid.css')}">
<!-- Custom Theme Roller -->
<!-- Important: Bootstrap must be first to avoid over raid jquery-ui -->
<script src="${tg.url('/js/bootstrap.min.js')}"></script>
<script src="${tg.url('/js/jquery-ui.js')}"></script>
<script src="${tg.url('/js/jquery-validation-1.17.0/dist/jquery.validate.js')}"></script>
<link rel="stylesheet" href="https://ajax.googleapis.com/ajax/libs/jqueryui/1.8.16/themes/redmond/jquery-ui.css" type="text/css"/>
<!-- end jqgrid -->
<script src="${tg.url('/js/mqtt/mqttws31.js')}" type="text/javascript"></script>
<!-- notifications grid -->
<!-- moment for UTC to local dates -->
<script src="${tg.url('/js/moment/moment.js')}"></script>
<script src="js/lumino/chart.min.js"></script>
<script src="js/lumino/chart-data.js"></script>
<script src="js/lumino/easypiechart.js"></script>
<script src="js/lumino/easypiechart-data.js"></script>
<script src="js/lumino/bootstrap-datepicker.js"></script>
<script src="js/lumino/custom.js"></script>
<script type="text/javascript">
$(document).ready(function () {
});
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) {
$.ajax({
url:pageName ,
error: function () {
$('#info').html('<p>An error has occurred</p>');
},
beforeSend: function(xhr){
xhr.setRequestHeader("Content-Type","application/json");
xhr.setRequestHeader("Accept","application/json");
xhr.setRequestHeader( "Authorization", make_base_auth(username,password));
},
dataType: 'html',
success: function (data, rq) {
$("#fragment0").html(data);
},
type: 'GET'
});
}
</script>
</head>
<body>
<div class="container">
<h2>Dynamic Tabs</h2>
<button onclick="doAjax('https://venus.dudewhereismy.mx/validate/jqgrid')">Login</button>
<br>
<ul class="nav nav-tabs">
<li class="active"><a data-toggle="tab" href="#home">Home</a></li>
<li><a data-toggle="tab" href="#menu1">Menu 1</a></li>
<li><a data-toggle="tab" href="#menu2">Menu 2</a></li>
<li><a data-toggle="tab" href="#menu3">Menu 3</a></li>
</ul>
<div class="tab-content">
<div id="home" class="tab-pane fade in active">
<div id="fragment0"></div>
</div>
<div id="menu1" class="tab-pane fade">
<h3>Menu 1</h3>
<div id="fragment1"></div>
</div>
<div id="menu2" class="tab-pane fade">
<h3>Menu 2</h3>
<div id="fragment1"></div>
</div>
<div id="menu3" class="tab-pane fade">
<h3>Menu 3</h3>
<p>Eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo.</p>
</div>
</div>
</div>
</body>
</html>
The following code will be running at https://venus.dudewhereismy.mx
Create a controller named validate.py insert the following:
# -*- coding: utf-8 -*-
"""The base Controller API."""
from tg.decorators import expose
from pythonvenus.lib.base import BaseController
from pythonvenus.controllers.jqgrid import jqgridDataGrabber
from pythonvenus.model.tables import Trackers
__all__ = ['ValidateController']
from tg import predicates
class ValidateController(BaseController):
allow_only = predicates.not_anonymous()
@expose('pythonvenus.templates.jqgrid')
def jqgrid(self):
return dict()
@expose('json')
def loadTest2(self, **kw):
filter = []
return jqgridDataGrabber(Trackers, 'id', filter, kw).loadGrid()
@expose('json')
def updateTest2(self, **kw):
filter = []
return jqgridDataGrabber(Trackers, 'id', filter, kw).updateGrid()
At top of root.py insert:
from pythonvenus.controllers.validate import ValidateController
At the class RootController(BaseController): insert:
validate = ValidateController()
Create jqgrid.mak and insert the following:
<!DOCTYPE html>
<html lang="en">
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<script src="https://cdn.jsdelivr.net/free-jqgrid/4.8.0/js/i18n/grid.locale-es.js"></script>
<script src="https://cdn.jsdelivr.net/free-jqgrid/4.8.0/js/jquery.jqgrid.min.js"></script>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/free-jqgrid/4.8.0/css/ui.jqgrid.css">
<meta http-equiv="Content-Security-Policy" content="upgrade-insecure-requests">
<link rel="stylesheet" href="https://code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
<link rel="stylesheet" href="https://ajax.googleapis.com/ajax/libs/jqueryui/1.8.16/themes/redmond/jquery-ui.css" type="text/css"/>
<meta charset="utf-8" />
<title>jqGrid Loading Data - Million Rows from a REST service</title>
</head>
<body>
<table style="width:100%;overflow:auto;">
<table id="jqGridTable" class="scroll" cellpadding="0" cellspacing="0"></table>
<div id="listPagerTables" class="scroll" style="text-align:center;"></div>
<div id="listPsetcols" class="scroll" style="text-align:center;"></div>
</table>
<script type="text/javascript">
$(document).ready(
function () {
var username = 'manager';
var password = 'managepass';
function make_base_auth(user, password) {
var tok = user + ':' + password;
var hash = btoa(tok);
return "Basic " + hash;
}
$.ajaxSetup({
headers : {
'Authorization' : make_base_auth(username,password)
}
});
var grid_name = '#jqGridTable';
var grid_pager= '#listPagerTables';
var update_url='https://venus.dudewhereismy.mx/validate/updateTest2';
var load_url='https://venus.dudewhereismy.mx/validate/loadTest2/';
var header_container='Test 2';
var addParams = {left: 0,width: window.innerWidth-600,top: 20,height: 200,url: update_url, closeAfterAdd: true,closeAfterEdit: true,closeAfterSearch:true}
var editParams = {left: 0,width: window.innerWidth-400,top: 20,height: 200,url: update_url,closeAfterAdd: true,closeAfterEdit: true,closeAfterSearch:true,modal: true,
width: "500",
editfunc: function (rowid) {
alert('The "Edit" button was clicked with rowid=' + rowid);
}
};
var deleteParams = {left: 0,width: window.innerWidth-700,top: 20,height: 130,url: update_url,closeAfterAdd: true,closeAfterEdit: true,closeAfterSearch:true}
var viewParams = {left: 0,width: window.innerWidth-700,top: 20,height: 130,url: update_url,closeAfterAdd: true,closeAfterEdit: true,closeAfterSearch:true}
var searchParams = {top: 20,height: 130,width: "500",closeAfterAdd: true,closeAfterEdit: true,closeAfterSearch:true,url: update_url,modal: true, };
var grid = jQuery(grid_name);
grid.jqGrid({
url: load_url,
datatype: 'json',
mtype: 'GET',
colNames: ['id', 'imei','ticket','nombre'],
colModel: [
{name: 'id',index: 'id', width: 5,align: 'left',key:true,hidden: true, editable: true,edittype: 'text',editrules: {required: false}},
{name: 'imei',index: 'imei', width: 30, align: 'right',hidden: false,editable: true, edittype: 'text',editrules: {required: false}},
{name: 'ticket',index: 'ticket', width: 30, align: 'right',hidden: false,editable: true, edittype: 'text',editrules: {required: false}},
{name: 'name',index: 'name', width: 30, align: 'right',hidden: false,editable: true, edittype: 'text',editrules: {required: false}},
],
pager: jQuery(grid_pager),
rowNum: 10,
rowList: [10, 50, 100],
sortname: 'imei',
sortorder: "desc",
autowidth: true,
shrinkToFit: true,
viewrecords: true,
height: 250,
caption: header_container,
});
grid.jqGrid('navGrid',grid_pager,{edit:true,add:true,del:true, search:true},
editParams,
addParams,
deleteParams,
searchParams,
viewParams);
});
$.extend($.jgrid.nav,{alerttop:1});
</script>
</body>
</html>
Edit /etc/haproxy/haproxy.cfg and insert the following:
global
log 127.0.0.1 syslog
maxconn 1000
user haproxy
group haproxy
daemon
tune.ssl.default-dh-param 4096
ssl-default-bind-options no-sslv3 no-tls-tickets
ssl-default-bind-ciphers EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH
defaults
log global
mode http
option httplog
option dontlognull
option http-server-close
option forwardfor except 127.0.0.0/8
option redispatch
option contstats
retries 3
timeout http-request 10s
timeout queue 1m
timeout connect 10s
timeout client 1m
timeout server 1m
timeout check 10s
###########################################
#
# HAProxy Stats page
#
###########################################
listen stats
bind *:9090
mode http
maxconn 10
stats enable
stats hide-version
stats realm Haproxy\ Statistics
stats uri /
stats auth admin:GPSc0ntr0l1
###########################################
#
# Front end for all
#
###########################################
frontend ALL
bind *:80
bind *:443 ssl crt /etc/haproxy/certs/dudewhereismy.mx.pem
mode http
######
# rewrite URL
######
#http-request set-var(txn.host_header) req.hdr(Host),lower
#acl is_domain1 var(txn.host_header) -m beg mercury.dudewhereismy.mx
#http-request set-header Host venus.dudewhereismy.mx if is_domain1
#http-request set-uri /pathtoapp/%[capture.req.uri] if is_domain1
#####
# Add CORS headers when Origin header is present
capture request header origin len 128
http-response add-header Access-Control-Allow-Origin %[capture.req.hdr(0)] if { capture.req.hdr(0) -m found }
rspadd Access-Control-Allow-Headers:\ Origin,\ X-Requested-With,\ Content-Type,\ Accept if { capture.req.hdr(0) -m found }
# Define path for lets encrypt
acl is_letsencrypt path_beg -i /.well-known/acme-challenge/
use_backend letsencrypt if is_letsencrypt
# Define hosts
acl host_sun hdr(host) -i sun.dudewhereismy.mx
acl host_earth hdr(host) -i earth.dudewhereismy.mx
acl host_pluto hdr(host) -i pluto.dudewhereismy.mx
acl host_mercury hdr(host) -i mercury.dudewhereismy.mx
acl host_venus hdr(host) -i venus.dudewhereismy.mx
acl is_options method OPTIONS
use_backend venus_cors_headers if METH_OPTIONS host_venus
use_backend earth_cors_headers if METH_OPTIONS host_earth
# Direct hosts to backend
use_backend sun if host_sun
use_backend earth if host_earth
use_backend pluto if host_pluto
use_backend mercury if host_mercury
use_backend venus if host_venus
# Redirect port 80 to 443
# But do not redirect letsencrypt since it checks port 80 and not 443
redirect scheme https code 301 if !{ ssl_fc } !is_letsencrypt
###########################################
#
# Back end letsencrypt
#
###########################################
backend letsencrypt
server letsencrypt 127.0.0.1:54321
###########################################
#
# Back end for foo
#
###########################################
backend sun
rspadd Access-Control-Allow-Origin:\ *
rspadd Access-Control-Max-Age:\ 31536000
balance roundrobin
option httpchk GET /check
http-check expect rstring ^UP$
default-server inter 10s fall 3 rise 2
server sun1 127.0.0.1:8080 check
backend earth
rspadd Access-Control-Max-Age:\ 31536000
rspadd Access-Control-Allow-Credentials:\ true
rspadd Access-Control-Allow-Methods:\ GET,\ HEAD,\ OPTIONS,\ POST,\ PUT
rspadd Access-Control-Allow-Headers:\ Origin,\ Accept,\ X-Requested-With,\ Content-Type,\ Access-Control-Request-Method,\ Access-Control-Request-Headers,\ Authorization
balance roundrobin
option httpchk GET /check
http-check expect rstring ^UP$
default-server inter 10s fall 3 rise 2
server earth1 127.0.0.1:8082 check
backend pluto
rspadd Access-Control-Allow-Origin:\ *
rspadd Access-Control-Max-Age:\ 31536000
balance roundrobin
option httpchk GET /check
http-check expect rstring ^UP$
default-server inter 10s fall 3 rise 2
server pluto1 127.0.0.1:8084 check
backend mercury
balance roundrobin
option httpchk GET /check
http-check expect rstring ^UP$
default-server inter 10s fall 3 rise 2
server mercury1 127.0.0.1:8086 check
server mercury2 127.0.0.1:8087 check
backend venus
rspadd Access-Control-Max-Age:\ 31536000
rspadd Access-Control-Allow-Credentials:\ true
rspadd Access-Control-Allow-Methods:\ GET,\ HEAD,\ OPTIONS,\ POST,\ PUT
rspadd Access-Control-Allow-Headers:\ Origin,\ Accept,\ X-Requested-With,\ Content-Type,\ Access-Control-Request-Method,\ Access-Control-Request-Headers,\ Authorization
balance roundrobin
option httpchk GET /check
http-check expect rstring ^UP$
default-server inter 10s fall 3 rise 2
server venus1 127.0.0.1:8088 check
backend venus_cors_headers
errorfile 503 /root/venus.http
backend earth_cors_headers
errorfile 503 /root/earth.http
At the haproxy server at /root insert earth.http with the following:
HTTP/1.1 200 OK
Access-Control-Allow-Origin: https://sun.dudewhereismy.mx
Access-Control-Allow-Methods: GET,PUT,POST,DELETE,PATCH,OPTIONS
Access-Control-Allow-Headers: Origin, X-Requested-With, Content-Type, Accept, Authorization
Access-Control-Max-Age: 31536000
Access-Control-Allow-Credentials: true
Content-Length: 0
Cache-Control: private
At the haproxy server at /root insert mercury.http with the following:
HTTP/1.1 200 OK
Access-Control-Allow-Origin: https://sun.dudewhereismy.mx
Access-Control-Allow-Methods: GET,PUT,POST,DELETE,PATCH,OPTIONS
Access-Control-Allow-Headers: Origin, X-Requested-With, Content-Type, Accept, Authorization
Access-Control-Max-Age: 31536000
Access-Control-Allow-Credentials: true
Content-Length: 0
Cache-Control: private
Test the code:
https://mercury.dudewhereismy.mx/tabs