-
Notifications
You must be signed in to change notification settings - Fork 339
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
Authorization model #544
Authorization model #544
Conversation
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.
Some more comments for you. thanks!
|
||
| | ||
|
||
**GET /api/1.2/api_capabilities/capability/: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.
usually when filtering a result set, query params are used instead of route params. i.e. GET /api/1.2/api_capabilities?capName=ds-read
that way you don't have to create 2 routes and 2 documentation snippets, etc:
GET /api/1.2/api_capabilities
GET /api/1.2/api_capabilities/capability/:name
^^ no need for 2 routes. only this one is required:
GET /api/1.2/api_capabilities
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.
Fixed, thanks
+-------------------+--------+--------------------------------------------------+ | ||
| Parameter | Type | Description | | ||
+===================+========+==================================================+ | ||
| ``httpMethod`` | enum | One of: 'GET', 'POST', 'PUT', 'PATCH', 'DELETE'. | |
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 you want your documentation to be perfect :) you could add a column for "required" with yes | no
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.
Done
**Request Route Parameters** | ||
|
||
+-------------------+----------+------------------------------------------------+ | ||
| Name | Type | Description | |
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 you meant this column header to say "Required" and not type
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.
Fixed, thanks
+-----------------+----------+------------------------------------------------+ | ||
| Name | Required | Description | | ||
+=================+==========+================================================+ | ||
| ``id`` | yes | Mapping 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.
make sure you get these pipes in the right place or the docs won't build.
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.
Done
**Request Parameters** | ||
|
||
+-------------------+--------+-------------------------------------------------+ | ||
| Parameter | Type | Description | |
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 you add a required column here too?
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.
Done
my $name = $self->param('name'); | ||
|
||
my $rs_data = $self->db->resultset("Capability")->search( 'me.name' => $name ); | ||
my @data = (); |
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.
you might want to do this
if ( !defined($rs_data) ) { return $self->not_found(); }
so they get back a 404 instead of an empty result set if id is invalid
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.
Done
my $description = $params->{description} if defined( $params->{description} ); | ||
|
||
my $capability = $self->db->resultset('Capability')->find( { name => $name } ); | ||
if ( !defined($capability) or $capability eq "" ) { |
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'm not sure this is needed:
or $capability eq ""
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.
Right, done.
$r->put("/api/$version/api_capabilities/:id")->over( authenticated => 1 )->to( 'ApiCapability#update', namespace => $namespace ); | ||
$r->post("/api/$version/api_capabilities")->over( authenticated => 1 )->to( 'ApiCapability#create', namespace => $namespace ); | ||
$r->delete("/api/$version/api_capabilities/:id")->over( authenticated => 1 )->to( 'ApiCapability#delete', namespace => $namespace ); | ||
|
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.
do you plan to create apis for associating capabilities with roles?
my $dbh = Schema->database_handle; | ||
my $t = Test::Mojo->new('TrafficOps'); | ||
|
||
my $false = 0; |
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 don't see where you are using these variables. plus, per our resident perl expert, @dangogh, this is not a good idea.
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.
Removed, thanks.
my $dbh = Schema->database_handle; | ||
my $t = Test::Mojo->new('TrafficOps'); | ||
|
||
my $false = 0; |
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.
again, i don't think you need these.
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.
Right. 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.
and a few more comments...
traffic_ops/app/db/seeds.sql
Outdated
@@ -81,10 +81,260 @@ insert into role (name, description, priv_level) values ('steering', 'Role for S | |||
insert into role (name, description, priv_level) values ('read-only user', 'Read-Only user', 10) ON CONFLICT (name) DO NOTHING; | |||
insert into role (name, description, priv_level) values ('portal', 'Portal User', 2) ON CONFLICT (name) DO NOTHING; | |||
insert into role (name, description, priv_level) values ('disallowed', 'Block all access', 0) ON CONFLICT (name) DO NOTHING; | |||
insert into role (name, description, priv_level) values ('root', 'Role for full capabilities - super-user ', 30) ON CONFLICT DO NOTHING; |
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 still don't think this is needed as we already have the "admin" user which has always been the "super user".
traffic_ops/app/db/seeds.sql
Outdated
insert into capability (name, description) values ('user-write', 'Create, edit or delete user configuration') ON CONFLICT (name) DO NOTHING; | ||
|
||
-- roles_capabilities | ||
insert into role_capability (role_id, cap_name) values ((select id from role where name='root'), 'all-read') ON CONFLICT (role_id, cap_name) DO NOTHING; |
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.
again, unless you really feel strongly about creating a 2nd "super user" called root (in addition to admin), i'd change this to
insert into role_capability (role_id, cap_name) values ((select id from role where name='admin'), 'all-read') ON CONFLICT (role_id, cap_name) DO NOTHING;
insert into role_capability (role_id, cap_name) values ((select id from role where name='admin'), 'all-write') ON CONFLICT (role_id, cap_name) DO NOTHING;
I think having 2 super users will only create unnecessary confusion.
traffic_ops/app/db/seeds.sql
Outdated
insert into role_capability (role_id, cap_name) values ((select id from role where name='root'), 'all-write') ON CONFLICT (role_id, cap_name) DO NOTHING; | ||
|
||
-- api_capabilities | ||
insert into api_capability (http_method, route, capability) values ('GET', '/', 'all-read') ON CONFLICT (http_method, route, capability) DO NOTHING; |
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 feel like these should be /api as this authorization model is used by the api gateway and therefore only applicable to /api. However, I understand that there are a few that start with /internal but my understanding is that those that start with /internal should NOT be exposed thru the api.
insert into api_capability (http_method, route, capability) values ('PUT', '/api/*/asns/*', 'asn-write') ON CONFLICT (http_method, route, capability) DO NOTHING; -- 7 | ||
insert into api_capability (http_method, route, capability) values ('DELETE', '/api/*/asns/*', 'asn-write') ON CONFLICT (http_method, route, capability) DO NOTHING; -- 8 | ||
insert into api_capability (http_method, route, capability) values ('GET', '/api/*/cache_stats', 'cache-stats-read') ON CONFLICT (http_method, route, capability) DO NOTHING; -- 11 | ||
insert into api_capability (http_method, route, capability) values ('GET', '/internal/api/*/daily_summary', 'cache-stats-read') ON CONFLICT (http_method, route, capability) DO NOTHING; -- 12 |
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 would take out the /internal ones
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 should probably bring this up in an email to the dev list. I'm not 100% familiar with the behavior of the api gateway but I assumed because of its name it handles /api requests. For example, if a request came in to traffic-ops.domain.com/foo.jpg then foo.jpg would be served and the api gateway would not be concerned. however, if a call to traffic-ops.domain.com/api/whatever came in that request would go thru the api gateway where roles/capabilites would be checked for the route. Therefore, this would mean the /internal ones would not go thru the api gateway.
So, my advice would be to duplicate the "authenticated" /internal routes in TrafficOpsRoutes.pm and add those to your seeds file. for example, in trafficopsroutes.pm you'll find this:
$r->get("/internal/api/$version/steering")->over( authenticated => 1 )->to( 'Steering#index', namespace => 'API::DeliveryService' );
I would create a clone like this in trafficopsroutes.pm:
$r->get("/api/$version/steering")->over( authenticated => 1 )->to( 'Steering#index', namespace => 'API::DeliveryService' );
^^ and that is the one I'd add to your seeds file.
I think I created an email a little while ago to address /internal routes. I can see if I can get that email thread started again.
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.
Since the first implementation of the API gateway reads the mapping from a file, and not from the DB table, I tend to either leave it as is, or remove everything from this table, for now, until the discussion yields some conclusions. What do you say?
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, let's leave the /internal ones in as I have not been able to get any conclusions on the matter.
insert into api_capability (http_method, route, capability) values ('DELETE', '/api/*/types/*', 'type-write') ON CONFLICT (http_method, route, capability) DO NOTHING; -- 283 | ||
insert into api_capability (http_method, route, capability) values ('GET', '/api/*/users', 'user-read') ON CONFLICT (http_method, route, capability) DO NOTHING; -- 289 | ||
insert into api_capability (http_method, route, capability) values ('GET', '/api/*/users/*', 'user-read') ON CONFLICT (http_method, route, capability) DO NOTHING; -- 290 | ||
insert into api_capability (http_method, route, capability) values ('PUT', '/api/*/users/*', 'user-write') ON CONFLICT (http_method, route, capability) DO NOTHING; -- 292 |
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.
you might want to do a quick check against the TrafficOpsRoutes.pm file to make sure you got everything. I'm sure some new routes have been added since the PR was first submitted.
Also, what about the new routes you created in this PR. are they in this seeds 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.
Same here. Will give it another look once we decide about the way this data is used by the API gateway.
I'm ready to merge this PR however it says "This branch cannot be rebased safely". To be honest I'm not really sure what that means but it doesn't sound great. So here's what I'd suggest:
if all goes smoothly:
if all doesn't go smoothly:
of course if that doesn't work you can always do: git rebase --abort and we'll sync up and see what the issue is... |
Adding tables: capability (list of available capabilities), api_capability mapping, role_capability mapping & user_role. Seeding capability & api_capability tables. Also seeding root role. (cherry picked from commit 4879a2c)
(cherry picked from commit db31205)
(cherry picked from commit 78f2f84)
(cherry picked from commit d79f76c)
(cherry picked from commit 0dcee94)
Added "capability" as a query parameter to the api_capabilities API as a filter, and removed the dedicated API Updated the documentation and UT accordingly.
perltidy
8914d63
to
f04b4db
Compare
Branch rebased, PR updated. I believe it can be merged now. |
A new PR instead of #435 with fixes according to comments by @mitchell852