Skip to content
This repository was archived by the owner on Apr 17, 2023. It is now read-only.

REST API#1299

Merged
mssola merged 1 commit intoSUSE:masterfrom
Vad1mo:api
Aug 14, 2017
Merged

REST API#1299
mssola merged 1 commit intoSUSE:masterfrom
Vad1mo:api

Conversation

@Vad1mo
Copy link
Copy Markdown
Contributor

@Vad1mo Vad1mo commented Jun 9, 2017

REST API for Portus to manage Users and Tokens. Furthermore based on this effort here it is possible to add more APIs to Portus.

PR Content and Features:

  • CRUD Users and their application tokens via a REST PAI
  • Swagger Spec/OpenAPI
  • Documentation

@mssola
Copy link
Copy Markdown
Collaborator

mssola commented Jun 10, 2017

First of all, thanks a lot for this 👍

Now, you may want to take a look at what we are doing here: #1289. There's a lot of stuff on this PR, but take into consideration:

  • The usage of PORTUS-AUTH in app/controllers/application_controller.rb. This is inspired by what Gitlab is doing, and it allows remote clients to make API calls.
  • The app/controllers/tags_controller.rb file now implements the show method, which is the first one providing API support.

Now, this is far from perfect, so I encourage you to innovate upon these ideas. I also thought of using something like grape, but so far I've used good ol' Rails as I'm already used to it (also notice all the ugly as_json methods, that I'd like to get rid off with a proper serializer or other solution...).

@Vad1mo
Copy link
Copy Markdown
Contributor Author

Vad1mo commented Jun 10, 2017

I saw some of the work in the branch. We will take PORTUS-AUTH into consideration. @mssola when do you plan to merge #1289 into master?
I like the grape approach. We also see this as an viable option and thinking about using it.

@Vad1mo
Copy link
Copy Markdown
Contributor Author

Vad1mo commented Jun 10, 2017

It would be nice if someone could review the API Docs f1999b7 It would be nice if @mssola or someone else would take some time to review the API concept.

@mssola
Copy link
Copy Markdown
Collaborator

mssola commented Jun 12, 2017

I saw some of the work in the branch. We will take PORTUS-AUTH into consideration. @mssola when do you plan to merge #1289 into master?

Both me and @vitoravelino have been busy with other stuff, and it will probably take a while, since we have to review the code, and apply more testing... I'd say I can break away the code for managing PORTUS-AUTH in another PR, so you can use it.

I like the grape approach. We also see this as an viable option and thinking about using it.

I have to admit that I've never used it, so this is something I'm not really sure. It needs some exploration from my part 😄

It would be nice if someone could review the API Docs f1999b7 It would be nice if @mssola or someone else would take some time to review the API concept.

Left some comments. In principle it looks good to me 👍

@mssola
Copy link
Copy Markdown
Collaborator

mssola commented Jun 21, 2017

@Vad1mo ping me whenever this is ready to be reviewed.

@Vad1mo
Copy link
Copy Markdown
Contributor Author

Vad1mo commented Jun 21, 2017

@mssola we are fixing the travis build and adding some documentation next to the swagger spec. The code is basically ready for an review.

fyi: you can get the swagger spec localhost:3000/api/swagger_doc

@mssola
Copy link
Copy Markdown
Collaborator

mssola commented Jun 21, 2017

@Vad1mo ok, I'll wait also for the swagger documentation if you don't mind 😉

@andrew2net
Copy link
Copy Markdown

@mssola Hello,
I'm trying to pass travis. Running command, which got an error on travis:

bundle exec rspec spec packaging/suse/portusctl/spec

got

...
rpc error: code = 2 desc = oci runtime error: exec failed: container_linux.go:247: starting container process caused "exec: \"mysqladmin\": executable file not found in $PATH"

Command 'mysqladmin --count=1 --connect-timeout=1 --host=integration_db -u root --password=portus ping' failed! Waiting 5 seconds...
...

can you help me find cause?

@mssola
Copy link
Copy Markdown
Collaborator

mssola commented Jun 22, 2017

@andrew2net have you tried without running the integration tests ? (they might be broken...):

$ bundle exec rspec spec packaging/suse/portusctl/spec --tag ~integration

@andrew2net
Copy link
Copy Markdown

@mssola I haven't. traied now and all tests passed. Does it need to pass integration tests for successfull travis checkung?

@mssola
Copy link
Copy Markdown
Collaborator

mssola commented Jun 22, 2017

@andrew2net no. Travis does not run integration tests for Portus.

@Vad1mo
Copy link
Copy Markdown
Contributor Author

Vad1mo commented Jun 22, 2017

@mssola you can take a look now at the PR

Copy link
Copy Markdown
Collaborator

@mssola mssola left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Left some comments. Thanks a lot for all your hard work 👏

Comment thread .gitignore Outdated
/spec/integration/fixtures/data
/node_modules No newline at end of file
/node_modules
.idea
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove this line

Comment thread .rubocop.yml
Enabled: false

Style/FrozenStringLiteralComment:
Enabled: false
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This wasn't an issue before 😕 If you call it with bundle exec there shouldn't be any problem no ?

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@mssola with ruby 2.3 rubocop reports offense Missing frozen string literal comment. on each rb file

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Gotcha

Comment thread .ruby-version
@@ -1 +1 @@
2.1.2
2.3.3
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unrelated to this PR.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

well, grape requires to go to minimum 2.3.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll have to check about this requirement...

Comment thread .travis.yml Outdated

# Stable versions
- 2.1.10
- 2.2.6
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The changes on this file are unrelated to this PR. Moreover, why should we stop testing these versions ? (maybe we could upgrade the 2.2.6 to 2.2.7)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ruby 2.3 is required

Comment thread Gemfile
gem "grape-swagger"
gem "grape-swagger-entity"
gem "grape-swagger-representable"
gem "hashie-forbidden_attributes"
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure about this gem... Do you really need mass assignment ?

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@@ -0,0 +1,20 @@
class VulnerabilitiesController < ApplicationController
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is from another PR. Please, don't include it...

Comment thread app/api/grape_api/user_api.rb Outdated
@@ -0,0 +1,191 @@
module GrapeAPI
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Two things:

  • There's functionality already existing in app/controllers/application_tokens_controller.rb for this. Could we merge the code somehow ? (either changes the frontend to use this API instead of the controller, thus removing the controller, or creating methods that both the controller and the API use)
  • Could you add more documentation ?

Copy link
Copy Markdown

@andrew2net andrew2net Jun 23, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@mssola the functionality slightly different. API can create tokens for any user, not only for current, and returns plain_token. I think changing the frontend to use the API is preferred.
Will add more doc.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The functionality is moved to model.

Comment thread app/api/grape_api/root_api.rb Outdated
end

class RootAPI < Grape::API
# version 'v1', using: :path
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why not? 😀

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

indeed 😄

Comment thread app/api/grape_api/root_api.rb Outdated
error!("Authorization fails.", 403) unless user.admin
end

def current_user
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This already exists in the application_controller.rb. We should be using the same code and share it somehow.

Copy link
Copy Markdown

@andrew2net andrew2net Jun 23, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Moved it to concern auth_from_token.

Comment thread app/api/grape_api/root_api.rb Outdated
title: "Portus user API",
description: "CRUD users and user's application tokens API",
contact_name: "Anldrei Kislichenko",
contact_email: "andrei.kislichenko@gmail.com"
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd prefer:

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@mssola ok, I don't mind 😄

@mssola
Copy link
Copy Markdown
Collaborator

mssola commented Jul 18, 2017

Note that we have just merged #1289, and so there are quite some conflicts now. Also, make sure to rebase against master.

@Vad1mo Vad1mo changed the title WIP: REST API REST API Jul 19, 2017
@Vad1mo
Copy link
Copy Markdown
Contributor Author

Vad1mo commented Jul 20, 2017

@mssola IMHO, we are ready now, for the review.

@mssola mssola added this to the Release 2.3 milestone Aug 2, 2017
Copy link
Copy Markdown
Collaborator

@mssola mssola left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In general it looks good to me. Just fix my comments 😉 I still have to test it locally more deeply though ...

username, password = auth.split(":")
user = User.find_by(username: username)
if user && user.application_token_valid?(password)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove this empty line. Maybe you could add this empty line before the if statement actually.

@@ -0,0 +1,16 @@
module AuthFromToken
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please, add documentation

module AuthFromToken
extend ActiveSupport::Concern

def authenticate_user_from_authentication_token!
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add documentation please 😉

Comment thread lib/api/root_api.rb Outdated
expose :id, documentation: { type: Integer, desc: "User id" }
expose :username, documentation: { type: String, desc: "User name" }
expose :email, documentation: { type: String, desc: "E-mail" }
expose :sign_in_count, documentation: { type: Integer }
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this really needed ?

Copy link
Copy Markdown
Contributor Author

@Vad1mo Vad1mo Aug 4, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sign_in_count we can skip. The others we would like to keep. We want to use the API to perform CRUD operations on the on the user, so we can decide what users to create and maybe remove users automatically that don't use their account. However the last use case is no yet relevant for us right now.

Comment thread lib/api/root_api.rb Outdated
expose :sign_in_count, documentation: { type: Integer }
expose :current_sign_in_at, documentation: { type: DateTime }
expose :last_sign_in_at, documentation: { type: DateTime }
expose :current_sign_in_ip, :last_sign_in_ip
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure about these two, since it's not that useful imho

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok, not really relevant.

Comment thread lib/api/v1/user_api.rb Outdated

route_param :id, type: Integer do
resource :application_tokens do

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove empty line

Comment thread lib/api/v1/user_api.rb

params do
requires :application, documentation: { desc: "Application name" }
end
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add an empty line after the end line.

Comment thread lib/api/v1/user_api.rb

params do
requires :id, documentation: { desc: "Token id" }
end
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here

Comment thread lib/api/v1/user_api.rb
only: [:display_name],
using: API::Entities::Users.documentation.slice(:display_name)
end
end
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here

Comment thread lib/api/v1/user_api.rb
only: [:display_name],
using: API::Entities::Users.documentation.slice(:display_name)
end
end
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same

Copy link
Copy Markdown
Collaborator

@mssola mssola left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some comments after using it:

There should be a way to return a 404 when the path does not exist. For example I typed /api/users, and I got an HTML page, instead of simply a not found error. Maybe in production this is already handled?

Besides this, when I performed:

curl -X DELETE \
     -H "PORTUS-AUTH: mssola:KXsgWZQyDq8rMoy-hHaD" \
    https://registry.mssola.cat/api/v1/users/2/application_tokens/2

I got:

{
  "error": "Internal server error: Grape::Exceptions::MethodNotAllowed"
}

Overall really nice work. Thanks a lot for your patience 👏

Comment thread lib/api/root_api.rb Outdated
},
security: [api_key: []],
info: {
title: "Portus user API",
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Argh, overlooked this, sorry ... It should be "Portus API" instead since we will extend it to other endpoints as well...

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok

Comment thread lib/api/root_api.rb Outdated
security: [api_key: []],
info: {
title: "Portus user API",
description: "CRUD users and user's application tokens API",
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here. It should be something like this: "Portus CRUD API" (or better 😅 )

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok

Comment thread lib/api/v1/users.rb Outdated
[401, "Authentication fails."],
[403, "Authorization fails."]
],
consumes: ["application/x-www-form-urlencoded"]
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe this can be done in another PR, but would it be too difficult to also support JSON ? It would be simpler than with an encoded form. See the curl command I had to use:

curl -X POST \
     -H "PORTUS-AUTH: mssola:KXsgWZQyDq8rMoy-hHaD" \
     -F "user[username]=another" -F "user[email]=asd@example.org" -F "user[password]=12341234" \
     https://registry.mssola.cat/api/v1/users

Maybe this could work too (so without the user[...] part):

curl -X POST \
     -H "PORTUS-AUTH: mssola:KXsgWZQyDq8rMoy-hHaD" \
     https://registry.mssola.cat/api/v1/users?username=another&email=asd@example.org&password=12341234

Copy link
Copy Markdown

@andrew2net andrew2net Aug 8, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will add JSON

curl -X POST "http://localhost:3005/api/v1/users" \
     -H "accept: application/json" \
     -H "Content-Type: application/json" \
     -H "Portus-Auth: andrei:xzgZj6toUiuM2h49zA7z" \
     -d '{"user":{"username":"another","email":"asd@example.org","password":"12341234"}}'

Comment thread lib/api/v1/users.rb Outdated
[403, "Authorization fails."],
[404, "Not found."]
],
consumes: ["application/x-www-form-urlencoded"]
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok

@andrew2net
Copy link
Copy Markdown

andrew2net commented Aug 8, 2017

@mssola API with GRAPE processes requests if the path matches any of endpoints. If not then the request is ignored by GRAPE and the app processes it and returns No route matches error in development as HTML if route not exists.
Will add interception of Grape::Exceptions::MethodNotAllowed error.

Copy link
Copy Markdown
Collaborator

@mssola mssola left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If I submit a malformed JSON (create user), I receive and HTML. It should instead return a proper error response (in this case this is a 400 Bad Request).

We are getting really close, nice work!

Comment thread spec/api/grape_api/v1/users_spec.rb Outdated
expect(JSON.parse(response.body)["errors"]).not_to be_nil
end

it "returs user error" do
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Typo: "returs" -> "returns"

mssola
mssola previously approved these changes Aug 11, 2017
Copy link
Copy Markdown
Collaborator

@mssola mssola left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

Rebase all this to the master branch, and squash commits into a set of commits (or a single commit even)

Again, thanks a lot for all this. You rock 👏

Signed-off-by: Vadim Bauer <bauer.vadim@gmail.com>
Copy link
Copy Markdown
Collaborator

@mssola mssola left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM 👏

@mssola mssola merged commit 586636b into SUSE:master Aug 14, 2017
@Vad1mo Vad1mo deleted the api branch February 6, 2018 21:53
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants