Saiku Widget shows No Data - pentaho-cde

I am using Pentaho CDE and I am trying to put a Saiku analysis file inside the dashboard using Saiku Widget.
However I am getting No Data message on the screen and in the browser console I am getting an error 401 - Bad Credentials.
When I access the Saiku URL directly from the browser, I am getting JSON response. It is not working with-in pentaho CDE dashboard.
Can someone help me out with this?

You must edit the file /biserver-ce/pentaho-solutions/system/saiku/ui/js/saiku/embed/SaikuEmbed.js and then restart bi-server, because the content of this file is minified in CDF.js
In this SaikuEmbed.js the user and password are set in
var _settings = {
server: '/saiku',
path: '/rest/saiku/embed',
user: 'admin',
password: 'admin',
blockUI: false
};
but i don't have user admin with password admin, so when it's try to do a verification before ajax call it stack with 401 authorization required.
I modified
beforeSend: function(request) {
if (self.settings.user && self.settings.password) {
var auth = 'Basic ' + Base64.encode(
self.settings.user + ':' + self.settings.password
);
request.setRequestHeader('Authorization', auth);
return true;
}
},
with
beforeSend: function(request) {
if (Dasboards.context.user) {
return true;
}
},
You can comment all beforeSend, if you want.

Related

Get OAuth 2.0 token for google service accounts

Short explanation
I want to get a Auth2.0 token for access to some APIs in my Google Cloud Platform proyect.
Context
At the current time i have a Wordpress page that has to make the connection. Temporarily i will make a javascript connection with the client via Ajax (when all work successfully i will make this in another way, for example with a PHP server in the middle).
The process that has to execute in our GCP don't need the user to log in with his google account, for that reason we will make a google service account for server to server connections. All the threads executed by the API will be log like be executed by this service account that isn't owned by any real person.
When i generate the Ajax connection for get the token, this will be send to the following URL:
https://oauth2.googleapis.com/token
I send it on JWT coding.
The coded message is generated in this Javascript code:
`
var unixHour = Math.round((new Date()).getTime() / 1000);
var header = {
"alg":"RS256",
"typ":"JWT"
}
var data = {
"iss":"nombreoculto#swift-firmament-348509.iam.gserviceaccount.com",
"scope":"https://www.googleapis.com/auth/devstorage.read_only",
"aud":"https://oauth2.googleapis.com/token",
"exp":(unixHour+3600),
"iat":unixHour
}
var secret = "MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCkhZH7TuaNO4XBVVVcE2P/hvHSsGXNu1D/FcCaMrW56BF/nbOlxAtbp07TCIOyrR1FEcJb+to66olSFnUVUWhWUB9zLbzKpULQoFmYECSWppUbCZd+bp271AFYZpxXFduziWuaG9BNxV2cmWTjLLlZI7FoIYFwLgPZHPWndY0E99lGEjmnH";
function base64url(source) {
// Encode in classical base64
encodedSource = CryptoJS.enc.Base64.stringify(source);
// Remove padding equal characters
encodedSource = encodedSource.replace(/=+$/, '');
// Replace characters according to base64url specifications
encodedSource = encodedSource.replace(/\+/g, '-');
encodedSource = encodedSource.replace(/\//g, '_');
return encodedSource;
}
var stringifiedHeader = CryptoJS.enc.Utf8.parse(JSON.stringify(header));
var encodedHeader = base64url(stringifiedHeader);
//document.getElementById("header").innerText = encodedHeader;
console.log(encodedHeader);
var stringifiedData = CryptoJS.enc.Utf8.parse(JSON.stringify(data));
var encodedData = base64url(stringifiedData);
//document.getElementById("payload").innerText = encodedData;
console.log(encodedData);
var signature = encodedHeader + "." + encodedData;
signature = CryptoJS.HmacSHA256(signature, secret);
signature = base64url(signature);
console.log(signature);
//document.getElementById("signature").innerText = signature;
var jwt = encodedHeader + "." + encodedData + "." + signature;
console.log(jwt);
$.ajax({
url: 'https://oauth2.googleapis.com/token',
type: 'POST',
data: { "grant_type": "urn:ietf:params:oauth:grant-type:jwt-bearer", "assertion" : jwt} ,
contentType: 'application/x-www-form-urlencoded; charset=utf-8',
success: function (response) {
alert(response.status);
},
error: function () {
alert("error");
}
});
`
Console:
Console output
The problem
The Ajax message generated in the script return "Invalid JWT signature".
send message API
ajax response API
Following the google documentation, this problem is for a bad coding of the message or a incorrect secret key.
You can see the code for generate the coding message in the previous script.
About the secret key, maybe i am not selecting the correct key for this task, here you have the steps i follow:
cred GCP
Inside the service account, i create a key in the "keys" section:
Keys GCP
As result this download this file:
File keys
I tried to use like secret key the "private_key" content of this file and additionally i tried to delete the line breaks (\n) of this and try again.
¿Is that correct?¿Or i dont use the corret key?
¿Maybe i make an incorrect coding?
*There aren't problems with share the key and account id because the key was disabled at the moment of share this thread and the project is only for testing purposes.

Parse: Session Not Created on Login

I'm having a slight issue when using the logIn class method. According to the docs, I should see a Session automatically created when a user logs in successfully.
Sessions are automatically created when users log in or sign up. They
are automatically deleted when users log out.
I'm logging in successfully, and am returning a success message to the console.
$("#login").submit(function(event) {
event.preventDefault();
var name = $("#login-name").val();
var pass = $("#login-password").val();
Parse.User.logIn(name, pass, {
success: function(user) {
console.log("Logged in successfully!");
}, error: function(user, error) {
console.log("Login error: " + error.message);
}
});
});
But when I jump into the Parse.com Data Browser, I can't see the Session under the Data Tab.
What am I doing wrong?
Any help is appreciated. Thanks in advance!
Seem to have fixed this by enabling "Require Revocable Sessions" in the Parse.com app settings page.

way to access user's Google Finance portfolio?

I noticed that Google removed the Finance API for Google App Engine. All I want is a list of stock tickers that they have in their Google Finance portfolio. Is there any way to still pull this data from the end user's portfolio, given that the API has been removed? I'm trying to manually retrieve it given that I know the login and password (e.g., it's my own).
Is there any way to retrieve it manually through curl, by logging in to the Google services? It seems like it should be possible to log in and go to my portfolio page, retrieving the source.
I have tried the following code:
#!/bin/bash
function ClientLogin() {
read -p 'Email> ' email
read -p 'Password> ' -s password
local service=$1
curl -s -d Email=$email -d Passwd=$password -d service=$service https://www.google.com/accounts/ClientLogin | tr ' ' \n | grep Auth= | sed -e 's/Auth=//'
}
function GetFinance() {
curl -L -s -H "Authorization: GoogleLogin auth=$(ClientLogin finance)" "http://www.google.com/finance/portfolio?action=view&pid=1" &> output.html
}
GetFinance
However, this code only retrieves a page that tells me to log in. The solution does not need to use curl, but it must be an automated retrieval using some scripting language.
Thanks to x4avier, I learned about casperjs and was able to write a quick script to load the Google services login page, enter the username and password, and then fetch the Google Finance portfolio. I'm sure this would work with any other google service and page. I save the html of the portfolio to portfolio.html. Hopefully this helps someone else also.
var fs = require('fs');
var failed = [];
var links = [
"https://www.google.com/finance/portfolio?action=view&pid=13"
];
var casper = require('casper').create({
verbose: true,
logLevel: 'debug',
pageSettings: {
loadImages: false, // The WebPage instance used by Casper will
loadPlugins: false, // use these settings
userAgent: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_5) AppleWebKit/537.4 (KHTML, like Gecko) Chrome/22.0.1229.94 Safari/537
}
});
// print out all the messages in the headless browser context
casper.on('remote.message', function(msg) {
this.echo('remote message caught: ' + msg);
});
// print out all the messages in the headless browser context
casper.on("page.error", function(msg, trace) {
this.echo("Page Error: " + msg, "ERROR");
});
var url = 'https://accounts.google.com/ServiceLogin?service=finance';
casper.start(url, function() {
// search for 'casperjs' from google form
console.log("page loaded");
this.test.assertExists('form#gaia_loginform', 'form is found');
this.fill('form#gaia_loginform', {
Email: 'youraccount#gmail.com',
Passwd: 'yourpass'
}, true);
});
casper.each(links, function(casper, link) {
this.then(function() {
this.test.comment("Loading " + link);
start = new Date();
this.open(link);
});
this.then(function() {
var message = this.requestUrl + " loaded";
if (failed.indexOf(this.requestUrl) === -1) {
this.test.pass(message);
fs.write('portfolio.html',this.getPageContent(),'w');
}
});
});
casper.run();
You should consider using an headless browser like casper.js.
With it you can login to google, go to google finance and get the html of a page or of a particular css selector.
To login you will to use the fill() function, it works like this :
casper.start('http://admin.domain.tld/login/', function() {
this.fill('form[id="login-form"]', {
'username': 'chuck',
'password': 'n0rr1s'
}, true);
});
casper.run();
Then you can parse the page and the specific content with getHTML(), work as below :
casper.then(function() {
this.echo(this.getHTML('h1#foobar')); // => 'The text included in the <h1 id=foobar>'
});
CasperJs works with cookies and explore more than one page, it should fit your needs.
Hope it helps :)
What information do you want to retrieve exactly?
It's pretty easy to do that using python urllib and beautifulsoup
http://docs.python.org/2/library/urllib2.html
http://www.crummy.com/software/BeautifulSoup/bs4/doc/
I've done it myself to post and retrieve messages on different forums website. The only thing that is not cool is that you have to hardcode the id of some elements you want to retrieve.
Here's a sample of what I did for the login part
#!/usr/bin/python
import urllib
import urllib2
import cookielib
import BeautifulSoup
url = "https://accounts.google.com/ServiceLogin?hl=en";
values = {'Email': 'me#mymail.fr', 'Passwd' : '', 'signIn' : 'Sign in', 'PersistentCookie' : 'yes'} # The form data 'name' : 'value'
cookie = cookielib.CookieJar()
opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(cookie))
data = urllib.urlencode(values)
response = self.opener.open(url, data)
print response
I filled some of the required info for the google login. But when I checked the POST request there was some others values you might need to add too in the values dict.
Here's the POST request I captured:
dsh:5606788993588
hl:en
checkedDomains:youtube
checkConnection:youtube:47:1,youtube:46:1
pstMsg:1
GALX:YU6dyLz2tHE
pstMsg:0
dnConn:
checkConnection:
checkedDomains:youtube
timeStmp:
secTok:
_utf8:☃
bgresponse:!A0LP9ks4H06eS0R0GKgonCCotgIAAAAiUgAAAAkqAOjHBiH2qA-EIczqcDooax5q8bxis...
Email:****#gmail.com
Passwd:mypassword
signIn:Sign in
PersistentCookie:yes
rmShown:1
I guess you will have to parse the login page using Beautifulsoup to get this values before you can actually send the form. I wonder if the casper example given above does that automatically, if it does you'd rather use it and then parse the portfolio page using Beatifulsoup of whatever you want.

Error handling when downloading a file from a servlet

I have a web application that must work with IE7 (yeah i know..) where the frontend is entirely made with ExtJS4, and theres a servlet used to download files. To download a file i send some parameters so i cant simply use location.href. it must be a POST.
So far it works, but when an exception is thrown in the servlet i dont know how to handle it to show the user some alert box or some message without redirecting to another page.
In my webapp im also using DWR and im aware of the openInDownload() function, but it triggers a security warning in IE.
So, (finally!) the question is
Using this code:
post = function (url, params) {
var tempForm=document.createElement("form");
tempForm.action=url;
tempForm.method="POST";
tempForm.style.display="none";
for(var x in params) {
// ...snip boring stuff to add params
}
document.body.appendChild(tempForm);
tempForm.submit();
return tempForm;
}
is it possible to stay in the same page after submitting ?
or with this other one:
Ext.Ajax.request({
url: './descargaArchivoNivs',
method: 'POST',
autoAbort: true,
params: {
nivs: jsonData
},
success: function(response){
// HERE!!
// i know this is wrong
document.write('data:text/plain,' + response.responseText );
/* this looked promising but a warning pops up
var newwindow = window.open();
newwindow.document.open();
newwindow.document.write('data:text/plain, ' + response.responseText );
newwindow.document.close();*/
},
failure: function(resp){
alert('There was an error');
}
});
is it possible to open the file download dialog // HERE!! with the response content??
or is there some other way to open the file download dialog on success, and on failure show a friendly message without losing the users input (the params of the POST) ?
(sorry if this post was too long)

Django Posts Not Working:

I am using Django 1.2.3 to develop a site. My ajax get requests work fine but the post requests work in development mode (127.0.0.1:8000) but not when I push the site into production using apache + nginx.
Here is an example
urls.py:
(r'api/newdoc/$', 'mysite.documents.views.newdoc'),
views.py
def newdoc(request):
# only process POST request
if request.is_ajax():
data= dict(request.POST)
# save data to db
return HttpResponse(simplejson.dumps([True]))
in javascript:
$.post("/api/newdoc/", {data : mydata}, function(data) { alert(data);}, "json");
my alert is never called .... this is a problem because i want to sanitize this data via a django form and the post requests do not seem to making it to the server (in production only).
what am i doing wrong?
UPDATES:
solution: crsf tokens need to be pushed ajax post requests (not gets) as of django 1.3
also, per the link provide below, the following javascript
$.ajaxSetup({
beforeSend: function(xhr, settings) {
if (!(/^http:.*/.test(settings.url) || /^https:.*/.test(settings.url))) {
// Only send the token to relative URLs i.e. locally.
xhr.setRequestHeader("X-CSRFToken",
$("#csrfmiddlewaretoken").val());
}
}
});
needs to be changed as follows:
$.ajaxSetup({
beforeSend: function(xhr, settings) {
if (!(/^http:.*/.test(settings.url) || /^https:.*/.test(settings.url))) {
// Only send the token to relative URLs i.e. locally.
xhr.setRequestHeader("X-CSRFToken",
$('input[name="csrfmiddlewaretoken"]').val());
}
}
});
the way the csrf token gets rendered in the form must have changed between 1.25 - 1.3??
regardless, it works. thanks for all your help everyone
Can you directly access your javascript files from the production server? Which Django version are you using in production? If you are using 1.2.5+ in production, you will need to push the csrf token to the server during an AJAX post operation.
See the release notes in 1.2.5 and CSRF
To check your Django version:
import django
django.get_version()
Print the above in your production site or from the shell in your production server while making sure you are using the proper Python path.
Your code appears fine with a cursory glance, but I'll show you an example of my ajax form processing code in a hope it'll help with figuring out the error that's occurring. Though, what #dmitry commented should be your first debugging step - use firebug or the inspector to see if the ajax call returns an error.
// js (jQuery 1.5)
$(form).submit(function(event) {
event.preventDefault();
$.post(post_url, $(form).serialize())
.success(function(data, status, jqxhr) {
if (data.success) { // form was valid
$(form)
// other irrelevant code
.siblings('span')
.removeClass('error')
.html('Form Successful');
} else { // form was invalid
$(form).siblings('span').addClass('error').html('Error Occurred');
}
})
.error(function(jqxhr, status, error) { // server error
$(form).siblings('span').addClass('error').html("Error: " + error);
});
});
// django
class AjaxFormView(FormView):
def ajax_response(self, context, success=True):
html = render_to_string(self.template_name, context)
response = simplejson.dumps({'success': success, 'html': html})
return HttpResponse(response, content_type="application/json", mimetype='application/json')
// view deriving from AjaxFormView
def form_valid(self, form):
registration = form.save()
if self.request.is_ajax():
context = {'competition': registration.competition }
return self.ajax_response(context, success=True)
return HttpResponseRedirect(registration.competition.get_absolute_url())
def form_invalid(self, form):
if self.request.is_ajax():
context = { 'errors': 'Error Occurred'}
return self.ajax_response(context, success=False)
return render_to_response(self.template_name, {'errors':form.errors})
Actually, comparing the above to your code, you may need to set the content_type in your django view so that jQuery can understand and process the response. Note that the above is using django 1.3 class-based views, but the logic should be familiar regardless. I use context.success to signal if the form processing passed or failed - since a valid response (json) of any kind will signal the jQuery.post that the request was successful.

Resources