Manually Setting a firebaseStorageDownloadTokens on image Upload to Firebase Storage with Flutter - flutter

I am trying to put a file to Firebase Storage with the following:
final metadata = firebase_storage.SettableMetadata(
customMetadata: {'firebaseStorageDownloadTokens': customToken});
_uploadTask =
_storage.ref().child(filePath).putFile(widget.file!, metadata);
I get the following error in my console:
E/StorageException( 6906): Caused by: java.io.IOException: { "error": { "code": 400, "message": "Not allowed to set custom metadata for firebaseStorageDownloadTokens" }}
Submitting this as both a bug & feature request on the plugin site, but in the meantime, in the off-chance I'm just writing this wrong, as documentation on this isn't thorough, I thought I'd submit here to see if anybody has done it successfully from the client.
I'll be writing a cloud function later if I can't do it from client, but since this isn't a high security thing I'm doing...I have many reasons to avoid forcing my app to get the downloadUrl....my aim is to create a predictable downloadUrl...readily done in the cloud, I know, just looking to do it from the client here.

After talking to some folks, this is not allowed from the client. It has to be done with a Cloud Function. It's highly discouraged. Here is why:
Anyone can access images if they have the image ID and the downloadToken. The idea is that both are hard to guess...hence an modicum of security. You can set security rules to getDownloadUrl for authenticated users, hence "restricting" the viewability through the obscurity of the image name, downloadToken and location.
By manually setting a downloadToken, you erode that "security."
It is allowed, however, you have to do it with a cloud function, triggering on create of the image, over-writing the auto-generated downloadToken. Send me a DM for help in that if you need it.

Related

How can I resolve 400 bad request in Google Picker dialog in test application?

I'm running into trouble with test users and the Picker component in my web applicaton.
A subset of my test users are receiving a 400: The server cannot process the request because it is malformed when attempting to access the picker. Some of them experience a looping sign-in beforehand.
The picker is constructed in the following way inside of a useEffect in a React component:
// if there's a non-config related bug, I would imagine it must be related to getting the access token here.
const accessToken = gapi.auth2.getAuthInstance().currentUser.get().getAuthResponse().access_token;
const view = new picker.DocsView(picker.ViewId.DOCUMENTS);
view.setIncludeFolders(true);
const pickerDisplay = new picker.PickerBuilder()
.enableFeature(picker.Feature.MULTISELECT_ENABLED)
.setAppId(appId)
.addView(view)
.addView(new picker.DocsUploadView())
.setOAuthToken(accessToken)
.setDeveloperKey(apiKey)
.setCallback(pickerCallback)
.build();
setPicker(pickerDisplay); // sets picker state
Because I am not receiving the error message and the application has not been verified, I believe this likely has something to do with the IAM.
I believe I've been able to eliminate managed browsers settings,
cookie settings, and extensions as possible sources of error.
I've also added the users to the GCP project with the Browser role, though
they did not receive invites. What do I need to try next to resolve
this issue?
I cannot provide a minimum reproducible example because this only seems to be confined to a subset of my users' browsers.
I reached out to Google support, but unfortunately this is not covered.
I need to get this application into production relatively soon, so I'm very seriously considering just writing my own Drive microservice and recreating the Picker. I would love to avoid this though.

Firebase Storage Code -13000 Permission Error

I have previously been able to use firebase to store user images, but when once I created a new xcode project I've been getting this error:
Error Domain=FIRStorageErrorDomain Code=-13000 "An unknown error occurred, please
check the server response." UserInfo={object=WtLirPvwL9b7eI3zipGZkk1G4Hi2,
ResponseBody={
"error": {
"code": 400,
"message": "Permission denied. Please enable Firebase Storage for your bucket by
visiting the Storage tab in the Firebase Console and ensure that you have
sufficient permission to properly provision resources."
}
I have been getting this error even after setting up storage for my project.
And I don't think it has to do with the usage rules--for one, I allowed unauthorized reads and writes, and in my testing, the user is already authorized before attempting to push images to storage. In fact, the uid generated from firebase's auth is what is being used as the reference. Also noteworthy is the fact that authorization with firebase is working fine--I'm having no errors creating accounts.
Another interesting fact--I also received this error after setting up yet another XCode project (and the corresponding steps in Firebase). So with two different Xcode projects, the same error is happening to me.
EDIT: usage rules and permissions
rules_version = '2';
service firebase.storage {
match /b/{bucket}/o {
match /{allPaths=**} {
allow read, write: if request.auth != null;
}
}
}
This is the default usage configuration. I previously had changed the content to allow read allow write to see if that would affect anything. But my error is happening with both that config and the default one.
Also, someone linked in the comments to a site recommending to check IAM and Admin permissions. As I suspected, I am the owner and so I see no permission problem there.
Additionally, nothing appears to be wrong with the GoogleService-Info.plist, even though that was what I suspected was wrong. Indeed, it includes the correct string for my storage bucket.
EDIT 2: CONSOLE ERROR
Thanks for #Leopold for pointing out that this error also occurs in the console. At first I thought that the console was working for me (I was able to upload images to it) but I now get the error when trying to view the image I uploaded through the console.
I got to this page by clicking on the image name hyperlink.
For me it looks, that Google Cloud Platform configured in the way, that you do not have permission storage bucket.
Go to https://console.cloud.google.com
Pick your project
Navigate to Cloud Storage
Go to Permissions tab
Add permission. Add permission which suits your needs most.
For my storage I am allowing to access my storage for everyone. And for you to see and play for troubleshooting to do the same.
In the permission tap ADD
Add Storage Object Viewer
Click save
Considering I don't find older questions about this Exact issue, and that the only ones are from yesterday, then I suspect it's a server/google side issue. So I went on firebase storage, uploaded a file through the console, and then I saw this on the right side, under the upload button:
Error Loading Thumbnail/Image (Erro Carregando Visualiação)
image
And then I clicked on the name link (Nome: Fachada.jpg)
and got this:
Permission denied. Please enable Firebase Storage for your bucket by visiting the Storage tab in the Firebase Console and ensure that you have sufficient permission to properly provision resources.
{ "error": {
"code": 400,
"message": "Permission denied. Please enable Firebase Storage for your bucket by visiting the Storage tab in the Firebase Console and
ensure that you have sufficient permission to properly provision
resources." } }
So even the console is yielding this error! It's server sided, you just have to wait, and I have never seen this happen before on Firebase(there is no google search result for this exact error, except for yesterday Saturday, November 20th 2021)

flask-jwt-extended - Catch raise RevokedTokenError('Token has been revoked')

I already tried reading the documents as well try out the changing default behaviors https://flask-jwt-extended.readthedocs.io/en/latest/changing_default_behavior.html to handle the error (the link shows how to handle expired token) and search around in google everything in every keyword combination i could do but seems no one has example about this.
I tried using #jwt.revoked_token_loader to handle the RevokedTokenError but it seems it doesn't work as I applied it like this
#jwt.revoked_token_loader
def revoked_token_response(revoked_token):
jwtkn = revoked_token['jti']
return jsonsify({
'msg': 'token {} already been revoked!'.format(jwtkn)
)}, 401
actually, i don't know exactly how does the example on the link to handle expired tokens had parameter of 'expired_token', is that self-declaration like what I did above on the 'revoked_token'?? as far as I know, 'jti' is like a default value in the flask-jwt-extended package as I see error whenever I don't use this (in my db, it is different but there is no problem at all.
I tried following this tutorial and it works out fine on my side (as well his original code source) but I see that this one doesn't have a catch exception also on Revoke Tokens https://codeburst.io/jwt-authorization-in-flask-c63c1acf4eeb
I use postman and if based on the tutorial link, here's how i get this
i do login
i use the access token generated to access protected routes ('/secrets')
i do logout
i use again the access token generated to access protected routes
after the last one, i get this error on my server side (ide):
....flask_jwt_extended\utils.py", line 216, in verify_token_not_blacklisted
raise RevokedTokenError('Token has been revoked')
flask_jwt_extended.exceptions.RevokedTokenError: Token has been revoked
127.0.0.1 -- [02/Jul/2019 22:25:26] "GET /secrets HTTP/1.1" 500 -
in postman, this is what I get:
{
'message': 'Internal Server Error'
}
my target is to send out a custom json response instead of 'Internal Server Error'
edit:
I am no wiz on programming or such, a beginner that wanted to practice out python about secured web development. I don't yet quite understand still how decorator works out in terms of application, etc. so i don't know if others tweaks out the flask-jwt-extended package to work such things out.
Getting back a 500 error normally occurs because of a bug in other flask extensions and how that interact with native flask errorhandlers. You can find a bunch of discussions about it here (https://github.com/vimalloc/flask-jwt-extended/issues/86), but the tl;dr version is you might need to set app.config['PROPAGATE_EXCEPTIONS'] = True if using something like Flask-Restul, or use a hack like this if using flask-restplus:
jwt = JWTManager(app)
api = Api()
jwt._set_error_handler_callbacks(api)
If those don't help you, please take a look through that linked github issue, and if nothing in there helps make a reply in that issue detailing your setup.
Cheers.

Serverless Watson Deployment? (Questions about integrations with other RESTful services)

Introduction:
I feel like I'm missing something terribly obvious about how Watson Assistant should be designed at an architecture level, but maybe I'm not.
The specific problem I'm having is that I can't seem to get API calls for information back into the conversation.
The bigger issue is that I'm not sure I setting this all up correctly for the long-haul of what I'm trying to accomplish.
Purpose:
I am building a 24/7 customer-service Tier 1 helpdesk for our managed networks. A user of one of our networks should, via SMS, Web chat, Facebook messenger, and eventually phone call, be able to ask for:
Instructions on how to connect their specific device (PC, Mac, Chromebook, Xbox, Apple TV, etc.)
Ask for help troubleshooting if the instructions don't result in a successful connection. (Step by step instructions for deleting the saved network, restarting the wireless card, etc.)
Help creating a case - at which point the conversation becomes Watson asking for a bunch of information, like what time and date they first experienced the problem, any other times/dates they experienced the problem, their MAC address, etc. etc.
Problems:
I have most of the dialog built and working well. Getting information via Entities, saving to context variables, spitting them back out to make the conversation work, digressions, etc. all working.
I cannot, for the life of me, figure out what I am doing wrong when trying to GET information from an external API.
We have a 'daily password' for our guest networks, and we would like a user who asks for the daily password to receive it. This involves a very simple GET request to a publicly accessible server.
I have built a BlueMix/IBM Cloud function that works perfectly, but I can't seem to successfully call or receive information back from it.
Watson Error:
Error when updating output with output of dialog node id [node_66_xxxxxxxxxx]. Node output is [{"text":{"values":["Today's password for <? $guestNetwork.ssid ?> is <? $guestNetwork.password ?>"],"selection_policy":"sequential"}}] SpEL evaluation error: Expression [ $guestNetwork.ssid ] converted to [ context['guestNetwork'].ssid ] at position 0: EL1007E: Property or field 'ssid' cannot be found on null (and there is 1 more error in the log)
This error leads me to believe I am not properly defining the result variable in Watson, or improperly trying to retrieve it in conversation - because I do know my code returns the SSID and Password when I run it in BlueMix Console.
JSON for the action itself (and yes, I am setting the credentials in the previous node):
{
"output": {
"text": {
"values": [
"Today's password for <? $guestNetwork.ssid ?> is <? $guestNetwork.psk ?>"
],
"selection_policy": "sequential"
}
},
"actions": [
{
"name": "get-http-resource/getGuestNetworkPassword",
"type": "server",
"credentials": "$private.myCredentials",
"result_variable": "$guestNetwork"
}
]
}
Question:
Is my idea of a 'serverless' Watson possible by using Watson <-> IBM Cloud <-> external services? We don't currently have an 'application' or a server, it's all integrations between existing services.
Can anyone help me understand what I'm doing wrong when trying to access that variable?
Bonus points: How do I know to access the variable only after the action has completed successfully in IBM cloud? Basically, if accessing the information via the IBM Cloud function I wrote takes 1.5 seconds, do I need to pause the dialog for 1.5 seconds? Or am I completely missing the point for how to get external info in and out of Watson?
EDIT:
After watching Mitch's video, I have changed a couple things around, and the error message has evolved to this:
"Error when updating output with output of dialog node id
[node_66_1533646714776]. Node output is [{"text":{"values":["Today's
password for is "],"selection_policy":"sequential"}}] SpEL evaluation error:
Expression [ $guestNetwork['ssid'] ] converted to [
context['guestNetwork']['ssid'] ] at position 24: EL1012E: Cannot
index into a null value" error.
Without seeing your dialog, its a guess, but most common error I see is that you just need to jump to a child dialog node after doing the action call. You cannot do the action call and show the response in the same dialog node, as dialog needs a chance to run the action.
Its outlined in my video here:
https://ibm-dte.mybluemix.net/ibm-watson-assistant?refresh
see the video on dialog callouts. Its 13 minutes long I'm sure you only need about 2 of them, but still, should help.
What you are trying to do is definitely possible, especially if it works from within the cloud function environment.
We re-created the action using the default package (not having it in a sub-package), and it started working immediately.
Things to note: Watson dialog editor does not like dashes in the package name.
Thanks Mitch!

error: Failed to run the post merge process

I'm trying to generate documents using conga composer 8 from apex code but its failing with error Failed to run the post-merge process. I have looked into url and its same as the one I used initially in another salesforce org. I couldn't find any help online or on conga-composer form.
Here is my conga endpoint URL:
https://composer.congamerge.com/Composer8/Index.Html? sessionId=00D41000000dorw!ARQAQKbinH5TXMR_70s3XCShQh5GuSVdrFcq0Fg9OidZLo9MLxzWSby8QY1B4xM8e72DPawVziclnXBjTzpG41RiCAPKQqOt
&serverUrl=https://na35.salesforce.com/services/Soap/u/29.0/00D41000000dorwEAA
&id=a1J410000012BwS
&TemplateId=a0C41000000kg5GEAQ
&APIMODE=13
&ESAgreementName=Contract+for+Test
&queryid=a0441000001PwI7AAK,a0441000001PwICAA0
&ESSignatureType=2
&ESSignatureOrder=2
&ESVisible=1
&ESCustomField=cldocgen__App__c
&ESCustomFieldValue=a1J410000012BwSEAU
&ESRecipient1=00541000000Ke9pAAC
&ESRecipient2=003410000078zVbAAI
&ESRecipient3=003410000078zVhAAI, Method=GET]
Any insight what might be causing this issue.
I had the same problem and was able to solve it using permissions. In this case make sure the user id whose sessionID is passing to Conga has the correct CRUD access to the primary object in your conga call (id=a1J410000012BwS). My guess is that this is something to do with Conga not being able to write the attachment back to salesforce.
Apart from what Greg has mentioned, there are 2 more observations for this error:
Under Email Administration -> Deliverability -> Access to Send Email (All Email Services) should be set to All email.
In case you are using the EmailTemplateId parameter then the classic email template must be available for use.
Also mostly this error is also because of some discrepancy in the URL.