Why is the list of spaces of my Confluence wiki empty? - confluence-rest-api

I have a Confluence wiki with over 1000 spaces. I try to retrieve the list of spaces of my Confluence wiki using the curl query:
curl -D -u user:password -X GET \
-H "Content-Type: application/json" https://[hostname]/rest/api/space
It returns an empty list of spaces:
{"results":[],"start":0,"limit":25,"size":0,
"_links":{"self":https://[hostname]/rest/api/space,
"e":https://[hostname],"context":""}}
What could be the issue?

https://developer.atlassian.com/cloud/confluence/rest/api-group-space/#api-wiki-rest-api-space-get states:
Note, the returned list will only contain spaces that the current user has permission to view.
That was indeed a permission issue: the account used to make the curl query had no permission for any spaces.

Related

Trying to get a session value from a post call in Postman: TypeError: postman.getResponseHeader is not a function

In Postman, I am trying to retrieve a session value returned from a post call and use it in another get call.
I mean, I called via Postman:
curl -X POST \
https://skyscanner-skyscanner-flight-search-v1.p.rapidapi.com/apiservices/pricing/v1.0 \
-H 'Accept: */*' \
-H 'Cache-Control: no-cache' \
-H 'Connection: keep-alive' \
-H 'Content-Type: application/x-www-form-urlencoded' \
-H 'Host: skyscanner-skyscanner-flight-search-v1.p.rapidapi.com' \
-H 'Postman-Token: xxxx' \
-H 'User-Agent: PostmanRuntime/7.15.0' \
-H 'accept-encoding: gzip, deflate' \
-H 'cache-control: no-cache' \
-H 'content-length: 177' \
-d 'inboundDate=2019-11-25&cabinClass=economy&children=0&infants=0&Country=BR&Currency=BRL&locale=pt-BR&originPlace=GRU-sky&destinationPlace=MCZ-sky&outboundDate=2019-11-19&adults=2'
It returned in Header among others keys:
Location →http://partners.api.skyscanner.net/apiservices/pricing/uk2/v1.0/b5b906e9-164e-4f1d-b5ce-9085b8a3506d
Now, I want to call another API and I must use the session id returned in previous call. It is after /v1.0/. In this case it is b5b906e9-164e-4f1d-b5ce-9085b8a3506d
The first steps is getting the Location key value but I am getting the error mentioned in this question title (see picture attached for more details).
So my straight question is how can I retrieve the Location value from another post request? Well, a complementary and helpfull coment will be how to parse and get only the session id but naturally firsly I have to fix how retrieve the whole Location value.
It is more or less this what I am trying:
var sessionKey = JSON.parse(postman.getResponseHeader('Location') );//maybe here applying some regular expression to get only the value after the last "/"
pm.environment.set("sessionkey", postman.getResponseHeader("sessionkey"));
My question is somehow close to In POSTMAN how do i get substring of response header item? but here the question author is able to use postman.getResponser and it seems he didn't get a final answer at the end.
My Postman version is 7.3.4 (Latest) (I have just updated it).
*** edited after first sugestion
*** another tentative failling
var locationHeader = pm.response;
console.log(pm.response); //Print successfully all response including body and header
var jsonData = JSON.parse(pm.response); //exception: There was an error in evaluating the Pre-request Script: JSONError: Unexpected token u in JSON at position 0
console.log("Location = " + jsonData.Location);
PS. it is interesting that
pm.request.headers.add({key: 'X-RapidAPI-Host', value: 'skyscanner-skyscanner-flight-search-v1.p.rapida.com'})
works properly in my collection Pre-request scripts. It is obvious to have pm.request.headers.get, isn't it? But it doesn't have.
*** edited
I also added this question in https://community.getpostman.com/t/trying-to-get-a-session-value-from-a-post-call-in-postman-typeerror-postman-getresponseheader-is-not-a-function/6804
*** edited
Just in case someone get interested, my final implementation is
var locationHeader = pm.response.headers.get("Location").split('/');
var locationPosition = locationHeader.length-1;
var sessionKey = locationHeader[locationPosition];
pm.environment.set("sessionkey", sessionKey);
in Test tab while calling POst Create Session
Add the following script in the first request test, it will set sessionkey value that you can use for later calls.
var locationHeader = postman.getResponseHeader("Location").split('/');
var sessionKey = locationHeader[locationHeader.length-1];
pm.environment.set("sessionkey", sessionKey);

Which `format` would be negotiated for REST request?

There are three variants of format selection:
curl -uadmin:admin "http://localhost:8080/alfresco/service/hellouser.json"
curl -uadmin:admin "http://localhost:8080/alfresco/service/hellouser?format=json"
curl -uadmin:admin -H "Accept: text/html" "http://localhost:8080/alfresco/service/hellouser"
But this is unclear from the DOC what format would be selected for next query:
curl -uadmin:admin -H "Accept: text/html" "http://localhost:8080/alfresco/service/hellouser.xml?format=json"
I expect json here.
May someone provide links to relevant specifications or documentation which describes priority how {format} negotiated? like this is described for Rails:
Rails picks up the expected format from the query parameter format, or if not there from the URL path suffix, or it not there from the Accept header
UPD
The controller can handle all supplied formats: json, xml, html
UPD
Another corner case:
curl -uadmin:admin "http://localhost:8080/alfresco/service/hellouser.pl?format=json"
curl -uadmin:admin "http://localhost:8080/alfresco/service/hellouser.pl?format=xml"
I'd believe you wouldn't have a 200 response, only an error with content negotiation.
The code shows that:
?format=json(format_query_param) will be discarded by the .xml (format_suffix)
filter available renderers leaving only the XMLRenderer left
then it will loop on the accept header but none will match text/html
finally this will be down to the exception

django | class based views | user passwords not working using curl [duplicate]

I've a few APIs I'd like to test with cURL. I tried doing a GET as follows:
curl --user username:password --request GET http://my_domain/get_result/52d6428f3ea9a008358ad2d8/
On the server, it showed a '302' (which means redirection, right?). I'm guessing it redirected to the 'login/' page.
What is the proper way of getting this done?
Edit: I tried:
curl -c cookies.txt -b cookies.txt -L -d #login_form.txt http://my_domain/login/
where login_form.txt contains "username=username&password=password&this_is_the_login_form=1". Doesn't work. No cookies.txt files generated. And no login happening. Can you tell me how you achieve login to Django using cURL?
Here is a fully coded answer. The idea of the solution is:
you have to first visit the login page with GET to get the cookies file generated,
then parse the CSRF token out of the cookies file
and do the login using a POST request, passing the data with -d.
Afterwards you can perform any request always using that CSRF token in the data ($DJANGO_TOKEN) or with a custom X-CSRFToken header. To log out simply delete the cookies file.
Note that you need a referer (-e) to make Django's CSRF checks happy.
LOGIN_URL=https://yourdjangowebsite.com/login/
YOUR_USER='username'
YOUR_PASS='password'
COOKIES=cookies.txt
CURL_BIN="curl -s -c $COOKIES -b $COOKIES -e $LOGIN_URL"
echo -n "Django Auth: get csrftoken ..."
$CURL_BIN $LOGIN_URL > /dev/null
DJANGO_TOKEN="csrfmiddlewaretoken=$(grep csrftoken $COOKIES | sed 's/^.*csrftoken\s*//')"
echo -n " perform login ..."
$CURL_BIN \
-d "$DJANGO_TOKEN&username=$YOUR_USER&password=$YOUR_PASS" \
-X POST $LOGIN_URL
echo -n " do something while logged in ..."
$CURL_BIN \
-d "$DJANGO_TOKEN&..." \
-X POST https://yourdjangowebsite.com/whatever/
echo " logout"
rm $COOKIES
I have a slightly more secure version of this code, which uses a file for submitting the POST data, as a Gist on GitHub: django-csrftoken-login-demo.bash
Interesting background reading on Django's CSRF token is on docs.djangoproject.com.
Passing username:password in a curl request is only good for HTTP Authentication, which isn't how most websites do auth these days. Instead, you'll have to post to the login page, get the cookie, then pass it back when requesting your desired page.
Actually #Paterino answer is correct but it will not work on every implementation of sed. Instead sed 's/^.*csrftoken\s*//') we can use sed 's/^.*csrftoken[[:blank:]]*//') which is more old fashioned. MacOSXs curl doesn't use escaping, so \n\t\s don't work at all.
To use the token with a get request, use
$CURL_BIN \
-H "$DJANGO_TOKEN" \
-X GET https://yourdjangowebsite.com/whatever/
I tried using -d with -X GET, however it resulted in weird socket behaviour on the server side (Heruko H18 errors).
I'm using Django 4.1.2 and trying the #Paterino method found a couple of changes to make it work (but i have not enogh reputation to comment so wrote another answer).
Firstly, if the generated cookies.txt file is empty you have to ensure than csrf cookie is generated. I achieved this using django.views.decorators.csrf.ensure_csrf_cookie in django.contrib.auth.views.LoginView
Now, after login cookies.txt changes, so you have to recalculate DJANGO_TOKEN variable in the same way:
DJANGO_TOKEN="csrfmiddlewaretoken=$(grep csrftoken $COOKIES | sed 's/^.*csrftoken\s*//')"
From here the method doesn't change.
the accepted answer, until now(2022-12-19), has 2 issues:
misses updating DJANGO_TOKEN after login (since a new csrftoken cookie is returned after login)
doesn't include an example with a POST request (moving the csrftoken to a header) where -d already contains some payload
here is my version dealing with both:
# user and password from `./manage.py createsuperuser`
YOUR_USER='user'
YOUR_PASS='pass'
COOKIES=cookies.txt
LOGIN_URL=http://localhost:8000/admin/login/
# stores csrftoken cookie on cookies.txt
curl -s -c $COOKIES $LOGIN_URL > /dev/null
TOKEN_VALUE="$(grep -oP '(?<=csrftoken[[:space:]]).*' cookies.txt)" # https://stackoverflow.com/a/10358949/3026886 https://stackoverflow.com/a/4233691/3026886
# logs in, updating csrftoken and adding sessionid cookies
curl -b $COOKIES -c $COOKIES -d "csrfmiddlewaretoken=$TOKEN_VALUE&username=$YOUR_USER&password=$YOUR_PASS" $LOGIN_URL
# updates var env with new cookie
TOKEN_VALUE="$(grep -oP '(?<=csrftoken[[:space:]]).*' cookies.txt)"
# here comes the real request
curl -s -X POST -b $COOKIES -d "{\"a\":1}" -H "X-CSRFToken: $TOKEN_VALUE" http://localhost:8000/yourViewReceivingJsonPayload/ > /dev/null
rm cookies.txt

Django-rest-auth basic authorization error {"password":["(This field is required"]}

I i am new to django-rest-auth and apis.
Its the first time i build a rest auth and i am not very familiar with Authorization headers and Content Types.
I am trying to understand why when i try to authenticate a user in /login/ with Basic Authorization like this:
curl -X POST -H "Authorization: Basic dXNlcm5hbWU6cGFzc3dvcmQ=" 'https://myurl.com/rest-auth/login/' --insecure
i got this error message:
{"password":["(This field is required"]}
When passing the username and password in the body like this:
curl -X POST -H "Content-Type: application/x-www-form-urlencoded" -d 'username=myuser&password=mypassword' 'https://myurl.com/rest-auth/login/' --insecure
I got the key:
{"key":"b5c0f3a9c7b2fc2f58a74b25f816e2968c64712f"}
Why this is happening?
I also wonder why when trying the same in /user/ it didn't throw me any error and give me my user model serialized
curl -X GET -H "Authorization: Basic dXNlcm5hbWU6cGFzc3dvcmQ=" -H "Cache-Control: no-cache" 'https://myurl.com/rest-auth/user/' --insecure
The only difference i can understand is that in /login i am using POST and in /user/ is GET
Can anybody explain this to me?
Thanks for reading!
The '/auth/login/' endpoint is specifically for getting an authentication token to use with token authentication on the rest of the app. It doesn't itself support any authentication methods. The second curl command uses the correct method. the third curl command works because you are using an endpoint which does support Basic Authentication (you can could also use the token you got in the second call).
pls refer
Inet Mode Example (unprivileged user with AltAuth)
$ echo -e "GET http://localhost/slurm/v1/diag HTTP/1.1\r\nAccept: */*\r\n" |
slurmrestd -f etc/slurm.token.conf
● slurmrestd: operations_router: /slurm/v1/diag for pipe:[1052487]
● HTTP/1.1 200 OK
● Content-Length: 973
● {
● "parts_packedg": 1,
● "req_timeg": 1568051342,
● "req_time_startg": 1568050812,
● "server_thread_count": 3,
… JSON continues ...

How to cURL an Authenticated Django App?

I've a few APIs I'd like to test with cURL. I tried doing a GET as follows:
curl --user username:password --request GET http://my_domain/get_result/52d6428f3ea9a008358ad2d8/
On the server, it showed a '302' (which means redirection, right?). I'm guessing it redirected to the 'login/' page.
What is the proper way of getting this done?
Edit: I tried:
curl -c cookies.txt -b cookies.txt -L -d #login_form.txt http://my_domain/login/
where login_form.txt contains "username=username&password=password&this_is_the_login_form=1". Doesn't work. No cookies.txt files generated. And no login happening. Can you tell me how you achieve login to Django using cURL?
Here is a fully coded answer. The idea of the solution is:
you have to first visit the login page with GET to get the cookies file generated,
then parse the CSRF token out of the cookies file
and do the login using a POST request, passing the data with -d.
Afterwards you can perform any request always using that CSRF token in the data ($DJANGO_TOKEN) or with a custom X-CSRFToken header. To log out simply delete the cookies file.
Note that you need a referer (-e) to make Django's CSRF checks happy.
LOGIN_URL=https://yourdjangowebsite.com/login/
YOUR_USER='username'
YOUR_PASS='password'
COOKIES=cookies.txt
CURL_BIN="curl -s -c $COOKIES -b $COOKIES -e $LOGIN_URL"
echo -n "Django Auth: get csrftoken ..."
$CURL_BIN $LOGIN_URL > /dev/null
DJANGO_TOKEN="csrfmiddlewaretoken=$(grep csrftoken $COOKIES | sed 's/^.*csrftoken\s*//')"
echo -n " perform login ..."
$CURL_BIN \
-d "$DJANGO_TOKEN&username=$YOUR_USER&password=$YOUR_PASS" \
-X POST $LOGIN_URL
echo -n " do something while logged in ..."
$CURL_BIN \
-d "$DJANGO_TOKEN&..." \
-X POST https://yourdjangowebsite.com/whatever/
echo " logout"
rm $COOKIES
I have a slightly more secure version of this code, which uses a file for submitting the POST data, as a Gist on GitHub: django-csrftoken-login-demo.bash
Interesting background reading on Django's CSRF token is on docs.djangoproject.com.
Passing username:password in a curl request is only good for HTTP Authentication, which isn't how most websites do auth these days. Instead, you'll have to post to the login page, get the cookie, then pass it back when requesting your desired page.
Actually #Paterino answer is correct but it will not work on every implementation of sed. Instead sed 's/^.*csrftoken\s*//') we can use sed 's/^.*csrftoken[[:blank:]]*//') which is more old fashioned. MacOSXs curl doesn't use escaping, so \n\t\s don't work at all.
To use the token with a get request, use
$CURL_BIN \
-H "$DJANGO_TOKEN" \
-X GET https://yourdjangowebsite.com/whatever/
I tried using -d with -X GET, however it resulted in weird socket behaviour on the server side (Heruko H18 errors).
I'm using Django 4.1.2 and trying the #Paterino method found a couple of changes to make it work (but i have not enogh reputation to comment so wrote another answer).
Firstly, if the generated cookies.txt file is empty you have to ensure than csrf cookie is generated. I achieved this using django.views.decorators.csrf.ensure_csrf_cookie in django.contrib.auth.views.LoginView
Now, after login cookies.txt changes, so you have to recalculate DJANGO_TOKEN variable in the same way:
DJANGO_TOKEN="csrfmiddlewaretoken=$(grep csrftoken $COOKIES | sed 's/^.*csrftoken\s*//')"
From here the method doesn't change.
the accepted answer, until now(2022-12-19), has 2 issues:
misses updating DJANGO_TOKEN after login (since a new csrftoken cookie is returned after login)
doesn't include an example with a POST request (moving the csrftoken to a header) where -d already contains some payload
here is my version dealing with both:
# user and password from `./manage.py createsuperuser`
YOUR_USER='user'
YOUR_PASS='pass'
COOKIES=cookies.txt
LOGIN_URL=http://localhost:8000/admin/login/
# stores csrftoken cookie on cookies.txt
curl -s -c $COOKIES $LOGIN_URL > /dev/null
TOKEN_VALUE="$(grep -oP '(?<=csrftoken[[:space:]]).*' cookies.txt)" # https://stackoverflow.com/a/10358949/3026886 https://stackoverflow.com/a/4233691/3026886
# logs in, updating csrftoken and adding sessionid cookies
curl -b $COOKIES -c $COOKIES -d "csrfmiddlewaretoken=$TOKEN_VALUE&username=$YOUR_USER&password=$YOUR_PASS" $LOGIN_URL
# updates var env with new cookie
TOKEN_VALUE="$(grep -oP '(?<=csrftoken[[:space:]]).*' cookies.txt)"
# here comes the real request
curl -s -X POST -b $COOKIES -d "{\"a\":1}" -H "X-CSRFToken: $TOKEN_VALUE" http://localhost:8000/yourViewReceivingJsonPayload/ > /dev/null
rm cookies.txt