apigee baas example has a syntax error - apigee-baas

The Hello World example on the apigee site has a quote mismatch error:
var dataClient = new Apigee.Client({
orgName:'your-org', //your Apigee organization name
appName:'your-app'
});
var options = {
endpoint:"users", //the collection to query
qs:{ql:"status='active'",limit:5"} //the query string - note the use of the 'ql' property
};
//Call request to initiate the API call
dataClient.request(options, function (error, response) {
if (error){
//error
} else {
//success
}
});
Q: Is there any hope that this will run once I remove the " after the 5?

Related

Unable to Save ParseObject with User ACL in Cloud Code

I have an issue saving changes to an object from a Cloud Code function.
I have a collection called Character and one record inside it.
This Character record has an ACL with Public Read, and Private Write Access by a specific ParseUser (6MwfSLdAxd).
In Unity, I authenticated the user and I then call the Cloud Code function as follows:
ParseCloud.CallFunctionAsync<Character>("startBattle", null).ContinueWith(t =>
{
Debug.Log("I got here...");
Debug.Log(t.Result.ClassName);
});
In my Cloud Code function, I grab the first character in the collection (ignoring checking if it belongs to this user, because at the moment there is only one and it DOES belong to this user - there's only one user too).
var Character = Parse.Object.extend("Character");
Parse.Cloud.define("startBattle", function (request, response) {
var user = request.user;
if (user == null)
{
return response.error("You must login before you can battle!");
}
var characterQuery = new Parse.Query(Character);
characterQuery.first()
.then(
function (character) {
character.set("name", "Cloud Code sucka");
character.save().then(function(character) {
return response.success(character);
});
},
function (error) {
return response.error("You must create a character before you can battle! " + error);
}
)
});
However, I simply cannot save any changes to this character. All the documentation and forum posts I've found suggest that if you call a Cloud Code function when authenticated then that function should have the same level permissions as the user calling it.
The only time this code works is if I set the ACL of the character to Public Write.
Does anyone have any ideas why this wouldn't be working?
Note: Worth noting that I can see in the server logs that the Cloud Code function IS being called by the authenticated user 6MwfSLdAxd as I get this error (if I add a response.error call):
error: Failed running cloud function startBattle for user 6MwfSLdAxd with:
Input: {}
Error: {"code":141,"message":"Messed up: [object Object]"} functionName=startBattle, code=141, message=Messed up: [object Object], , user=6MwfSLdAxd
error: Error generating response. ParseError { code: 141, message: 'Messed up: [object Object]' } code=141, message=Messed up: [object Object]
[object Object]
[object Object]
After some extensive searching I've now found the solution to this.
For anyone else encountering the same issues, you should be aware that whilst Parse.com used to run Cloud Code functions in the context of the user that called them (afaik), self-hosted Parse Servers do not.
In order to call queries or saves in the context of a user you must pass their session token as shown below. I hope this saves someone the hours of confusion I went through!
var MyObject = Parse.Object.extend("MyObject");
Parse.Cloud.define("myCloudFunction", function (request, response) {
var user = request.user;
var sessionToken = user.getSessionToken();
var query = new Parse.Query(MyObject)
.find({ sessionToken: sessionToken })
.then(
function (object) {
object.set("someKey", "someValue");
return object.save(null, { sessionToken: sessionToken });
}
)
.then(
function (object) {
return response.success(object);
},
function (error) {
return response.error(error.message);
}
);
});
For further context see:
https://github.com/ParsePlatform/parse-server/wiki/Compatibility-with-Hosted-Parse#cloud-code

protractor - testing rest end point

I am trying to invoke rest end point from Protractor E2E tests. I have referred to following site, however this post seems to be based on old API
eg: protractor.promise.defer(); seems no longer valid on latest API.
http://squirrel.pl/blog/2014/01/15/direct-server-http-calls-in-protractor/
Could you please advise/give sample code to invoke rest end point based on latest protractor API (>= 1.3).
I'm trying to write generic function, something like following.
var executeRequest = function(method, url) {
var defer = protractor.promise.defer();
// method can be ‘GET’, ‘POST’ or ‘PUT’
request({uri: url, method: method, json: true}, function(error, response, body) {
if (error || response.statusCode >= 400) {
defer.reject({
error : error,
message : response
});
} else {
defer.fulfill(body);
}
});
// Return a promise so the caller can wait on it for the request to complete
return defer.promise;
};
You could use request-promise instead. Example from their website...
var rp = require('request-promise');
var options = {
uri : 'http://posttestserver.com/post.php',
method : 'POST'
};
rp(options)
.then(console.dir)
.catch(console.error);
I have used npm module - "needle" to invoke restAPI . That has option for redirects, which helped to validate test site even after redirect.
Please find below sample test to validate rest endpoint is up and running.
it("check restendpoint service is running", function(done){
var restendpointUrl = browser.baseUrl + 'service';
needle.get(healthcheckUrl,{follow_max : 5}, function(err,resp) {
expect(resp.statusCode).toBe(200);
if (!err && resp.statusCode == 200) {
expect(true).toBe(true);
} else {
expect(false).toBe(true);
}
done();
});
});
Brine, many thanks for your earlier reply.

DotNetNuke Service API Authorization throwing 401 Unauthorized code

I am having a bit of difficulty figuring out why I am getting 401 Unauthorized status from service framework. At the moment I have it setup to allow everyone to do as they please but that because when I try to enable authorisation I get 401 error code.
//[SupportedModules("Boards")]
//[DnnModuleAuthorize(AccessLevel = SecurityAccessLevel.View)]
[AllowAnonymous]
public class BoardsServiceController : DnnApiController
{ ... }
The strange thing is I have another module which is more than happy to work away with DnnModuleAuthorize
[SupportedModules("Assignments")]
[DnnModuleAuthorize(AccessLevel = SecurityAccessLevel.View)]
public class AsgnsServiceController : DnnApiController
{ ... }
In both cases I have checked to make sure the user has permissions to view the page on which the module lives.
I have cross referenced both projects and everything seems to be spot on. Yet one is working away just fine and the other one returns 401.
Any suggestions?
Update
For Assignments module I am mostly using jQuery style of ajax request just because I haven't got around to revising the module. So a typical GET request would look something like this:
$.ajax({
type: "GET",
url: sf.getServiceRoot( "Assignments" ) + "AsgnsService/GetAssignments",
data: data,
beforeSend: sf.setModuleHeaders
}).done( function ( items ) {
//removed for brevity
}).fail( function ( xhr, result, status ) {
//removed for brevity
});
As for Boards module the code structure is slightly different due knockout implementation. There is a dedicated ServiceCaller but it all boils down to the same ajax call to the server except that instead of having full blown ajax call defined as above it looks much neater.
var that = this;
that.serviceCaller = new dnn.boards.ServiceCaller($, this.moduleId, 'BoardsService');
var success = function (model) {
if (typeof model !== "undefined" && model != null) {
viewModel = new boardViewModel(model.colLists);
ko.bindingHandlers.sortable.beforeMove = viewModel.verifyAssignments;
ko.bindingHandlers.sortable.afterMove = viewModel.updateLastAction;
// normally, we apply moduleScope as a second parameter
ko.applyBindings(viewModel, settings.moduleScope);
}
//console.log('success', model);
};
var failure = function (response, status) {
console.log('request failure: ' + status);
};
var params = {
BoardId: this.boardId
};
that.serviceCaller.get('GetBoardLists', params, success, failure);
And the ServiceCaller ajax function itself looks like this:
function (httpMethod, method, params, success, failure, synchronous) {
var options = {
url: that.getRoot() + method,
beforeSend: that.services.setModuleHeaders,
type: httpMethod,
async: synchronous == false,
success: function (d) {
if (typeof (success) != 'undefined') {
success(d || {});
}
},
error: function (xhr, textStatus, errorThrown) {
if (typeof (failure) != 'undefined') {
var message = undefined;
if (xhr.getResponseHeader('Content-Type').indexOf('application/json') == 0) {
try {
message = $.parseJSON(xhr.responseText).Message;
} catch (e) {
}
}
failure(xhr, message || errorThrown);
}
}
};
if (httpMethod == 'GET') {
options.data = params;
} else {
options.contentType = 'application/json; charset=utf-8';
options.data = ko.toJSON(params);
options.dataType = 'json';
}
$.ajax(options);
};
This would be the two GET requests from two different modules where one is happy and the other throws a status 401 when I enable the same annotations.
Does this provide any clues?
Update
Now in saying all of the above if one takes a look at the original Boards module code base one will notice [DnnAuthorize] annotation attached to every function.
During module revision I removed all instances of [DnnAuthorize] annotation and replaced it with two of my own on the service class itself.
When I add [DnnAuthorize] as annotation on service class itself things work as expected. So why [SupportedModules("Boards")] and [DnnModuleAuthorize(AccessLevel = SecurityAccessLevel.View)] combination doesn't !?
I am not sure but working with the WebAPI you have to register the Service Framework anti forgery stuff
ServicesFramework.Instance.RequestAjaxAntiForgerySupport();
This is part of asking the API to work with a specific module.

Baasbox and Javascript

I'm trying BaaSbox, a free Backend as a Service. But it has no out-of-the-box Javascript support I can use right away (yet, only iOS and Android)
I'm having trouble sending the right curl command from javascript, anyone happen to know a good resource or a simple working $.ajax template? I've tried a few examples from stackoverflow, but none of them specifically aimed at BaaSbox.
I've tried following the Java instructions on their site here. Just making a simple login work, but I keep getting the wrong responses from the server.
Or on the other hand, anyone know a good, free alternative to BaaSbox? I just want to be able to install it on my own server, no paid plans or whatever.
in the download page there is a preliminary version of the JS SDK (added few days ago).
The documentation is on the way, however in the zip file you can find a simple example.
For example to perform a signup:
//set the BaasBox parameters: these operations initialize the SDK
BaasBox.setEndPoint("http://localhost:9000"); //this is the address of your BaasBox instance
BaasBox.appcode = "1234567890"; //this is your instance AppCode
//register a new user
BaasBox.createUser("user", "pass", function (res, error) {
if (res) console.log("res is ", res);
else console.log("err is ", error);
});
Now you can login into BaasBox
//perform a login
$("#login").click(function() {
BaasBox.login("user", "pass", function (res, error) {
if (res) {
console.log("res is ", res);
//login ok, do something here.....
} else {
console.log("err is ", error);
//login ko, do something else here....
}
});
Once the user is logged in he can load the Documents belonging to a Collection (the SDK automatically manages the Session Token for you):
BaasBox.loadCollection("catalogue", function (res, error) { //catalogue is the name of the Collection
if (res) {
$.each (res, function (i, item) {
console.log("item " + item.id); //.id is a field of the Document
});
} else {
console.log("error: " + error);
}
});
However under the hood the SDK uses JQuery. So you can inspect it to know how to user $.ajax to call BaasBox.
For example the creatUser() method (signup) is:
createUser: function (user, pass, cb) {
var url = BaasBox.endPoint + '/user'
var req = $.ajax({
url: url,
method: 'POST',
contentType: 'application/json',
data: JSON.stringify({
username: user,
password: pass
}),
success: function (res) {
var roles = [];
$(res.data.user.roles).each(function(idx,r){
roles.push(r.name);
})
setCurrentUser({"username" : res.data.user.name,
"token" : res.data['X-BB-SESSION'],
"roles": roles});
var u = getCurrentUser()
cb(u,null);
},
error: function (e) {
cb(null,JSON.parse(e.responseText))
}
});
}

How to get Meteor.Call to return value for template?

I've tried to understand this post regarding this concept, however, I'm failing to get it. I have the following simple setup:
/server/test.js
Meteor.methods({
abc: function() {
var result = {};
result.foo = "Hello ";
result.bar = "World!";
return result;
}
});
/client/myapp.js
var q = Meteor.call('abc');
console.log(q);
This structure returns to the console undefined.
If I change the myapp.js file to:
Meteor.call('abc', function(err, data) {
!err ? console.log(data) : console.log(err);
}
I receive the Object in my console.
Ideally this is what I'd like to be able to do, but it doesn't work, stating in the console: Cannot read property 'greeting' of undefined
/client/myapp.js
var q = Meteor.call('abc');
Template.hello.greeting = function() {
return q.foo;
}
Any help in passing the data from the server object into the template would be greatly appreciated. I'm still learning JavaScript & Meteor.
Thanks!
From the Meteor.call documentation:
On the client, if you do not pass a callback and you are not inside a stub, call will return undefined, and you will have no way to get the return value of the method. That is because the client doesn't have fibers, so there is not actually any way it can block on the remote execution of a method.
So, you'll want to do it like this:
Meteor.call('abc', function(err, data) {
if (err)
console.log(err);
Session.set('q', data);
});
Template.hello.greeting = function() {
return Session.get('q').foo;
};
This will reactively update the template once the data is available.
This happens because Npm.require has Async behavior. That's the reason that you have to write a callback for Meteor.call.
But there is a solution, just use install(mrt add npm) and you'll get a function named Meteor.sync(//...) with this you can do both games: sync and async in your Meteor.call().
Reference: http://www.sitepoint.com/create-a-meteor-app-using-npm-module/
You can get the return value of a Meteor method for use in a template by using a reactive variable. Check out the working demonstration on Meteorpad
I went for a ghetto solution. But, it works for me, which is what matters, to me. Below is my code, which, in concept, I think, solves OP's problem.
In the client's main.js:
Meteor.setInterval(function() {
confirmLogin();
}, 5000);
This runs the confirmLogin() function every five seconds.
The confirmLogin function (in the client's main.js):
function confirmLogin() {
Meteor.call('loggedIn', function (error, result) {
Session.set("loggedIn", result);
});
}
The loggedIn method (in the server's main.js):
loggedIn: function () {
var toReturn = false;
var userDetails = Meteor.user();
if (typeof userDetails["services"] !== "undefined") {
if (typeof userDetails["services"]["facebook"] != "undefined") {
toReturn = true;
}
}
return toReturn;
},
The relevant helper:
loggedIn: function () {
return Session.get("loggedIn");
}