Save in flex a file get by web service - web-services

I'm working with Flex 10 for web applications.
I need to save a binary file which is received in Flex from a web service. To do this I need to use FileReference.save(), which must be invoked by a user event (mouse or keyboard) for security requirements of Flex. The general idea is as follows:
protected function cmdSave(event:MouseEvent):void{
var inp:String = webService.getString("fieldBinary"); //here I get the data
var base64Dec:Base64Decoder = new Base64Decoder();
base64Dec.decode(inp);
var byteArray:ByteArray = base64Dec.toByteArray();
var fileRef:FileReference = new FileReference();
fileRef.save(byteArray, "output.pdf");
}
Now my problem is that the method to consume a web service is synchronous. Therefore, my original function should split in two, and the call to FileReference.save() is not performed in the function triggered by the user event, but in the function triggered by de web service, something like:
protected function cmdSave(event:MouseEvent):void{
responseFunction=cmdSave_End;
methodToCallWebService(responseFunction);
}
protected function cmdSave_End(event:Ws_Event):void{
var webService = Ws_event.getResult();
var inp:String = webService.getString("fieldBinary"); //here I get the data
var base64Dec:Base64Decoder = new Base64Decoder();
base64Dec.decode(inp);
var byteArray:ByteArray = base64Dec.toByteArray();
var fileRef:FileReference = new FileReference();
fileRef.save(byteArray, "output.pdf");
}
(I omit most of the code)
At this time, FileReference throws this error:
Error #2176: Certain actions, such as those that display a pop-up
window, may only be invoked upon user interaction, for example by a
mouse click or button press.
Would anyone think a way to fix this? I need FileReference run in the function invoked by the user.
Thanks in advance.

You can trick this by forcing the user to click some button and save on disk only at that point.
What I did was to show an Alert message telling the user that the file has been successfully generated, and on the alert handle function call the save method.
private var _byteArray:ByteArray;
protected function cmdSave(event:MouseEvent):void
{
responseFunction=cmdSave_End;
methodToCallWebService(responseFunction);
}
protected function cmdSave_End(event:Ws_Event):void{
var webService = Ws_event.getResult();
var inp:String = webService.getString("fieldBinary"); //here I get the data
var base64Dec:Base64Decoder = new Base64Decoder();
base64Dec.decode(inp);
_byteArray = base64Dec.toByteArray();
Alert.show("File content was generated", "Info", Alert.OK, this, alertClickHandler);
}
// Event handler function for Alert
private function alertClickHandler(evt:CloseEvent):void
{
var fileRef:FileReference = new FileReference();
fileRef.save(_byteArray, "output.pdf");
}

Related

How do I get the Code Review Id in a custom section of the code review page?

I am writing a visual studio extension that has a section on the code review page. I would like access to the information about the rest of the code review page, specifically what code review is current on the page being displayed. I should be able to access the workitemId but so far I have not figured out how.
Edit
Using Cole's suggestion I have accessed the PageContent but I do not know what type I should cast the content to. Nor do I know when it will be available. I would like access both when I initialize my section, and later. Here is my code when I try to initialize the section:
public override object SectionContent
{
get
{
if (base.SectionContent == null)
{
var teamExplorerPage = this.GetService<ITeamExplorerPage>();
var pageContent = teamExplorerPage.PageContent;
this.model.CodeReviewId = pageContent;
base.SectionContent = new CodePlusTeamExplorerSectionView(this.ServiceProvider, this.model);
}
return base.SectionContent;
}
}
When I debug the code I see that a DataContext is available on the PageContent, but I do not know what type to cast the pageContent (orITeamExplorerPage) to, to gain access to it. Also the DataContext has a CodeReviewId property which seems like the value I need but it is null at this point of the Lifecycle. If I want to retrieve some additional data based on the CodeReviewId when/where is it available?
I am still trying to figure out how to get it earlier in the lifecycle of the page but from an event like a button click in the page I can retrieve the value using reflection. This seems like a bit of a hack, perhaps someone else has a better way, but here it is.
private void Button_Click(object sender, RoutedEventArgs e)
{
var teamExplorer = this.GetService<ITeamExplorer>();
var currentPage = teamExplorer.CurrentPage;
var currentContent = currentPage.PageContent;
Type type = currentContent.GetType();
PropertyInfo pi = type.GetProperty("DataContext");
var dataContext = pi.GetValue(currentContent);
Type contextTypetype = dataContext.GetType();
PropertyInfo contextTypePi = contextTypetype.GetProperty("CodeReviewId");
var codeReviewId = contextTypePi.GetValue(dataContext);
var context = new Dictionary<string, object>();
context.Add("WorkItemId", codeReviewId);
teamExplorer.NavigateToPage(new Guid(TeamExplorerPageIds.ViewCodeReview), context);
}

Rally Web Services API: How do I get the URL link of the user story? (getDetailUrl() method)

Please be patient and Do Not flag this as duplicate: Using the Rally REST API, how can I get the non-API (website) URL for a user story?
I want to be able to generate a link for the user story.
Something like this: https://rally1.rallydev.com/#/-/detail/userstory/*********
As opposed to this: https://rally1.rallydev.com/slm/webservice/v2.0/hierarchicalrequirement/88502329352
The link will be integrated into another application for the managers to see the user story.
I did read about the getDetailUrl() method, but in my case I am creating the user stories by parsing email and linking that to a notification service in Slack.
I am aware of the formattedID and (_ref), but I would have to query for it again, and I am creating batches of userstories through a loop. I need the actual web site link to the user story.
Here is my sample code:
public void CreateUserStory(string workspace, string project, string userstoryName){
//authenticate with Rally
this.EnsureRallyIsAuthenticated();
//DynamicJsonObject for HierarchicalRequirement
DynamicJsonObject toCreate = new DynamicJsonObject();
toCreate[RallyConstant.WorkSpace] = workspace;
toCreate[RallyConstant.Project] = project;
toCreate[RallyConstant.Name] = userstoryName;
try
{
//Create the User Story Here
CreateResult createUserStory = _api.Create(RallyConstant.HierarchicalRequirement, toCreate);
Console.WriteLine("Created Userstory: " + "URL LINK GOES HERE");
}
catch (WebException e)
{
Console.WriteLine(e.Message);
}
}
We don't have a method in the .NET toolkit for doing this, but it's easy to create.
The format is this:
https://rally1.rallydev.com/#/detail/<type>/<objectid>
Just fill in the type (hierarchicalrequirement turns into userstory, but all the others are the same as the wsapi type) and the objectid from the object you just created.
var parameters = new NameValueCollection();
parameters["fetch"] = "FormattedID";
var toCreate = new DynamicJsonObject();
var createResult = restApi.create("hierarchicalrequirement", toCreate, parameters);
var type = Ref.getTypeFromRef(createResult.Reference);
var objectID = Ref.getOidFromRef(createResult.Reference);
var formattedID = createResult.Object["FormattedID"];
And you can specify fetch fields to be returned on the created object so you don't have to re-query for it.

Is Qooxdoo protected against XSS

I'm looking for informations about security on Qooxdoo.
I want to check my app vs OWASP top 10
A point to review is the XSS OWASP A3 XSS
How can I be sure that Qooxdoo is secure against XSS attacks ?
Does Qooxdoo use some sanitizer tools ?
SOLVED
A short answer from all the discussions. Yes Qooxdoo is XSS safe. By default, no javascript value in any field will be executed.
But, if you use rich=true, you have to check input/output
A common XSS attack vector are situations where an attacker somehow inputs JS code into a web application, such that this code then shows up in the DOM of a webpage and gets thus activated.
To protect against this kind of XSS, you must make sure that the backend server does not send user generated (un-cleaned) html towards the browser ... (this has nothing to do with qooxdoo).
That said, the regular qooxdoo widgets do not in general display data as html so you are reasonably safe even without a clever server. The exception is the qx.ui.basic.Label widget and its descendants. The Label widget has the ability to display HTML directly if you set the rich property. The rich property is set to false by default, but if you enable it, you have to make sure you don't display 'dangerous' html content.
Only very few (non essential) qooxdoo widgets allow you to insert HTML code into the DOM. In these instance you have to take care to sanitize the data. The widgets in question are:
qx.ui.embed.Html
qx.ui.table.cellrenderer.Html
qx.ui.progressive.renderer.table.cell.Html
qx.ui.virtual.cell.Html
qx.ui.virtual.layer.HtmlCell
qx.ui.virtual.layer.HtmlCellSpan
If you do use qx.html.* and qx.bom.*and qx.dom.* objects to work with the DOM directly, you are beyond the reach of qooxoo and have to take care to act accordingly.
Another important attack vector are authentication cookies. Most of the attacks work by getting the browser to send a request together with the cookie to its server without the user being aware it.
Qooxdoo itself does not require you to use cookies at all. Since qooxdoo applications by design run in a single browser window, you can work without ever using cookies. An easy way of implementing something like this is to have a 'server access singleton' which takes care of all the communication with the backend and supplies the access token in a special header added to every request.
The code below could serve as a guide ... for the cookie problem.
qx.Class.define('myapp.Server', {
extend : qx.io.remote.Rpc,
type : "singleton",
construct : function() {
this.base(arguments);
this.set({
timeout : 60000,
url : 'QX-JSON-RPC/',
serviceName : 'default'
});
},
properties: {
sessionCookie: {
init: null,
nullable: true
}
},
members : {
/**
* override the request creation, to add our 'cookie' header
*/
createRequest: function() {
var req = this.base(arguments);
var cookie = this.getSessionCookie();
if (cookie){
req.setRequestHeader('X-Session-Cookie',this.getSessionCookie());
}
return req;
}
}
});
and if you provide a login popup window in myapp.uiLogin you could replace
the standard callAsync by adding the following to popup a login window if the backend is unhappy with your request.
/**
* A asyncCall handler which tries to
* login in the case of a permission exception.
*
* #param handler {Function} the callback function.
* #param methodName {String} the name of the method to call.
* #return {var} the method call reference.
*/
callAsync : function(handler, methodName) {
var origArguments = arguments;
var origThis = this;
var origHandler = handler;
var that = this;
var superHandler = function(ret, exc, id) {
if (exc && exc.code == 6) {
var login = myapp.uiLogin.getInstance();
login.addListenerOnce('login', function(e) {
var ret = e.getData();
that.setSessionCookie(ret.sessionCookie);
origArguments.callee.base.apply(origThis, origArguments);
});
login.open();
return;
}
origHandler(ret, exc, id);
};
if (methodName != 'login') {
arguments[0] = superHandler;
}
arguments.callee.base.apply(this, arguments);
},
take a look at the CallBackery application to see how this works in a real application.

How to observe a computed property in EmberJS? Creating a FB like notification feature

I am building notification feature for my app just like Facebook's notification. I have almost made it work but just unable to observe a computed property.
Here is the scenario:
There are many deals and when a deal is updated(like it's name/ price is changed), the notification is sent through RabbitMQ. The object payload that we send, it has an attribute "status" which could be 'read' or 'unread'.
controller:
notificationsCount: function() {
var notifications = this.get('notifications');
var unreadCount = 0;
for (var i = 0; i < notifications.length; i++) {
if (notifications[i].status == 'unread') {
unreadCount++;
}
}
return unreadCount;
}.property('notifications.[]'),
Here, initially 'notifications' is an empty array. All the notifications coming from RMQ as object payloads goes inside this. This 'unreadCount' is what I want to show kinda like a small badge over the notification icon.
When I click the notification icon, all the notifications' status should change to 'read' from 'unread'.
controller:
action:{
readNotifications: function () {
var notifications = this.get('notifications');
for (var i = 0; i < notifications.length; i++) {
notifications[i].status = 'read';
}
},
}
Through debugging, I found everything is working fine till this point. But what I want is, once the user clicks the notification icon and all the notifications are marked as read, the notificationCount should be set as zero as there are no more any notifications that is unread.
Theoretically, I have to either observe notificationsCount or execute notificationsCount once inside readNotifications action. But I couldn't find a way to do it. If there is any other way, feel free to share.
Thanks in advance.
The short of it is that you should define your notificationsCount computed property to listen to notifications.#each.status instead of notifications.[]. .[] triggers when the array contents change (elements are added or removed), while an .#each.prop triggers when the prop property on any array element changes.
Refer to the relevant Ember.js docs for details on this.
Additionally, you can make your code more concise using NativeArray methods (because, since you are already using the .property() shorthand, you do have prototype extension enabled). Your entire notificationsCount could be written as
notificationsCount: function() {
return this.get('notifications').filterBy('status', 'unread').length;
}.property('notifications.#each.status'),
and your action as
readNotifications: function () {
this.get('notifications').setEach('status', 'read');
},

Trouble accessing child objects in Firebase

I'm trying to pull a list of connected users in Firebase to simply populate a select dropdown. My problem is that I can't seem to access the child objects properly.
Using connectedUsers.userName (see below code) works but only for my own user data, it doesn't pull anything else.
It seemed to me like changing "myUserRef.on" to "userListRef.on" and using something like "snapshot.child('userName').val()" should work but it just throws undefined. The same goes for "connectedUsers.child.userName", I'm sure I'm missing something simple here.
In the below code by changing to "userListRef.on('child_added', function(snapshot)" I can successfully add and remove user data from Firebase, and log all of the objects to the console and all data looks fine when I drill down the objects. I just need a way to access that data so I can put all connected users into a select dropdown or remove them from it when they disconnect.
var userListRef = new Firebase('https://myaccount.firebaseIO.com/users/');
var myUserRef = userListRef.push();
// ADD USER DATA TO FIREBASE
var userId = $('#myIdInput').val();
var userName = $('#nameInput').val();
myUserRef.push({userId: userId, userName: userName});
// READ USER OBJECTS AND FIRE ADDUSER FUNCTION
myUserRef.on('child_added', function(snapshot) {
var connectedUsers = snapshot.val();
console.log(addUser);
//addUser(connectedUsers.userId, connectedUsers.userName);
});
// ADD USER TO SELECT DROPDOWN
function addUser(userId, userName) {
var modSelect = $('#tsmmodsendto');
modSelect.append($('<option></option>').attr("value", userId).text(userName));
}
// READ USER OBJECTS AND FIRE REMOVEUSER FUNCTION
myUserRef.on('child_removed', function(snapshot) {
var connectedUsers = snapshot.val();
console.log(removeUser);
//removeUser(connectedUsers.userId, connectedUsers.userName);
});
// REMOVE USER TO SELECT DROPDOWN
function removeUser(userId, userName) {
var modSelect = $('#tsmmodsendto');
modSelect.append($('<option></option>').removeAttr("value", userId).text(userName));
}
// ON DISCONNECT REMOVE USER DATA FROM FIREBASE
myUserRef.onDisconnect().remove();
The code you've written won't work properly because each user is writing to:
/users/PUSH_ID/PUSH_ID
And is then listening at:
/users/PUSH_ID
So every client is going to be listening only to its own data and will never see anyone else's data. In order to view other people's data, you need to all be listening / writing to the same path.
In your question you mention you see "undefined" if you change to listening at /users. Could you simplify your code, and use that approach, and perhaps then I can provide a more helpful answer?
Or if I'm not understanding correctly, please simplify and clarify your question.