-
Notifications
You must be signed in to change notification settings - Fork 208
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: add authorization to user/order route #231
Conversation
async createOrder( | ||
@param.path.string('userId') userId: string, | ||
@requestBody() order: Order, | ||
): Promise<Order> { | ||
// should be moved to an authorizor | ||
if (userId !== order.userId) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
or use voter to decide.
a4f9c7e
to
1d6cce9
Compare
7f27197
to
1bfb2ac
Compare
45d113e
to
53604a9
Compare
packages/shopping/package.json
Outdated
"pretest:ci": "npm run build", | ||
"pretest": "npm run clean && npm run build && npm run docker:start", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please remove && npm run docker:start
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
agreed
packages/shopping/package.json
Outdated
"bcryptjs": "2.4.3", | ||
"casbin": "^3.0.3", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please remove ^
from all versions.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
agreed
} | ||
|
||
async authorize( | ||
// @jannyHou: make sure it's universal for authorizers |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is it a reminder for something? Either way, I think it's the best to remove the @jannyHou
. :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good catch...I think it's some notes from meeting, should be removed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
agreed, removing note
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍 Great progress! Mostly good, I left a few comments.
@@ -35,8 +42,11 @@ describe('UserOrderController acceptance tests', () => { | |||
const userId = user.id; | |||
const order = givenAOrder({userId: userId, orderId: '1'}); | |||
|
|||
const token = await authenticateUser(user); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we can just generate the token once, then use it in all the it
tests.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
actually every test iteration calls givenAUser() to create a new user for every test. so a token has to be created every time for the new user.
__dirname, | ||
'../../fixtures/casbin/rbac_policy.csv', | ||
); | ||
return casbin.newEnforcer(conf, policy); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
good catch, and we can turn createEnforcer
into a sync function since casbin.newEnforcer()
is sync.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
casbin.newEnforcer returns a promise, so to resolve it createEnforcer has to be async. The reason I removed the await is because of lint errors and await is added in a return from an async function internally.
@@ -54,7 +58,7 @@ export class JWTService implements TokenService { | |||
); | |||
} | |||
const userInfoForToken = { | |||
id: userProfile[securityId], | |||
id: userProfile.id, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it should still be userProfile[securityId]
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
userProfile.id and userProfile[securityId] have same values.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
depends on what is returned by user service
convertToUserProfile(user: User): UserProfile {
// since first name and lastName are optional, no error is thrown if not provided
let userName = '';
if (user.firstName) userName = `${user.firstName}`;
if (user.lastName)
userName = user.firstName
? `${userName} ${user.lastName}`
: `${user.lastName}`;
return {[securityId]: user.id, name: userName, id: user.id};
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
true in this case theoretically [securityId]
always equals to id
, but conceptually we should retrieve the value from a user profile's unique field, which is [securityId]
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok, I will correct this.
2432c69
to
33451b1
Compare
33451b1
to
7a8cfce
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@deepakrkris almost there, a few more comments.
@@ -82,6 +91,8 @@ export class UserOrderController { | |||
}, | |||
}, | |||
}) | |||
@authenticate('jwt') | |||
@authorize({resource: 'order', scopes: ['patch']}) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ditto
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
agreed
@@ -66,6 +73,8 @@ export class UserOrderController { | |||
}, | |||
}, | |||
}) | |||
@authenticate('jwt') | |||
@authorize({resource: 'order', scopes: ['find']}) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can we also add voters: [compareId]
for patch and find methods?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
agreed
@@ -54,7 +58,7 @@ export class JWTService implements TokenService { | |||
); | |||
} | |||
const userInfoForToken = { | |||
id: userProfile[securityId], | |||
id: userProfile.id, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
true in this case theoretically [securityId]
always equals to id
, but conceptually we should retrieve the value from a user profile's unique field, which is [securityId]
0a27666
to
f1136b7
Compare
packages/shopping/package.json
Outdated
"@loopback/repository": "1.10.1", | ||
"@loopback/rest": "1.16.6", | ||
"@loopback/rest-explorer": "1.3.1", | ||
"@loopback/security": "^0.1.6", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please remove all leading ^
for version ranges.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@deepakrkris ^ +1 and please also resolve the conflicts for 2 package-lock.json files. LGTM after cleaning up the package.json file
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
agreed
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@deepakrkris LGTM after cleaning up the package.json, package-lock.json files. Thank you!
packages/shopping/package.json
Outdated
"@loopback/repository": "1.10.1", | ||
"@loopback/rest": "1.16.6", | ||
"@loopback/rest-explorer": "1.3.1", | ||
"@loopback/security": "^0.1.6", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@deepakrkris ^ +1 and please also resolve the conflicts for 2 package-lock.json files. LGTM after cleaning up the package.json file
f1136b7
to
0c12c45
Compare
Signed-off-by: DEEPAK RAJAMOHAN <[email protected]>
Signed-off-by: DEEPAK RAJAMOHAN <[email protected]>
Signed-off-by: DEEPAK RAJAMOHAN <[email protected]>
Signed-off-by: DEEPAK RAJAMOHAN <[email protected]>
Signed-off-by: DEEPAK RAJAMOHAN <[email protected]>
0c12c45
to
e3846bd
Compare
issue: loopbackio/loopback-next#3695
implements loopback features in loopbackio/loopback-next#1205 and loopbackio/loopback-next#2900
The PR serves as a PoC and feature to verify implementation of @loopback/authorization in the shopping app.
items:
authentication
,authorization
,authorizeInterceptor
,authorizor
,fixtures(casbin)
authentication
andauthorization
Users/{userId}/orders
with casbin policies , connect with loopback feature Refactor authorization loopback-next#3529To be improved: casbin policies set fixed roles instead of checking theSolved by adding a voter.order
's ownId on the fly.