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
Add role
query parameter to the HTTP interface
#62669
Add role
query parameter to the HTTP interface
#62669
Conversation
This is an automated comment for commit d9fd79e with description of existing statuses. It's updated for the latest CI running ❌ Click here to open a full report in a separate page
Successful checks
|
src/Server/HTTPHandler.cpp
Outdated
if (context->getUser()->granted_roles.isGranted(role_id)) | ||
context->setCurrentRoles(std::vector{role_id}); | ||
else | ||
throw Exception(ErrorCodes::UNKNOWN_ROLE, "Role {} does not exist or not granted to the current user", role_name); |
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.
If the role doesn't exist then getID<Role>()
will throw before this line. So this error message should be probably only about grants.
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.
Yes, you are right; this one probably should be ACCESS_DENIED then.
A question: If we call context->setCurrentRoles
with a non-granted role, it is no-op without a failure; the error message is then not very specific, as it does not set the role, and just skips it. Then, if we are querying a table for which you need a specific grant, the query results in an error without a hint that the role is incorrect, saying that you need a grant instead (a standard one, as if you did not provide the role at all).
Is it intended behavior? That's why I do this isGranted
check here, so the error message is a bit clearer.
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 it should be rather ErrorCodes::SET_NON_GRANTED_ROLE
- see
throw Exception(ErrorCodes::SET_NON_GRANTED_ROLE, "Role should be granted to set default"); |
Sometimes it's ok for Context::setCurrentRoles()
to be no-op for a non-granted role, and sometimes it's not ok.
Probably we could extend Context::setCurrentRoles()
function and add an argument check_roles_are_granted
to control if the function should check if some roles are not granted and throw SET_NON_GRANTED_ROLE
in that case.
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.
Thanks for pointing this out. I pushed a fix to use SET_NON_GRANTED_ROLE
instead.
@vitlibar, thanks for the review!
Edit: the long execution time was resolved after reducing the number of CLICKHOUSE_CLIENT calls. Still not sure what that was. |
src/Server/HTTPHandler.cpp
Outdated
const auto & user = context->getUser(); | ||
for (; role_params_it != params.end(); role_params_it++) | ||
{ | ||
if (role_params_it->first == "role") |
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 move this algorithm extracting multiple values of a parameter to the class of params
.
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.
@vitlibar, this is coming from Poco, namely, Poco::ListMap
, if I am not mistaken; is it OK to add it there? I assume it is since it is included in the CH source code and not as a contrib module.
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 added a new NameValueCollection::getAll
method to extract all the parameters. It might be useful in the future.
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.
Well, I thought about modifying DB::HTMLForm
actually, but probably modifying NameValueCollection
is also ok.
@vitlibar, I addressed the feedback; please have a look when you have time. The test is also simplified. I think there is no need to create the tables because we only want to check if the correct role was assigned. |
@vitlibar, thanks for the review. If the failed test runs are unrelated, shall we merge? |
yes, why not? I've approved your PR. |
@vitlibar, I don't seem to have the merge privileges. Can you please merge it? |
d12608f
Changelog category (leave one):
Changelog entry (a user-readable short description of the changes that goes to CHANGELOG.md):
Added
role
query parameter to the HTTP interface. It works similarly toSET ROLE x
, applying the role before the statement is executed. This allows for overcoming the limitation of the HTTP interface, as multiple statements are not allowed, and it is not possible to send bothSET ROLE x
and the statement itself at the same time. It is possible to set multiple roles that way, e.g.,?role=x&role=y
, which will be an equivalent ofSET ROLE x, y
.Documentation entry for user-facing changes