[ARVADOS] created: b588c254853ab654a685669c36b21e05154b6571

git at public.curoverse.com git at public.curoverse.com
Thu Dec 26 17:28:42 EST 2013


        at  b588c254853ab654a685669c36b21e05154b6571 (commit)


commit b588c254853ab654a685669c36b21e05154b6571
Author: Tom Clegg <tom at clinicalfuture.com>
Date:   Thu Dec 26 14:28:07 2013 -0800

    Allow self-activation after signing required user agreements.

diff --git a/services/api/app/controllers/application_controller.rb b/services/api/app/controllers/application_controller.rb
index 434b095..de0c50c 100644
--- a/services/api/app/controllers/application_controller.rb
+++ b/services/api/app/controllers/application_controller.rb
@@ -328,7 +328,7 @@ class ApplicationController < ActionController::Base
 
   def render_list
     @object_list = {
-      :kind  => "arvados##{resource_name}List",
+      :kind  => "arvados##{(@response_resource_name || resource_name).camelize(:lower)}List",
       :etag => "",
       :self_link => "",
       :next_page_token => "",
diff --git a/services/api/app/controllers/arvados/v1/user_agreements_controller.rb b/services/api/app/controllers/arvados/v1/user_agreements_controller.rb
new file mode 100644
index 0000000..ac74f3d
--- /dev/null
+++ b/services/api/app/controllers/arvados/v1/user_agreements_controller.rb
@@ -0,0 +1,74 @@
+class Arvados::V1::UserAgreementsController < ApplicationController
+  before_filter :admin_required, except: [:index, :sign, :signatures]
+
+  def model_class
+    Link
+  end
+
+  def index
+    current_user_uuid = current_user.uuid
+    act_as_system_user do
+      uuids = Link.where(owner_uuid: system_user_uuid,
+                         link_class: 'signature',
+                         name: 'require',
+                         tail_kind: 'arvados#user',
+                         tail_uuid: system_user_uuid,
+                         head_kind: 'arvados#collection').
+        collect &:head_uuid
+      @objects = Collection.where('uuid in (?)', uuids)
+    end
+    @response_resource_name = 'collection'
+    super
+  end
+
+  def signatures
+    current_user_uuid = (current_user.andand.is_admin && params[:uuid]) ||
+      current_user.uuid
+    act_as_system_user do
+      @objects = Link.where(owner_uuid: system_user_uuid,
+                            link_class: 'signature',
+                            name: 'click',
+                            tail_kind: 'arvados#user',
+                            tail_uuid: current_user_uuid,
+                            head_kind: 'arvados#collection')
+    end
+    @response_resource_name = 'link'
+    render_list
+  end
+
+  def sign
+    current_user_uuid = current_user.uuid
+    act_as_system_user do
+      @object = Link.create(link_class: 'signature',
+                            name: 'click',
+                            tail_kind: 'arvados#user',
+                            tail_uuid: current_user_uuid,
+                            head_kind: 'arvados#collection',
+                            head_uuid: params[:id])
+    end
+    show
+  end
+
+  def create
+    usage_error
+  end
+  
+  def new
+    usage_error
+  end
+
+  def update
+    usage_error
+  end
+
+  def destroy
+    usage_error
+  end
+
+  protected
+  def usage_error
+    raise ArgumentError.new \
+    "Manage user agreements via Collections and Links instead."
+  end
+  
+end
diff --git a/services/api/app/controllers/arvados/v1/users_controller.rb b/services/api/app/controllers/arvados/v1/users_controller.rb
index a0d2f54..5498619 100644
--- a/services/api/app/controllers/arvados/v1/users_controller.rb
+++ b/services/api/app/controllers/arvados/v1/users_controller.rb
@@ -40,4 +40,43 @@ class Arvados::V1::UsersController < ApplicationController
       }
     end
   end
+
+  def activate
+    if current_user.andand.is_admin && params[:uuid]
+      @user = User.find params[:uuid]
+    else
+      @user = current_user
+    end
+    if not @user.is_active
+      target_user_uuid = @user.uuid
+      act_as_system_user do
+        required_uuids = Link.where(owner_uuid: system_user_uuid,
+                                    link_class: 'signature',
+                                    name: 'require',
+                                    tail_uuid: system_user_uuid,
+                                    head_kind: 'arvados#collection').
+          collect(&:head_uuid)
+        signed_uuids = Link.where(owner_uuid: system_user_uuid,
+                                  link_class: 'signature',
+                                  name: 'click',
+                                  tail_kind: 'arvados#user',
+                                  tail_uuid: target_user_uuid,
+                                  head_kind: 'arvados#collection',
+                                  head_uuid: required_uuids).
+          collect(&:head_uuid)
+        todo_uuids = required_uuids - signed_uuids
+        if todo_uuids == []
+          @user.update_attributes is_active: true
+          logger.info "User #{@user.uuid} activated"
+        else
+          logger.warn "User #{@user.uuid} called users.activate " +
+            "before signing agreements #{todo_uuids.inspect}"
+          raise ArgumentError.new \
+          "Cannot activate without user agreements #{todo_uuids.inspect}."
+        end
+      end
+    end
+    @object = @user
+    show
+  end
 end
diff --git a/services/api/app/models/user_agreement.rb b/services/api/app/models/user_agreement.rb
new file mode 100644
index 0000000..1790dea
--- /dev/null
+++ b/services/api/app/models/user_agreement.rb
@@ -0,0 +1,4 @@
+class UserAgreement < Collection
+  # This class exists so that Arvados::V1::SchemaController includes
+  # UserAgreementsController's methods in the discovery document.
+end
diff --git a/services/api/config/routes.rb b/services/api/config/routes.rb
index 5f9900d..65b6a17 100644
--- a/services/api/config/routes.rb
+++ b/services/api/config/routes.rb
@@ -89,10 +89,13 @@ Server::Application.routes.draw do
       match '/jobs/:uuid/log_tail_follow' => 'jobs#log_tail_follow'
       post '/jobs/:uuid/cancel' => 'jobs#cancel'
       match '/users/:uuid/event_stream' => 'users#event_stream'
+      post '/users/:uuid/activate' => 'users#activate'
       match '/virtual_machines/get_all_logins' => 'virtual_machines#get_all_logins'
       match '/virtual_machines/:uuid/logins' => 'virtual_machines#logins'
       post '/api_client_authorizations/create_system_auth' => 'api_client_authorizations#create_system_auth'
       match '/repositories/get_all_permissions' => 'repositories#get_all_permissions'
+      get '/user_agreements/signatures' => 'user_agreements#signatures'
+      post '/user_agreements/sign' => 'user_agreements#sign'
       resources :collections
       resources :links
       resources :nodes
@@ -112,6 +115,7 @@ Server::Application.routes.draw do
       resources :repositories
       resources :traits
       resources :humans
+      resources :user_agreements
     end
   end
 
diff --git a/services/api/test/fixtures/api_client_authorizations.yml b/services/api/test/fixtures/api_client_authorizations.yml
index 7231b14..7effb2f 100644
--- a/services/api/test/fixtures/api_client_authorizations.yml
+++ b/services/api/test/fixtures/api_client_authorizations.yml
@@ -30,6 +30,12 @@ inactive:
   api_token: 5s29oj2hzmcmpq80hx9cta0rl5wuf3xfd6r7disusaptz7h9m0
   expires_at: 2038-01-01 00:00:00
 
+inactive_but_signed_user_agreement:
+  api_client: untrusted
+  user: inactive_but_signed_user_agreement
+  api_token: 64k3bzw37iwpdlexczj02rw3m333rrb8ydvn2qq99ohv68so5k
+  expires_at: 2038-01-01 00:00:00
+
 expired:
   api_client: untrusted
   user: active
diff --git a/services/api/test/fixtures/collections.yml b/services/api/test/fixtures/collections.yml
new file mode 100644
index 0000000..8cbaea5
--- /dev/null
+++ b/services/api/test/fixtures/collections.yml
@@ -0,0 +1,9 @@
+user_agreement:
+  uuid: b519d9cb706a29fc7ea24dbea2f05851
+  owner_uuid: qr1hi-tpzed-tpj2ff66551eyym
+  created_at: 2013-12-26T19:22:54Z
+  modified_by_client_uuid: zzzzz-ozdt8-brczlopd8u8d0jr
+  modified_by_user_uuid: zzzzz-tpzed-d9tiejq69daie8f
+  modified_at: 2013-12-26T19:22:54Z
+  updated_at: 2013-12-26T19:22:54Z
+  manifest_text: ". 6a4ff0499484c6c79c95cd8c566bd25f+249025 0:249025:GNU_General_Public_License,_version_3.pdf\n"
diff --git a/services/api/test/fixtures/links.yml b/services/api/test/fixtures/links.yml
new file mode 100644
index 0000000..4d5bfe5
--- /dev/null
+++ b/services/api/test/fixtures/links.yml
@@ -0,0 +1,47 @@
+user_agreement_required:
+  uuid: zzzzz-o0j2j-j2qe76q7s3c8aro
+  owner_uuid: zzzzz-tpzed-000000000000000
+  created_at: 2013-12-26T19:52:21Z
+  modified_by_client_uuid: zzzzz-ozdt8-brczlopd8u8d0jr
+  modified_by_user_uuid: zzzzz-tpzed-d9tiejq69daie8f
+  modified_at: 2013-12-26T19:52:21Z
+  updated_at: 2013-12-26T19:52:21Z
+  tail_kind: arvados#user
+  tail_uuid: zzzzz-tpzed-000000000000000
+  link_class: signature
+  name: require
+  head_kind: arvados#collection
+  head_uuid: b519d9cb706a29fc7ea24dbea2f05851
+  properties: {}
+
+user_agreement_signed_by_active:
+  uuid: zzzzz-o0j2j-4x85a69tqlrud1z
+  owner_uuid: zzzzz-tpzed-000000000000000
+  created_at: 2013-12-26T20:52:21Z
+  modified_by_client_uuid: zzzzz-ozdt8-brczlopd8u8d0jr
+  modified_by_user_uuid: zzzzz-tpzed-xurymjxw79nv3jz
+  modified_at: 2013-12-26T20:52:21Z
+  updated_at: 2013-12-26T20:52:21Z
+  tail_kind: arvados#user
+  tail_uuid: zzzzz-tpzed-xurymjxw79nv3jz
+  link_class: signature
+  name: click
+  head_kind: arvados#collection
+  head_uuid: b519d9cb706a29fc7ea24dbea2f05851
+  properties: {}
+
+user_agreement_signed_by_inactive:
+  uuid: zzzzz-o0j2j-lh7er2o3k6bmetw
+  owner_uuid: zzzzz-tpzed-000000000000000
+  created_at: 2013-12-26T20:52:21Z
+  modified_by_client_uuid: zzzzz-ozdt8-brczlopd8u8d0jr
+  modified_by_user_uuid: zzzzz-tpzed-7sg468ezxwnodxs
+  modified_at: 2013-12-26T20:52:21Z
+  updated_at: 2013-12-26T20:52:21Z
+  tail_kind: arvados#user
+  tail_uuid: zzzzz-tpzed-7sg468ezxwnodxs
+  link_class: signature
+  name: click
+  head_kind: arvados#collection
+  head_uuid: b519d9cb706a29fc7ea24dbea2f05851
+  properties: {}
diff --git a/services/api/test/fixtures/users.yml b/services/api/test/fixtures/users.yml
index b4f8fec..c6f25d6 100644
--- a/services/api/test/fixtures/users.yml
+++ b/services/api/test/fixtures/users.yml
@@ -22,7 +22,7 @@ active:
 
 inactive:
   uuid: zzzzz-tpzed-x9kqpd79egh49c7
-  email: active-user at arvados.local
+  email: inactive-user at arvados.local
   first_name: Inactive
   last_name: User
   identity_url: https://inactive-user.openid.local
@@ -30,3 +30,13 @@ inactive:
   is_admin: false
   prefs: {}
 
+inactive_but_signed_user_agreement:
+  uuid: zzzzz-tpzed-7sg468ezxwnodxs
+  email: inactive-user-signed-ua at arvados.local
+  first_name: Inactive But Agreeable
+  last_name: User
+  identity_url: https://inactive-but-agreeable-user.openid.local
+  is_active: false
+  is_admin: false
+  prefs: {}
+
diff --git a/services/api/test/functional/arvados/v1/user_agreements_controller_test.rb b/services/api/test/functional/arvados/v1/user_agreements_controller_test.rb
new file mode 100644
index 0000000..41c81cb
--- /dev/null
+++ b/services/api/test/functional/arvados/v1/user_agreements_controller_test.rb
@@ -0,0 +1,36 @@
+require 'test_helper'
+
+class Arvados::V1::UserAgreementsControllerTest < ActionController::TestCase
+
+  test "active user get user agreements" do
+    authorize_with :active
+    get :index
+    assert_response :success
+    assert_not_nil assigns(:objects)
+    agreements_list = JSON.parse(@response.body)
+    assert_not_nil agreements_list['items']
+    assert_not_nil agreements_list['items'][0]
+  end
+
+  test "active user get user agreement signatures" do
+    authorize_with :active
+    get :signatures
+    assert_response :success
+    assert_not_nil assigns(:objects)
+    agreements_list = JSON.parse(@response.body)
+    assert_not_nil agreements_list['items']
+    assert_not_nil agreements_list['items'][0]
+    assert_equal 1, agreements_list['items'].count
+  end
+
+  test "inactive user get user agreements" do
+    authorize_with :inactive
+    get :index
+    assert_response :success
+    assert_not_nil assigns(:objects)
+    agreements_list = JSON.parse(@response.body)
+    assert_not_nil agreements_list['items']
+    assert_not_nil agreements_list['items'][0]
+  end
+
+end
diff --git a/services/api/test/functional/arvados/v1/users_controller_test.rb b/services/api/test/functional/arvados/v1/users_controller_test.rb
new file mode 100644
index 0000000..4b52c9b
--- /dev/null
+++ b/services/api/test/functional/arvados/v1/users_controller_test.rb
@@ -0,0 +1,41 @@
+require 'test_helper'
+
+class Arvados::V1::UsersControllerTest < ActionController::TestCase
+
+  test "activate a user after signing UA" do
+    authorize_with :inactive_but_signed_user_agreement
+    get :current
+    assert_response :success
+    me = JSON.parse(@response.body)
+    post :activate, uuid: me['uuid']
+    assert_response :success
+    assert_not_nil assigns(:object)
+    me = JSON.parse(@response.body)
+    assert_equal true, me['is_active']
+  end
+
+  test "refuse to activate a user before signing UA" do
+    authorize_with :inactive
+    get :current
+    assert_response :success
+    me = JSON.parse(@response.body)
+    post :activate, uuid: me['uuid']
+    assert_response 422
+    get :current
+    assert_response :success
+    me = JSON.parse(@response.body)
+    assert_equal false, me['is_active']
+  end
+
+  test "activate an already-active user" do
+    authorize_with :active
+    get :current
+    assert_response :success
+    me = JSON.parse(@response.body)
+    post :activate, uuid: me['uuid']
+    assert_response :success
+    me = JSON.parse(@response.body)
+    assert_equal true, me['is_active']
+  end
+
+end

-----------------------------------------------------------------------


hooks/post-receive
-- 




More information about the arvados-commits mailing list