Node Acl | Authorization for Dynamic Urls - node.js

I am using node acl for authorization for my rest end points into my node app.
The the roles based authorization works perfectly fine for the below urls.
acl.allow([{
roles: ['user'],
allows: [{
resources: ['/books/v1/single'],
permissions: ['post'],
},
{
resources: ['/books/v1/book/list'],
permissions: ['get'],
},
]
},
{
roles: ['admin'],
allows: [{
resources: ['/books/v1/list'],
permissions: ['get'],
}
]
}]);
But when I try to add dynamic urls it does not works as expected and gives the error which meant as UnAuthorized Needs more permissions.
acl.allow([{
roles: ['user'],
allows: [{
resources: ['/books/v1/single'],
permissions: ['post'],
},
{
resources: ['/books/v1/book/list'],
permissions: ['get'],
},
]
},
{
roles: ['admin'],
allows: [{
resources: ['/books/v1/list'],
permissions: ['get'],
},
{
resources: ['/books/v1/user/:userID/book/:bookID'],
permissions: ['get', 'put', 'delete'],
},
{
resources: ['/users/v1/list'],
permissions: ['get'],
},
{
resources: ['/users/v1/:userId'],
permissions: ['get', 'post', 'put', 'delete'],
}
]
}]);
So it gives unauthorized error for rest endpoints for dynamic urls i.e. /users/v1/:userId or /books/v1/user/:userID/book/:bookID
Any way/method in which same can implemented using node-acl libraray.

That's because node acl does not actually support hierarchy. It is really just a flat list, so it is explicitly checking for the string to match the resource. This is just a fundamental problem with the package. Since all the functionality is contained in the middleware, and it just isn't extensible there is no way to do what you want with this package without making a change so that it accepts a custom handler to decide what to pass to the middleware check.
Here's an example of the relevant open issue from 2017-08. The lack of funcitonality here is exactly why solutions like PolicyServer and Authress exist which do handle wildcard middleware and dynamic resource hierarchies.

Related

EISDIR issue in Azure hosted Nuxt Vue webiste

I have hosted a Web app in Azure DevOps, the application built with Vue and Nuxt.
#vue/cli 5.0.1 and "nuxt": "^2.15.8". After hosting the web application works fine, I can login, then it navigates me to the listing page. But from there when I refresh the page it's showing this error. Sorry, check with the site admin for error: EISDIR .. in the browser and throwing a 500 Error in the console. In my login response I get only access token, there is no refresh token, could that be an issue? or any other settings in the Azure side? We tried setting this in the azure pm2 serve /home/site/wwwroot --no-daemon --spa. Still it's not working. Everything works fine in my dev environment.
export default {
ssr: false,
head: {
title: 'BBG Returns Self Service',
meta: [
{ charset: 'utf-8' },
{ name: 'viewport', content: 'width=device-width, initial-scale=1' },
{ hid: 'description', name: 'description', content: '' },
{ name: 'format-detection', content: 'telephone=no' },
],
link: [{ rel: 'icon', type: 'image/x-icon', href: '/favicon.ico' }],
},
plugins: ['~/plugins/clearTokens.js'],
components: true,
buildModules: ['#nuxtjs/style-resources'],
env: {
BASE_URL: 'https://my-api-url',
},
publicRuntimeConfig: {
baseURL: process.env.BASE_URL,
},
router: {
mode: 'history',
},
styleResources: {
// scss: ["~assets/scss/main.scss"],
},
modules: ['#nuxtjs/i18n'],
build: { transpile: [/^#storefront-ui/] },
server: {
port: 4200,
},
i18n: {
locales: [
{
code: 'en',
iso: 'en-GB',
name: 'English',
file: 'en.json',
icon: 'uk.svg',
},
{
code: 'de',
iso: 'de-DE',
name: 'Deutsch',
file: 'de.json',
icon: 'de.svg',
},
],
lazy: true,
langDir: 'i18n/',
defaultLocale: 'en',
detectBrowserLanguage: false,
},
target: 'static',
}
If deploying an SPA app, you need to have both:
target: 'static' (the default being 'server')
ssr: false
This removes quite some benefits regarding SEO + performance but at least, you still get all the benefits of the Nuxt DX and ecosystem.
To host it on Azure, you have several approaches, if you're using:
a static app, you can follow this official documentation for Azure Static Web Apps: https://nuxtjs.org/deployments/azure-static-web-apps/
a SSR app, you can follow this one about Azure Portal: https://nuxtjs.org/deployments/azure-portal
The actual issue was the Azure configuration. The resource should be created as Static website, then it will work fine.
Please follow this official documentation to understand How to Deploy in Azure.
https://nuxtjs.org/deployments/azure-static-web-apps/

How to make my cloud run service public (Allow unauthenticated invocations) using googleapi node.js?

My script deploys a cloud run service, but after several hours of search i can't find the option to make the service public available.
const auth = new google.auth.GoogleAuth({
keyFile: 'path/to/keyfile.json',
scopes: ['https://www.googleapis.com/auth/cloud-platform'],
});
const authClient = await auth.getClient();
const run = google.run({
version: 'v1',
auth: authClient,
rootUrl: 'https://europe-west6-run.googleapis.com/'
});
const response = await run.namespaces.services.create({
parent: 'namespaces/pace21',
requestBody: {
metadata: {
name: 'my-new-service',
namespace: 'myProject',
annotations: {
'run.googleapis.com/ingress': 'all',
},
},
kind: 'Service',
apiVersion: 'serving.knative.dev/v1',
spec: {
template: {
spec: {
containers: [
{
image: 'europe-west6-docker.pkg.dev/path/to/image',
}
]
}
},
traffic: [{ percent: 100, latestRevision: true }]
}
}
}, {})
I can see an option in the package but I don't know how to apply it.
Thanks #JohnHanley.
The second request to change the policy of the new service is the answer I was searching for. For completion the node script:
const policy_response = await run.projects.locations.services.setIamPolicy({
resource: `projects/${project_id}/locations/europe-west6/services/${service_name}`,
requestBody: {
policy: {
bindings: [
{
role: 'roles/run.invoker',
members: [
'allUsers',
],
},
],
},
},
});

How can I write to a file from a React component?

I have a SideNav menu that looks for a file called route.js that has a array inside it called routes. I am trying to change the value of routes in routes.js from another component. I want to be able to add an delete the physical array in the file routes.js from a component. Any help would be appreciated.
import Shop from "examples/Icons/Shop";
// import Office from "examples/Icons/Office";
const routes = [
{
type: "collapse",
name: "Our Mission",
key: "dashboards",
icon: <Shop size="12px" />,
collapse: [
{
name: "Ways We can Help",
key: "default",
route: "/dashboards/default",
component: Default,
},
{
name: "How It Works",
key: "automotive",
route: "/dashboards/automotive",
component: Automotive,
},
{
name: "Who We Are",
key: "smart-home",
route: "/dashboards/smart-home",
component: SmartHome,
},
],
},
{ type: "title", title: " ", key: "space1" },
{
type: "collapse",
name: "Services",
key: "services",
icon: <Shop size="12px" />,
href: "https://github.com/creativetimofficial/ct-soft-ui-dashboard-pro-material-ui/blob/main/CHANGELOG.md",
component: Default,
noCollapse: true,
},
];
export default routes;
Component accessing the routes.js
import routes from "../../../routes";
const loggedroutes = [
{
type: "collapse",
name: "Profile",
key: "profile",
icon: <CgProfile size="12px" color="blue" />,
route: "/dashboards/Default",
collapse: [],
},
{
type: "collapse",
name: "Calendar",
key: "calendar",
component: link,
route: "/dashboards/Default",
icon: <GoCalendar size="12px" color="blue" />,
collapse: [],
},
]
routes = loggedinroutes;
i want to change the data in routes.js to match the array loggedinroutes
Ok without knowing too much of what you're doing, I put together a quick sandbox on how I would go about this.
https://codesandbox.io/s/hopeful-shirley-q9mhz?file=/src/routes.js
I would basically use logic based on either a button click/state/page query/etc and pass that through a function that would load the routes in your navbar dynamically. in the app.js file you can see how I used the useState() hook with button clicks to dynamically load the routes.
I'm sure there is a more elegant way to accomplish this but I hope this gets you in the right direction!

Swagger bearerAuth token block request from UI

I am using the swagger UI interface to test my node js requests.
I added the Authentication for those requests but when I try them in swagger I have the following issue:
If I add a bearerAuth token in the swagger UI When I click on execute in one of my requests, they are not executed. If I don't put a bearerAuth token my request plays as intended.
To add a token I added those options :
const openApi = OpenAPI({
schema,
info: {
title: '**** API',
version: '1.0.0',
},
components: {
securitySchemes: {
bearerAuth: {
type: 'http',
scheme: 'bearer',
bearerFormat: 'JWT',
},
},
},
security: {
bearerAuth: [],
},
});
security must be an array:
security: [
{ bearerAuth: [] }
],

Symfony2 - FOSOauthServerBundle - Firewall configuration - Route Whitelist

My goal is to have all routes under the firewall protected API except some.
I have firewall configuration like this:
security:
acl:
connection: default
providers:
fos_userbundle:
id: fos_user.user_provider.username_email
encoders:
FOS\UserBundle\Model\UserInterface: sha512
firewalls:
oauth_token:
pattern: ^/oauth/v2/token
security: false
oauth_authorize:
pattern: ^/oauth/v2/auth
form_login:
provider: fos_userbundle
check_path: /oauth/v2/auth_login_check
login_path: /oauth/v2/auth_login
anonymous: true
api:
pattern: ^/.*
fos_oauth: true
stateless: true
anonymous: false
access_control:
- { path: ^/, methods: [GET], roles: [ IS_AUTHENTICATED_ANONYMOUSLY ]}
- { path: ^/doc, methods: [GET], roles: [ IS_AUTHENTICATED_ANONYMOUSLY ]}
- { path: ^/resque, methods: [GET], roles: [ IS_AUTHENTICATED_ANONYMOUSLY ]}
- { path: /monitor, methods: [GET], roles: [ IS_AUTHENTICATED_ANONYMOUSLY ]}
- { path: /users, methods: [POST], roles: [ IS_AUTHENTICATED_ANONYMOUSLY ]}
- { path: /users/me/registration/confirm, methods: [GET], roles: [ IS_AUTHENTICATED_ANONYMOUSLY ]}
- { path: /users/me/email/confirm, methods: [GET], roles: [ IS_AUTHENTICATED_ANONYMOUSLY ]}
- { path: /instants/.*, methods: [PUT], roles: [IS_AUTHENTICATED_ANONYMOUSLY ]}
- { path: ^/_profiler, roles: [IS_AUTHENTICATED_ANONYMOUSLY]}
- { path: ^/_wdt, roles: [IS_AUTHENTICATED_ANONYMOUSLY]}
- { path: ^/_configurator, roles: [IS_AUTHENTICATED_ANONYMOUSLY]}
- { path: /.*, roles: [ IS_AUTHENTICATED_FULLY ]}
But the routes /resque, /monitor and others are not reachable without access token.
Am I doing something wrong in the configuration? Or is not possible to implement a route whitelist?
you can use exceptions in your api's pattern:
api:
pattern: ^/api(?!/doc)(?!/user/add)(?!/user/availability) # All URLs are protected except api/doc ; api/user/add ; api/user/availability
fos_oauth: true # OAuth2 protected resource
stateless: true # Do no set session cookies
anonymous: false # Anonymous access is not allowed
With this you do not need to describe
access_control:
- ...
I had same problem and I solved it by implementing another firewall. No this road OAuth token wont be checked. I put another regex routes in pattern.
And don't forget to put this firewall in front of your api firewall since you have regex "match it all"
api_anonym_area:
pattern: (^/api/users/forgotten-password/.*)
methods: [POST]
security: false

Resources