Google Drive Rest API (V3) - 404 error while accessing private file owned by self - google-api-nodejs-client

I am trying to download (export) a Google Drive file owned by me (private - not shared with anyone) using release 21.3.0 of the nodejs client for Google API. I have set up a project in Google API Console and received a API key for the Drive API. When I try to access my file from a node program, I get a 'File not found' error. If I make the file public (On - Public on the web), I can access it fine. I have also tried setting up a service account to user server-to-server OAuth2 by following instructions here. I am then using the code in the examples to create a JWT token and use that to request a access token. But even with using that token, I get 'File not found' error when the file is private. Here is the code that I have so far for this functionality -
let key = require(#location_of_json_key_file);
let jwtClient = new google.auth.JWT(
key.client_email,
null,
key.private_key,
['https://www.googleapis.com/auth/drive'],
null
);
jwtClient.authorize(function (err, tokens) {
if (err) {
console.log(err);
return;
}
console.log(tokens);
let fileId = #id_of_file_on_google_drive;
googleDriveApi.files.export(
{
access_token: tokens.access_token, //tried auth: jwtClient as well
fileId: fileId,
mimeType: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
//key: <API_access_key> //Tried with API Access Key
},
{encoding: null},
(err, buffer) => {
if (err) {
//keep getting the error here - Error: File not found: #id_of_file_on_google_drive
console.log(`Error occurred while exporting file from Google Drive - ${err}`);
} else {
//process the file...
}
}
);
});
If the file is owned by my account, should I not be able to access it using service account belonging to the same Google account even when the file is private? Otherwise, to make the Drive files accessible programmatically, you would have to make them public which is not always possible / advisable.
What am I missing here? Thanks for any pointers.

Related

How to Properly Set Permissions for a Custom Strapi Plugin

Strapi Version: 4.1.5
Operating System: Debian GNU/Linux 9
Database: PostgreSQL 13
Node Version: v14.16.0
NPM Version: 6.14.11
Yarn Version: v1.22.5
Hi everyone, I can’t seem to find consistent information on how to use permissions with a custom plugin in Strapi. I want to make an endpoint available to my front-end (Next.JS) application, but only when the front-end application has authenticated as a user and using the JWT that is returned from authenticating with Strapi. I keep getting a 401 returned.
Here’s what I’m doing:
I used this page to set up authentication in Strapi. I have a user created in Strapi, and from the front-end, I can authenticate and it returns a JWT token. When I set up collection types to only be accessible with the “authenticated” role, I can access those collection types in the api using this JWT token. So all of that works. The problem is that I can’t get this to work with my custom plugin, and I’m not sure why. I still get a 401 error instead.
Here’s how I set up the permissions:
Based on this page, I initially tried to leverage the isAuthenticated permission that the Users & Permissions plugin provides:
{
method: "GET",
path: "/progress",
handler: "memberProgress.getProgress",
config: {
policies: ['plugins::users-permissions.isAuthenticated']
},
},
Unfortunately, this did not work. The server raised an error, saying that this could not be found. So back on the document linked above, I decided to take the approach of creating my own gloabl permission. I created src/policies/is-authenticated.js with the following contents:
module.exports = (policyContext, config, { strapi }) => {
if (policyContext.state.user) { // if a session is open
// go to next policy or reach the controller's action
return true;
}
return false; // If you return nothing, Strapi considers you didn't want to block the request and will let it pass
};
Then, I modified my plugin’s route as follows:
{
method: "GET",
path: "/progress",
handler: "memberProgress.getProgress",
config: {
policies: ['global::is-authenticated']
},
},
This is all based on that document I linked to. Unfortunately, this still does not work. It seems to find the permission (server doesn’t raise an error about it), but when I try to access my plugin’s endpoint with the JWT token, I just get a 401 error.
Here is how I’m trying to access the endpoint on the front-end:
// VERIFIED, auth works and I get the expected jwt
const strapiAuth = await strapiApiAuth();
if ( strapiAuth && strapiAuth.hasOwnProperty("jwt") ) {
try {
const response = await axios.get(
`${process.env.STRAPI_BACKEND_URL}/member-progress/progress?year=2022&name=&pageSize=10&page=1`,
{
headers: {
Accept: "application/json",
Authorization: `Bearer ${strapiAuth.jwt}`
},
timeout: 500,
}
);
console.log(response);
} catch (error) {
// This is where I land with the 401 error
console.log(error);
}
}
Strapi check if you have a valid jwt by default with "authenticated" role, but you must mark the permission to your custom endpoint in "Settings→User & Permission Plugin→Roles" of admin panel also.

AWS CDK: Api Key ignored when testing api gateway locally?

I'm currently developping an API with aws-cdk and I'm testing it locally with aws-sam-cli and docker. I wanted to add the requirement of an API Key to call the API.
Here is the code inside my stack:
const api = new apigw.RestApi(this, "MyAPI", {
restApiName: "My API",
description: "BLABLABLA API",
});
const myLambdaIntegration = new apigw.LambdaIntegration(myLambda, {
proxy: false,
});
// Endpoints of the API
api.root.addResource("test").addMethod("GET", myLambdaIntegration, {
apiKeyRequired: true,
});
Then I build this stack and synth it (npm run build ; cdk synth --no-staging myStack > template.yaml
And try to test it locally
sam local start-api
When I request my api without any API KEY, the API returns me the result of my lambda. 😭
I expected it to return me an error like {"message":"Missing Authentication Token"}
Does anyone have an idea of what is going on?
I suspect it's because authorizations are ignored locally but didn't find anything about that...
Thanks in advance! 😁
Edit: After deploying this stack, the API correctly asks me for a token.

How to add policy to Keycloak - UI crashes

I'm trying to enable flow when some admin user by some admin client is able to create users and obtain their access tokens to be used for another clients.
I have KeyCloak setup with token exchange and fine grained authz enabled and configured clients. I'm able to login my admin user by REST api, then exchange token. But when I specify audience I got error.
This one returns token but I need token for another client/audience.
http -f POST https://my-keycloak-server.com/auth/admin/realms/my-realm/protocol/openid-connect/token grant_type=urn:ietf:params:oauth:grant-type:token-exchange requested_subject=1a147915-53fe-454d-906a-186fecfa6974 client_id=api-admin client_secret=23a4ecbe-a9e8-448c-b36a-a45fa1082e6e subject_token=eyJhbGeiOiJSUzI1NiIs......
This one is failing with error.
http -f POST https://my-keycloak-server.com/auth/admin/realms/my-realm/protocol/openid-connect/token grant_type=urn:ietf:params:oauth:grant-type:token-exchange requested_subject=1a147915-53fe-454d-906a-186fecfa6974 client_id=api-admin client_secret=23a4ecbe-a9e8-448c-b36a-a45fa1082e6e subject_token=eyJhbGeiOiJSUzI1NiIs...... audience=my-another-client
{
"error": "access_denied",
"error_description": "Client not allowed to exchange"
}
So I tried to setup fine grained auth for target audience client (enabled it in tab, then tried to add policy for my admin user to be able to exchange token) but when I want to add policy that will allow my admin user to perform token exchange I'm stuck on UI error.
When typing policy name I got 404 when Keycloak is looking for name colisions. Afaik 404 in this case shouldn't block form from posting because it is no name collision. Instead I got instantly redirected with error.
https://my-keycloak-server.com/auth/admin/realms/my-realm/clients/1bafa9a4-f7e2-422c-9188-58ea95db32ef/authz/resource-server/policy/search?name=some-name
In the end of the day I can't add any policy in Keycloak. All the time form validation is ending up with crash caused by 404 policy name not found.
I'm using dockerized keycloak 10.0.0
Any ideas?
I hacked it by live editing Angular JS UI script function that performs verification in line 2403.
this.checkNameAvailability = function (onSuccess) {
if (!$scope.policy.name || $scope.policy.name.trim().length == 0) {
return;
}
ResourceServerPolicy.search({
realm: $route.current.params.realm,
client: client.id,
name: $scope.policy.name
}, function(data) {
if (data && data.id && data.id != $scope.policy.id) {
Notifications.error("Name already in use by another policy or permission, please choose another one.");
} else {
onSuccess();
}
});
}
to
this.checkNameAvailability = function (onSuccess) {
onSuccess();
}
And that end up with successfuly added policy. Still looks like it's UI bug.

Trouble Logging In To Realm Object Server - Swift

I am stuck trying to log into the Realm Object Server (ROS) from my app. I rolled my own log in scheme with a Keychain wrapper but would like to use Realm and the ROS with the cloud.
But I cannot write or find a simple way to log in using the username/password credentials. This is the server error: auth.password: Handle request failed with: InvalidCredentials: The provided credentials are invalid or a user does not exist.: Given account:
I am logged in to the ROS via the terminal and my cloud provider on the ROS dashboard. I can see my name and userID but it says I have no Realms.
How would connect my app to the server url to log in?
Here's something (among 10 different things) I've tried:
private func setUpPermissions() {
SyncUser.logIn(with: .usernamePassword(username: username, password: password, register: false), server: syncServerURL) { (user, error) in
guard user != nil else {
print(error!.localizedDescription)
return
}
do {
// This is where I get stuck
print("Logged in successfully")
} catch {
print(error.localizedDescription)
}
}
}
}
I haven't found ant of good examples (just code snippets) so apologies for my own code.

Connecting Aurelia with backend API

Context: I'm starting a new project for my company. It's been many years since I've done some web development and decided to build it using the latest platforms (so I'm a still new to all of this).
Current stack:
Aurelia frontend (running on localhost:9000)
Backend REST API using ExpressJS (running on localhost:8000)
PostGreSQL database running on AWS, providing data for the backend
Question: I can't seem to connect my frontend with my backend properly.
Here is my code:
import {inject} from "aurelia-framework";
import {HttpClient} from "aurelia-http-client";
#inject(HttpClient)
export class Login {
constructor(httpClient){
this.http = httpClient;
}
signIn() {
const url = 'http://localhost:8000/api/user/demo/test';
this.http
.get(url)
.then(data => {
console.log("data");
console.log(data);
})
.catch(error => {
console.log('Error getting ' + url);
console.log(error);
});
};
}
This always end up in the catch block, with a "response: ProgressEvent"
If I put the url in the browser I get a proper JSON:
{"status":"success","data":[],"message":"Retrieved ALL users"}
The code above only works for 'local' content, i.e. localhost:9000. As soon as I need content from somewhere else I get this error. What am I missing?
I think that CORS is not allowing you to access localhost:8000 from localhost:9000. To solve this, you should enable your ExpressJS server to accept CORS requests from localhost:9000 (or all hosts using a wildcard "*").
Look into these resources:
https://enable-cors.org/server_expressjs.html
https://github.com/expressjs/cors
Or search Google for 'expressJS cors'.