From 3a058339be1ee67a9c03e2628d9d9c4097cc0b8a Mon Sep 17 00:00:00 2001
From: Konstantin Haase <konstantin.mailinglists@googlemail.com>
Date: Tue, 24 Mar 2015 17:25:57 +0100
Subject: [PATCH] v3: add /user and /user/:id

---
 lib/travis/api/v3/access_control/generic.rb   |  4 ++++
 lib/travis/api/v3/renderer.rb                 |  4 +++-
 lib/travis/api/v3/routes.rb                   |  6 +++++
 lib/travis/api/v3/services.rb                 |  1 +
 .../api/v3/services/organization/sync.rb      |  0
 lib/travis/api/v3/services/user/current.rb    |  8 +++++++
 lib/travis/api/v3/services/user/find.rb       |  7 ++++++
 spec/v3/service_index_spec.rb                 | 14 ++++++++++-
 spec/v3/services/user/current_spec.rb         | 23 +++++++++++++++++++
 spec/v3/services/user/find_spec.rb            | 23 +++++++++++++++++++
 10 files changed, 88 insertions(+), 2 deletions(-)
 create mode 100644 lib/travis/api/v3/services/organization/sync.rb
 create mode 100644 lib/travis/api/v3/services/user/current.rb
 create mode 100644 lib/travis/api/v3/services/user/find.rb
 create mode 100644 spec/v3/services/user/current_spec.rb
 create mode 100644 spec/v3/services/user/find_spec.rb

diff --git a/lib/travis/api/v3/access_control/generic.rb b/lib/travis/api/v3/access_control/generic.rb
index 0253c18b..8220d653 100644
--- a/lib/travis/api/v3/access_control/generic.rb
+++ b/lib/travis/api/v3/access_control/generic.rb
@@ -44,6 +44,10 @@ module Travis::API::V3
       unrestricted_api?
     end
 
+    def user_visible?(user)
+      unrestricted_api?
+    end
+
     def repository_visible?(repository)
       return true if unrestricted_api? and not repository.private?
       private_repository_visible?(repository)
diff --git a/lib/travis/api/v3/renderer.rb b/lib/travis/api/v3/renderer.rb
index ab21513f..a2c2b1c5 100644
--- a/lib/travis/api/v3/renderer.rb
+++ b/lib/travis/api/v3/renderer.rb
@@ -18,7 +18,9 @@ module Travis::API::V3
 
       expander      = EXPANDER_CACHE[[type, script_name, args.keys]] ||= begin
         resource    = Routes.resources.detect { |r| r.identifier == type }
-        route       = resource.route if resource
+        verb, sub   = resource.services.key(:find)                         if resource
+        route       = resource.route                                       if verb
+        route      += sub                                                  if sub
         route     &&= Mustermann.new(script_name, type: :identity) + route if script_name and not script_name.empty?
         key_mapping = {}
         args.keys.each do |key|
diff --git a/lib/travis/api/v3/routes.rb b/lib/travis/api/v3/routes.rb
index 80e6a214..ebc26022 100644
--- a/lib/travis/api/v3/routes.rb
+++ b/lib/travis/api/v3/routes.rb
@@ -32,6 +32,12 @@ module Travis::API::V3
       get :find
     end
 
+    resource :user do
+      route '/user'
+      get :current
+      get :find, '/{user.id}'
+    end
+
     resource :organization do
       route '/org/{organization.id}'
       get :find
diff --git a/lib/travis/api/v3/services.rb b/lib/travis/api/v3/services.rb
index e5180864..45d35477 100644
--- a/lib/travis/api/v3/services.rb
+++ b/lib/travis/api/v3/services.rb
@@ -9,6 +9,7 @@ module Travis::API::V3
     Repositories  = Module.new { extend Services }
     Repository    = Module.new { extend Services }
     Requests      = Module.new { extend Services }
+    User          = Module.new { extend Services }
 
     def result_type
       @resul_type ||= name[/[^:]+$/].underscore.to_sym
diff --git a/lib/travis/api/v3/services/organization/sync.rb b/lib/travis/api/v3/services/organization/sync.rb
new file mode 100644
index 00000000..e69de29b
diff --git a/lib/travis/api/v3/services/user/current.rb b/lib/travis/api/v3/services/user/current.rb
new file mode 100644
index 00000000..8a513384
--- /dev/null
+++ b/lib/travis/api/v3/services/user/current.rb
@@ -0,0 +1,8 @@
+module Travis::API::V3
+  class Services::User::Current < Service
+    def run!
+      raise LoginRequired unless access_control.logged_in?
+      access_control.user || not_found(false)
+    end
+  end
+end
diff --git a/lib/travis/api/v3/services/user/find.rb b/lib/travis/api/v3/services/user/find.rb
new file mode 100644
index 00000000..ec86b46f
--- /dev/null
+++ b/lib/travis/api/v3/services/user/find.rb
@@ -0,0 +1,7 @@
+module Travis::API::V3
+  class Services::User::Find < Service
+    def run!
+      find
+    end
+  end
+end
diff --git a/spec/v3/service_index_spec.rb b/spec/v3/service_index_spec.rb
index 24949690..79b9419b 100644
--- a/spec/v3/service_index_spec.rb
+++ b/spec/v3/service_index_spec.rb
@@ -93,7 +93,19 @@ describe Travis::API::V3::ServiceIndex do
             [{"@type"=>"template",
               "request_method"=>"GET",
               "uri_template"=>"#{path}orgs"}]},
-         "attributes"=>["organizations"]}}
+         "attributes"=>["organizations"]},
+       "user"=>
+        {"@type"=>"resource",
+         "actions"=>
+          {"current"=>
+            [{"@type"=>"template",
+              "request_method"=>"GET",
+              "uri_template"=>"#{path}user"}],
+           "find"=>
+            [{"@type"=>"template",
+              "request_method"=>"GET",
+              "uri_template"=>"#{path}user/{user.id}"}]},
+         "attributes"=>["id", "login", "name", "github_id", "is_syncing", "synced_at"]}}
     }
 
     describe 'with /v3 prefix' do
diff --git a/spec/v3/services/user/current_spec.rb b/spec/v3/services/user/current_spec.rb
new file mode 100644
index 00000000..e96ef24d
--- /dev/null
+++ b/spec/v3/services/user/current_spec.rb
@@ -0,0 +1,23 @@
+require 'spec_helper'
+
+describe Travis::API::V3::Services::User::Current do
+  let(:user) { User.find_by_login('svenfuchs') }
+
+  let(:token)   { Travis::Api::App::AccessToken.create(user: user, app_id: 1) }
+  let(:headers) {{ 'HTTP_AUTHORIZATION' => "token #{token}"                  }}
+
+  describe "authenticated as user with access" do
+    before  { get("/v3/user", {}, headers)     }
+    example { expect(last_response).to be_ok   }
+    example { expect(JSON.load(body)).to be == {
+      "@type"      => "user",
+      "@href"      => "/v3/user/#{user.id}",
+      "id"         => user.id,
+      "login"      => "svenfuchs",
+      "name"       =>"Sven Fuchs",
+      "github_id"  => user.github_id,
+      "is_syncing" => user.is_syncing,
+      "synced_at"  => user.synced_at
+    }}
+  end
+end
\ No newline at end of file
diff --git a/spec/v3/services/user/find_spec.rb b/spec/v3/services/user/find_spec.rb
new file mode 100644
index 00000000..cf68fe63
--- /dev/null
+++ b/spec/v3/services/user/find_spec.rb
@@ -0,0 +1,23 @@
+require 'spec_helper'
+
+describe Travis::API::V3::Services::User::Find do
+  let(:user) { User.find_by_login('svenfuchs') }
+
+  let(:token)   { Travis::Api::App::AccessToken.create(user: user, app_id: 1) }
+  let(:headers) {{ 'HTTP_AUTHORIZATION' => "token #{token}"                  }}
+
+  describe "authenticated as user with access" do
+    before  { get("/v3/user/#{user.id}", {}, headers) }
+    example { expect(last_response).to be_ok          }
+    example { expect(JSON.load(body)).to be ==        {
+      "@type"      => "user",
+      "@href"      => "/v3/user/#{user.id}",
+      "id"         => user.id,
+      "login"      => "svenfuchs",
+      "name"       =>"Sven Fuchs",
+      "github_id"  => user.github_id,
+      "is_syncing" => user.is_syncing,
+      "synced_at"  => user.synced_at
+    }}
+  end
+end
\ No newline at end of file