I'm trying to use the standard tutorial from the Phonegap tutorial here: http://docs.phonegap.com/tutorials/develop/push-notifications/
I've got to "Sending Your First Push", trying to send to my Android device.
phonegap push --deviceID APA91bE1MmeTc92igNoi5OkDWUV --service fcm --payload "{ \"data\": { \"title\": \"Hello\", \"message\": \"World\"} }"
I replaced device ID with the ID that you get from the registration event/Device Push ID. I get the following error:
body: <html>
<head><title>502 Bad Gateway</title></head>
<body bgcolor="white">
<center><h1>502 Bad Gateway</h1></center>
<hr><center>nginx/1.4.6 (Ubuntu)</center>
</body>
</html>
According to this I should just try later, but I've been trying this over multiple days:
GCM push notifications cause 502 Bad Gateway
Is Phonegap missing something basic here that I should know, or does the tutorial simply not work? If it doesn't work, are there any plugin suggestions to get the push notifications quickly up and running?
Related
I am currently using Google Cloud Run to deploy an API and although everything was working fine I am now having quite a hard time understanding an error I get.
I created the API on python3 using FastAPI, the Location model is based on Pydantic's BaseModel.
To illustrate it I have defined a test route as follow :
class Location(BaseModel):
lat: float
lng: float
#router.get('/test_404')
async def test_404(origin: Location = Body(...),
destination: Location = Body(...)):
print(origin)
print(destination)
return {'res': 'ok'}
The route should take two arguments in the request's body : origin and destination, and it does but only when I deploy it locally.
This :
url_local = "http://0.0.0.0:8080/test_404"
data = {
'origin': {'lat': 104, 'lng': 342},
'destination': {'lat': 104, 'lng': 342}
}
resp = requests.get(url_local, json = data)
print(resp.text)
Outputs :
'{"res":"ok"}'
The issue arises when I deploy the same service on Cloud Run. All of my other routes work fine but here is the output I get when I use the code above with the container url :
<!DOCTYPE html>\n
<html lang=en>
<meta charset=utf-8>
\n
<meta name=viewport content="initial-scale=1, minimum-scale=1, width=device-width">
\n <title>Error 400 (Bad Request)!!1</title>\n
\n <a href=//www.google.com/><span id=logo aria-label=Google></span></a>\n
<p><b>400.</b>
<ins>That’s an error.</ins>
\n
<p>Your client has issued a malformed or illegal request.
<ins>That’s all we know.</ins>
This is an error triggered by google and that does not let my request reach the service (no log entry)
I've searched online but did not find what causes this error. What am I missing ?
Thank you very much
It might be related to this post, where a user experiences a similar message. After some reading, and seeing your example, I think the solution lies in the REST best practices.
Strictly speaking, a GET request should not send any data when doing the request, other than anything incorporated within the URI. Technically, everything is possible, but you should use query parameters instead of sending a body.
Some API wrappers (like Cloud Run), may not accept this behaviour, while in your local test it may seem to work. Other API wrappers may just accept a body with a GET request. I would recommend sticking to the REST best practices and you are fine.
I have used the Crossref REST API where I just send it a query in a browser address bar, which then returns results in JSON.
So I send the following URL:
https://api.crossref.org/works?query.bibliographic=Randomized trial of intensive early intervention for children with pervasive developmental disorder&query.author=Groen&rows=1
I was hoping to so the same with the Microsoft REST API, but if I send it:
I get "Access denied due to invalid subscription key".
Can I pass my key via the URL? If so how?
Or is it not that simple.
Does it need other code as well - I can code in PHP if needed, or use jQuery.
Something like:
$(document).ready(function() {
$.ajax({
type:'GET',
url:'https://api.crossref.org/works?query.bibliographic=<?php echo $title ?>&query.author=<?php echo $author ?>&rows=1&select=is-referenced-by-count,author,title,DOI,issn-type,volume,issue,link,page,abstract',
success:function(result) {
var total_results = result.message["total-results"];
}
});
But again, with the Microsoft API - how would I send it the keys?
Thank you.
What is "the Microsoft REST API"? Do you mean Azure API Management? "Invalid subscription key" implies that this is an API hosted in API Management which uses this term to describe its authentication model. The following answer assumes this is the case.
You would need to be registered as a user and be given a subscription key. There is a self-service portal for doing this, which is described by this documentation. It is up to the API's administrator whether you are permitted to self-service or not, so you may or may not be able to do this yourself, or you may have to request the administrator to register you. Further documentation describes a bit how to use the portal.
When you have it, you would apply it as an http header named Ocp-Apim-Subscription-Key, but the name it expects is also configurable and may have been changed, which the administrator would have to tell you.
I finally found the documentation for what I needed (the Microsoft documentation around Azure is a horrendous maze with a lot of stuff that is outdated and broken).
So the documentation is here:
https://msr-apis.portal.azure-api.net/docs/services/academic-search-api/operations/565d753be597ed16ac3ffc03?
I modified the Jacascript example at the bottom of page and came up with:
<!DOCTYPE html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
<script type="text/javascript">
$(document).ready(function() {
$.ajax({
type:'GET',
url:'https://api.labs.cognitive.microsoft.com/academic/v1.0/evaluate?expr=Composite(AA.AuN==%27jaime%20teevan%27)&count=2&attributes=Ti,Y,CC,AA.AuN,AA.AuId',
beforeSend: function(xhrObj){
// Request headers
xhrObj.setRequestHeader("Ocp-Apim-Subscription-Key","xxxxmykeyxxxxx");
},
success:function(result) {
alert(result.entities[0].Ti);
}
});
});
</script>
</head>
</html>
The query returns all the titles for the author "jamie teevan".
Though in this example I am just outputting the first title via 'alert'. I haven't coded the rest of it yet - just wanted to know if it worked or not at this point.
Now all I need to do is work out the expression to return all the citing documents for a given title + author!! :-/ wish me luck.
I have the following problem:
In Workfusion Studio I have created a new bot task and have defined 2 vars:
<var-def name="tJSON">
[{'Text':'ciao'}]
</var-def>
<var-def name="tLanguage">
<http-extended url="https://api.cognitive.microsofttranslator.com/translate?api-version=3.0" method="POST" charset="UTF-8" content-type="application/json">
<http-header-extended name="Ocp-Apim-Subscription-Key">83ffa3bd24bf4f75aa0814c3713bd0d4</http-header-extended>
<http-param-extended name="to">en</http-param-extended>
<var name="tJSON"/>
</http-extended>
</var-def>
I have the following response:
{"error":{"code":400036,"message":"The To field is required."}}
I have tested the following api via Restlet Client on Chrome:
What is wrong with the http-param-extended in my definition, please, advice!
Apparently the API requires the to parameter to be present in URL, rather than in the request body.
Can be done as following:
<http-extended url="https://api.cognitive.microsofttranslator.com/translate?api-version=3.0&to=en" ...
There are a few topics and articles on Solr authentication & authorization, but I cannot get it to work (the way I like).
I followed these tutorials / information sources:
https://cwiki.apache.org/confluence/display/solr/Authentication+and+Authorization+Plugins
and
https://lucidworks.com/blog/2015/08/17/securing-solr-basic-auth-permission-rules/
Then I created this security.json and I confirmed it is active in Zookeeper:
{
"authentication":{
"class":"solr.BasicAuthPlugin",
"credentials":{
"solr":"...",
"admin":"...",
"monitor":"...",
"data_import":"..."},
"":{"v":8}},
"authorization":{
"class":"solr.RuleBasedAuthorizationPlugin",
"permissions":[
{
"name":"security-edit",
"role":"adminRole"},
{
"name":"security-read",
"role":"adminRole"},
{
"name":"schema-edit",
"role":"adminRole"},
{
"name":"schema-read",
"role":"collectionRole"},
{
"name":"config-edit",
"role":"adminRole"},
{
"name":"config-read",
"role":"collectionRole"},
{
"name":"collection-admin-edit",
"role":"adminRole"},
{
"name":"collection-admin-read",
"role":"collectionRole"},
{
"name":"update",
"role":"dataImportRole"},
{
"name":"read",
"role":"dataImportRole"}],
"user-role":{
"solr":[
"adminRole",
"collectionRole",
"dataImportRole"],
"admin":[
"adminRole",
"collectionRole",
"dataImportRole"],
"monitor":[
"collectionRole",
"dataImportRole"],
"data_import":["dataImportRole"]}}}
I now have a security.json that works for curl requests from command line:
curl "http://localhost:8983/solr/admin/authorization"
Unauthorized request, Response code: 401
curl --user solr:<pwd> "http://localhost:8983/solr/admin/authorization"
Normal response with the info
So far so good.
Now I try and select something from a collection, which shouldn't work anonymously according to my security.json, however it still works
curl "http://localhost:8983/solr/outlets_shard1_replica1/select?q=*%3A*&wt=json&indent=true"
"responseHeader":{
"status":0,
"QTime":1,
"params":{
"indent":"true",
"q":"*:*",
"wt":"json"}},
"response":{"numFound":2000,"start":0,"d.. }
This is the first thing that vexes me. I probably can create some custom path permission for /select, but having the read right assigned to a specific role should do the trick right? but [1] How can I disable all anonymous access?
Continuing on, probably related, it bothers me that the Solr Admin UI(http://solrurl:8983/solr/#) is still accessible. In previous Solr installations (with tomcat) I remember that even this interface was secured. It also seems that I still have complete access to the entire core (reload worked) and I can also inspect cloud configuration.[2] How can I restrict access to Solr Admin UI?
The only stuff that actually seems to be secure is all the /solr/admin related commands
Which brings me to the 3rd thing I can't seem to figure out: How do I configure solr.in.sh so that solr authentication is passed with /bin/solr commands
I see the SOLR_AUTHENTICATION_CLIENT_CONFIGURER and SOLR_AUTHENTICATION_OPTS options, but I have no clue how to modify those to feed basic realm authentication into solr commandline. So [3] How do I keep all access from commandline to Solr (and Zookeeper) authorized & authenticated?
eg. solr status now returns
Found 1 Solr nodes:
Solr process 15931 running on port 8983
ERROR: Failed to get system information from http://localhost:8983/solr due to: org.apache.http.client.ClientProtocolException: Expected JSON response from server but received: <html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
<title>Error 401 Unauthorized request, Response code: 401</title>
</head>
<body><h2>HTTP ERROR 401</h2>
<p>Problem accessing /solr/admin/collections. Reason:
<pre> Unauthorized request, Response code: 401</pre></p><hr><i><small>Powered by Jetty://</small></i><hr/>
</body>
</html>
I've tested with
SOLR_AUTHENTICATION_OPTS="-DinternalAuthCredentialsBasicAuthUsername=solr -DinternalAuthCredentialsBasicAuthPassword=<pass>"
To no avail
I also faced the same issue and then I looked at the source code.
The read permission in RuleBasedAuthorizationPlugin is defined as :
read :{" +
path:['/update/*', '/get']}," +
Which will never work.
I have raised an issue:
https://issues.apache.org/jira/browse/SOLR-8439
Now, to lock down your admin ui completely, you need to define a new permission, with path="/", which will going to solve your issue, something like this:
curl --user solr:SolrRocks http://localhost:8983/solr/admin/authorization -H 'Content-type:application/json' -d '{
"set-permission" : {"name":"admin-ui",
"path":"/",
"before":"update",
"role":"admin"}}'
Did you forget setting the blockUnknown to true?
Your authentication block in security.json should be:
"authentication":{
"blockUnknown": true,
"class":"solr.BasicAuthPlugin",
"credentials":{"solr":"..."}
},
If you don't set it, it will allow all anonymous access! It is strange but here is the source:
'blockUknown:true' means that unauthenticated requests are not allowed to pass through [1]
Start by using the default user/Pw given in the Solr tutorials.
The passwords are hashed sha512 with a salt. Solr provides the encryption from the plaintext passwords when you create new authenticated users, but the pw in the Lucidworks instructions is already encrypted for the plaintext value: solrRocks (or similar) - use that account to create others, give them appropriate permissions, then remove the solr:solrRocks account.
I'm building a webapp with google appengine, node.js and socket.io, and I'm currently trying to set up a google compute instance to use the google cloud datastore api following this tutorial. So far, I've completed steps 1 and 2, but when running the downloaded adams.js file locally, I get this:
Error: No access or refresh token is set.
Stuff I've tried:
gcloud auth login (this logs me in google, but doesn't set my token locally)
changing the way I'm exporting my DATASTORE_SERVICE_ACCOUNT and DATASTORE_PRIVATE_KEY_FILE values, as strings, plain text, etc.
logging my credentials on the line before the error (I'm definitely missing a token)
creating a new service account and going through key creation steps again
ran
curl "http://metadata/computeMetadata/v1/instance/service-accounts/default/token" -D "Metadata-Flavor: Google" to get more info.
that command gives me this:
<html>
<head><title>301 Moved Permanently</title></head>
<body bgcolor="white">
<center><h1>301 Moved Permanently</h1></center>
<hr><center>nginx</center>
</body>
</html>
so I'm definitely missing a token, but for some reason I cannot figure out how I am supposed to be getting it. Or where I need to store it when my app is deployed and wants to access the API online. It feels like this should be a really easy thing to find, but for some reason all the documentation I'm reading is leading me into walls. Any help would be awesome.
If your code is running on a Google Compute Instance, and the instance has the correct scopes, you don't need to set any environment variables.
You can confirm the scopes by looking at the instance in the Developers Console or by asking the metadata server:
curl http://metadata/computeMetadata/v1/instance/service-accounts/default/scopes -H "Metadata-Flavor: Google"
To use Cloud Datastore, both the datastore and userinfo.email scopes must be present.