-
Notifications
You must be signed in to change notification settings - Fork 114
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
Update token level #942
base: main
Are you sure you want to change the base?
Update token level #942
Conversation
61d8995
to
8af41e5
Compare
* <p>Updates a permission of a token of the specified ID. | ||
*/ | ||
@Patch("/tokens/{appId}/level") | ||
@Consumes("application/json-patch+json") |
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.
json-patch+json
seems not used for this API
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.
Okay, I'll remove the annotation.
Author author, User loginUser) { | ||
return getTokenOrRespondForbidden(ctx, appId, loginUser).thenCompose( | ||
token -> { | ||
if (token.isAdmin()) { |
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.
Should we make this API idempotent instead of changing the behavior depending on the token's status?
Some people may want to retry an update request if the previous request is timed out somehow.
How about taking the desired level in the body?
PATCH /tokens/{appId}/permission
{ "level": "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.
@ikhoon
Oh, i got it.
In this project, in which package should the request body class be placed?
public class TokenLevel {
private String level;
public TokenLevel() {
}
public String getLevel() {
return level;
}
public void setLevel(String level) {
this.level = level;
}
}
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.
We may place this class in the same package of TokenService
.
- Could remove
public
- Rename
TokenLevel
toTokenLevelRequest
for clarity.
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.
Okay, Thanks for your comment. I'll add it.
token -> { | ||
if (token.isAdmin()) { | ||
return mds.updateTokenToUser(author, appId).thenApply( | ||
unused -> mds.findTokenByAppId(appId).join().withoutSecret() |
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.
join()
should not be called for asynchronous code. thenCompose()
could be used instead.
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'll remove the join()
.
8801c98
to
539202f
Compare
539202f
to
e7ee043
Compare
Could you add an e2e test to verify that the request is converted correctly? |
Author author, User loginUser) { | ||
|
||
return getTokenOrRespondForbidden(ctx, appId, loginUser).thenCompose( | ||
token -> { |
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.
Should we return 304 Not Modified
if the token is at the desired level already?
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.
Okay, I'll add
throw HttpStatusException.of(HttpStatus.NOT_MODIFIED);
when the current status and desired one is same.
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.
Looks great so far. 😉
@@ -203,4 +244,52 @@ public void updateToken() { | |||
.isInstanceOf(CompletionException.class) | |||
.hasCauseInstanceOf(IllegalArgumentException.class); | |||
} | |||
|
|||
@Test | |||
public void updateTokenLevel() { |
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.
nit:
public void updateTokenLevel() { | |
void updateTokenLevel() { |
} | ||
|
||
@Test | ||
public void createTokenAndUpdateLevel() throws JsonParseException { |
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.
nit:
public void createTokenAndUpdateLevel() throws JsonParseException { | |
void createTokenAndUpdateLevel() throws JsonParseException { |
class TokenLevelRequest { | ||
private String level; | ||
|
||
TokenLevelRequest() { | ||
} | ||
|
||
TokenLevelRequest(String level) { | ||
this.level = level; | ||
} | ||
|
||
String getLevel() { | ||
return level; | ||
} | ||
|
||
void setLevel(String level) { | ||
this.level = level; | ||
} | ||
} |
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.
Let's use Jackson annotations to make it clear. 😉
class TokenLevelRequest { | |
private String level; | |
TokenLevelRequest() { | |
} | |
TokenLevelRequest(String level) { | |
this.level = level; | |
} | |
String getLevel() { | |
return level; | |
} | |
void setLevel(String level) { | |
this.level = level; | |
} | |
} | |
class TokenLevelRequest { | |
private final String level; | |
@JsonCreator | |
TokenLevelRequest(@JsonProperty("level") String level) { | |
this.level = level; | |
} | |
@JsonProperty | |
String level() { | |
return level; | |
} | |
} |
@@ -192,6 +193,41 @@ public CompletableFuture<Token> updateToken(ServiceRequestContext ctx, | |||
); | |||
} | |||
|
|||
/** | |||
* PATCH /tokens/{appId}/permission |
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.
Should we use permission or level?
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 will change "permission" to "level" in the comment.
return mds.updateTokenToAdmin(author, appId).thenCompose( | ||
unused -> mds.findTokenByAppId(appId).thenApply(Token::withoutSecret)); | ||
default: | ||
throw new IllegalArgumentException("Unexpected token level: " + tokenLevelRequest); |
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 do this before calling getTokenOrRespondForbidden
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.
Before calling getTokenOrRespondForbidden
, i will check the argument.
checkArgument(Arrays.asList("user", "admin").contains(tokenLevelRequest.level().toLowerCase()),
"Unsupported token level: " + tokenLevelRequest.level());
|
||
return getTokenOrRespondForbidden(ctx, appId, loginUser).thenCompose( | ||
token -> { | ||
switch (tokenLevelRequest.getLevel()) { |
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.
What do you think about supporting case-insensitive requests?
switch (tokenLevelRequest.getLevel()) { | |
switch (tokenLevelRequest.getLevel().toLowerCase()) { |
/** | ||
* Update the {@link Token} of the specified {@code appId} to admin. | ||
*/ | ||
public CompletableFuture<Revision> updateTokenToAdmin(Author author, String appId) { |
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 merge these two methods with a boolean parameter. Could you merge them?
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.
Okay, it could be more simple.
1985215
to
1e9ef81
Compare
motivation:
modification:
result: