Merge pull request #199 from abf/rosa-build:192-hidden-platforms-and-tokens

#192: Add hidden platforms and tokens for them
This commit is contained in:
avm 2013-07-02 22:29:06 +04:00
commit 38a4729cbc
30 changed files with 608 additions and 22 deletions

View File

@ -736,6 +736,10 @@ table.tablesorter.list-users th.th4 {
width: 50px;
}
table.tablesorter.tokens th.th2 {
width: 200px;
}
div.admin-role {
padding-right: 10px;
}

View File

@ -1,9 +1,36 @@
# -*- encoding : utf-8 -*-
class Api::V1::PlatformsController < Api::V1::BaseController
before_filter :authenticate_user!
skip_before_filter :authenticate_user!, :only => :allowed
skip_before_filter :authenticate_user!, :only => [:show, :platforms_for_build, :members] if APP_CONFIG['anonymous_access']
load_and_authorize_resource
load_and_authorize_resource :except => :allowed
def allowed
platform_name = (params[:path] || '').match(/^\/#{Platform::NAME_PATTERN}\//)
render(:inline => 'true') && return unless platform_name
platform_name = platform_name[0].gsub(/\//, '')
platform = Platform.find_by_name platform_name
render(:inline => 'false', :status => 403) && return unless platform
render(:inline => 'true') && return unless platform.hidden?
if request.authorization.present?
token, pass = *ActionController::HttpAuthentication::Basic::user_name_and_password(request)
else
render(:inline => 'false', :status => 403) && return
end
render(:inline => 'true') && return if platform.tokens.by_active.where(:authentication_token => token).exists?
user = User.find_by_authentication_token token
@current_ability, @current_user = nil, user
if user && can?(:read, platform)
render :inline => 'true'
else
render :inline => 'false', :status => 403
end
end
def index
@platforms = @platforms.accessible_by(current_ability, :related).

View File

@ -8,7 +8,7 @@ class ApplicationController < ActionController::Base
layout :layout_by_resource
# Hack to prevent token auth on all pages except atom feed:
prepend_before_filter lambda { redirect_to(new_user_session_path) if params[:token] && params[:format] != 'atom'}
prepend_before_filter lambda { redirect_to(new_user_session_path) if params[:token] && params[:token].is_a?(String) && params[:format] != 'atom'}
before_filter :set_locale
before_filter lambda { EventLog.current_controller = self },

View File

@ -56,6 +56,17 @@ class Platforms::PlatformsController < Platforms::BaseController
end
end
def change_visibility
if @platform.change_visibility
flash[:notice] = I18n.t("flash.platform.saved")
redirect_to @platform
else
flash[:error] = I18n.t("flash.platform.save_error")
flash[:warning] = @platform.errors.full_messages.join('. ')
render :action => :edit
end
end
def clone
@cloned = Platform.new
@cloned.name = @platform.name + "_clone"

View File

@ -0,0 +1,42 @@
class Platforms::TokensController < Platforms::BaseController
before_filter :authenticate_user!
load_resource :platform
load_and_authorize_resource :through => :platform, :shallow => true
def index
authorize! :local_admin_manage, @platform
@tokens = @platform.tokens.includes(:creator, :updater)
.paginate(:per_page => 20, :page => params[:page])
end
def show
end
def withdraw
if @token.block
@token.updater = current_user
@token.save
redirect_to :back, :notice => t('flash.tokens.withdraw_success')
else
redirect_to :back, :notice => t('flash.tokens.withdraw_fail')
end
end
def new
end
def create
@token = @platform.tokens.build params[:token]
@token.creator = current_user
if @token.save
flash[:notice] = t('flash.tokens.saved')
redirect_to platform_tokens_path(@platform)
else
flash[:error] = t('flash.tokens.save_error')
flash[:warning] = @token.errors.full_messages.join('. ') unless @token.errors.blank?
render :new
end
end
end

View File

@ -105,7 +105,7 @@ class Ability
can [:read, :related, :members], Platform, :owner_type => 'Group', :owner_id => user.group_ids
can([:read, :related, :members], Platform, read_relations_for('platforms')) {|platform| local_reader? platform}
can :related, Platform, :id => user.repositories.pluck(:platform_id)
can([:update, :destroy], Platform) {|platform| owner?(platform) }
can([:update, :destroy, :change_visibility], Platform) {|platform| owner?(platform) }
can([:local_admin_manage, :members, :add_member, :remove_member, :remove_members] , Platform) {|platform| owner?(platform) || local_admin?(platform) }
can([:create, :publish], MassBuild) {|mass_build| owner?(mass_build.save_to_platform) || local_admin?(mass_build.save_to_platform)}
@ -118,10 +118,12 @@ class Ability
can([:remove_members, :remove_member, :add_member, :signatures], Repository) {|repository| owner?(repository.platform) || local_admin?(repository.platform)}
can([:add_project, :remove_project], Repository) {|repository| repository.members.exists?(:id => user.id)}
can(:clear, Platform) {|platform| owner?(platform) && platform.personal?}
can([:change_visibility, :settings, :destroy, :edit, :update], Repository) {|repository| owner? repository.platform}
can([:settings, :destroy, :edit, :update], Repository) {|repository| owner? repository.platform}
can([:create, :destroy], KeyPair) {|key_pair| owner?(key_pair.repository.platform) || local_admin?(key_pair.repository.platform)}
can([:read, :create, :withdraw], Token) {|token| local_admin?(token.subject)}
can :read, Product, :platform => {:owner_type => 'User', :owner_id => user.id, :platform_type => 'main'}
can :read, Product, :platform => {:owner_type => 'Group', :owner_id => user.group_ids, :platform_type => 'main'}
can(:read, Product, read_relations_for('products', 'platforms')) {|product| product.platform.main?}

View File

@ -392,20 +392,20 @@ class BuildList < ActiveRecord::Base
repos = include_repos
include_repos_hash = {}.tap do |h|
Repository.where(:id => (repos | (extra_repositories || [])) ).each do |repo|
path = repo.platform.public_downloads_url(
path, prefix = repo.platform.public_downloads_url(
repo.platform.main? ? nil : build_for_platform.name,
arch.name,
repo.name
)
h["#{repo.platform.name}_#{repo.name}_release"] = path + 'release'
h["#{repo.platform.name}_#{repo.name}_updates"] = path + 'updates' if repo.platform.main?
), "#{repo.platform.name}_#{repo.name}_"
h["#{prefix}release"] = insert_token_to_path(path + 'release', repo.platform)
h["#{prefix}updates"] = insert_token_to_path(path + 'updates', repo.platform) if repo.platform.main?
end
end
host = EventLog.current_controller.request.host_with_port rescue ::Rosa::Application.config.action_mailer.default_url_options[:host]
BuildList.where(:id => extra_build_lists).each do |bl|
path = "#{APP_CONFIG['downloads_url']}/#{bl.save_to_platform.name}/container/"
path << "#{bl.id}/#{bl.arch.name}/#{bl.save_to_repository.name}/release"
include_repos_hash["container_#{bl.id}"] = path
include_repos_hash["container_#{bl.id}"] = insert_token_to_path(path, bl.save_to_platform)
end
git_project_address = project.git_project_address user
@ -423,6 +423,14 @@ class BuildList < ActiveRecord::Base
}
end
def insert_token_to_path(path, platform)
if platform.hidden?
path.gsub(/^http:\/\//, "http://#{user.authentication_token}:@")
else
path
end
end
def notify_users
unless mass_build_id
users = []

View File

@ -1,12 +1,14 @@
# -*- encoding : utf-8 -*-
class Platform < ActiveRecord::Base
VISIBILITIES = ['open']#, 'hidden'] # Disable support hidden platforms.
VISIBILITIES = %w(open hidden)
NAME_PATTERN = /[a-zA-Z0-9_\-\.]+/
belongs_to :parent, :class_name => 'Platform', :foreign_key => 'parent_platform_id'
belongs_to :owner, :polymorphic => true
has_many :repositories, :dependent => :destroy
has_many :products, :dependent => :destroy
has_many :tokens, :as => :subject, :dependent => :destroy
has_many :relations, :as => :target, :dependent => :destroy
has_many :actors, :as => :target, :class_name => 'Relation', :dependent => :destroy
@ -20,7 +22,7 @@ class Platform < ActiveRecord::Base
validates :description, :presence => true
validates :visibility, :presence => true, :inclusion => {:in => VISIBILITIES}
validates :name, :uniqueness => {:case_sensitive => false}, :presence => true, :format => { :with => /\A[a-zA-Z0-9_\-\.]+\z/ }
validates :name, :uniqueness => {:case_sensitive => false}, :presence => true, :format => { :with => /\A#{NAME_PATTERN}\z/ }
validates :distrib_type, :presence => true, :inclusion => {:in => APP_CONFIG['distr_types']}
validate lambda {
if released_was && !released
@ -141,10 +143,8 @@ class Platform < ActiveRecord::Base
def change_visibility
if !hidden?
update_attributes(:visibility => 'hidden')
remove_symlink_directory
else
update_attributes(:visibility => 'open')
symlink_directory
end
end

32
app/models/token.rb Normal file
View File

@ -0,0 +1,32 @@
# -*- encoding : utf-8 -*-
class Token < ActiveRecord::Base
belongs_to :subject, :polymorphic => true, :touch => true
belongs_to :creator, :class_name => 'User'
belongs_to :updater, :class_name => 'User'
validates :creator_id, :subject_id, :subject_type, :presence => true
validates :authentication_token, :presence => true, :uniqueness => {:case_sensitive => true}
default_scope order("#{table_name}.created_at desc")
scope :by_active, where(:status => 'active')
before_validation :generate_token, :on => :create
attr_accessible :description
state_machine :status, :initial => :active do
event :block do
transition [:active, :blocked] => :blocked
end
end
protected
def generate_token
self.authentication_token = loop do
token = SecureRandom.urlsafe_base64(32)
break token unless Token.where(:authentication_token => token).exists?
end
end
end

View File

@ -30,6 +30,8 @@
- if can? :edit, @platform
%li{:class => (act == :index && contr == :key_pairs) ? 'active' : ''}
= link_to t("layout.key_pairs.header"), platform_key_pairs_path(@platform)
%li{:class => (contr == :tokens) ? 'active' : ''}
= link_to t('layout.tokens.header'), platform_tokens_path(@platform)
-#- if current_user.owner_of? @platform or current_user.admin?
%li{:class => (act == :index && contr == :private_users) ? 'active' : ''}
= link_to t("layout.platforms.private_users"), platform_private_users_path(@platform)

View File

@ -5,6 +5,16 @@
= form_for @platform, :url => platform_path(@platform), :html => { :class => :form } do |f|
= render "form", :f => f
- if can? :change_visibility, @platform
.hr
.leftside= t('activerecord.attributes.platform.visibility')
.rightside= link_to t("layout.platforms.change_visibility_from_#{@platform.visibility}"),
change_visibility_platform_path(@platform),
:method => :post,
:confirm => t("layout.platforms.confirm_change_visibility"),
:class => 'button'
.both
- if can? :destroy, @platform
.hr
.leftside= t("layout.platforms.delete_warning")

View File

@ -0,0 +1,21 @@
-set_meta_tags :title => [title_object(@platform), t('layout.tokens.header')]
= render 'submenu'
= render 'sidebar'
= link_to t('layout.tokens.new'), new_platform_token_path(@platform), :class => 'button'
%table#myTable.tablesorter.tokens{:cellspacing => "0", :cellpadding => "0"}
%thead
%tr
%th= t('activerecord.attributes.token.description')
%th.th2= t('activerecord.attributes.token.creator')
%th= t('activerecord.attributes.token.status')
%th
%tbody
- @tokens.each do |token|
%tr{:class => cycle('odd', 'even')}
%td= truncate token.description, :length => 50
%td= link_to token.creator.try(:fullname), token.creator
%td= t("layout.tokens.statuses.#{token.status}")
%td= link_to t('layout.show'), platform_token_path(@platform, token)
= will_paginate @tokens

View File

@ -0,0 +1,16 @@
-set_meta_tags :title => [title_object(@platform), t('layout.tokens.new')]
= render 'submenu'
= render 'sidebar'
%h3= t('layout.tokens.new')
= form_for @token, :url => platform_tokens_path(@platform), :method => :post, :html => { :class => :form } do |f|
.leftlist= f.label :description
.rightlist= f.text_area :description
.both
.hr
.button_block
= submit_tag t('layout.save')
%span.text_button_padding= t('layout.or')
= link_to t('layout.cancel'), platform_tokens_path(@platform), :class => 'button'

View File

@ -0,0 +1,41 @@
-set_meta_tags :title => [title_object(@platform), t('layout.tokens.header')]
= render 'submenu'
= render 'sidebar'
%h3.fix= "#{t('layout.tokens.about')} #{@platform.name}"
%p= @token.description
%table.tablesorter.unbordered
%tr
%td
%b= "#{t('activerecord.attributes.token.creator')}:"
%td= link_to @token.creator.try(:name), @token.creator
%tr
%td
%b= "#{t('activerecord.attributes.token.created_at')}:"
%td= @token.created_at
- if @token.updater
%tr
%td
%b= "#{t('activerecord.attributes.token.updater')}:"
%td= link_to @token.updater.try(:name), @token.updater if @token.updater
%tr
%td
%b= "#{t('activerecord.attributes.token.updated_at')}:"
%td= @token.updated_at
%tr
%td
%b= "#{t('activerecord.attributes.token.status')}:"
%td= t("layout.tokens.statuses.#{@token.status}")
%tr
%td
%b= "#{t('activerecord.attributes.token.authentication_token')}:"
%td= @token.authentication_token
- if @token.active?
.buttons_block
= link_to t('layout.tokens.withdraw'),
withdraw_platform_token_path(@platform, @token),
:method => :post, :class => 'button',
:confirm => t('layout.tokens.withdraw_confirm')

View File

@ -46,6 +46,9 @@ en:
mass_build: Mass build
build_task: Build Task
refresh_button: Refresh
change_visibility_from_hidden: Change status to "Public"
change_visibility_from_open: Change status to "Private"
confirm_change_visibility: Are you sure you want to change visibility of this platform?
flash:
platform:

View File

@ -46,6 +46,9 @@ ru:
build_task: Сборочное задание
refresh_button: Обновить
project: Проект
change_visibility_from_hidden: Сменить статус на "Публичный"
change_visibility_from_open: Сменить статус на "Приватный"
confirm_change_visibility: Вы уверены, что хотите сменить статус этой платформы?
flash:
platform:

View File

@ -22,8 +22,6 @@ en:
personal_repositories:
settings_header: Settings
change_visibility_from_hidden: Change status to "Public"
change_visibility_from_open: Change status to "Private"
settings: Settings
show: My repository
private_users: Private repository users

View File

@ -22,8 +22,6 @@ ru:
personal_repositories:
settings_header: Настройки
change_visibility_from_hidden: Сменить статус на "Публичный"
change_visibility_from_open: Сменить статус на "Приватный"
settings: Настройки
show: Мой репозиторий
private_users: Пользователи приватного репозитория

View File

@ -0,0 +1,32 @@
en:
layout:
tokens:
header: Tokens
new: New token
about: Token of platform
withdraw: Withdraw
withdraw_confirm: Are you sure you want to withdraw this token?
statuses:
active: Active
blocked: Withdrawed
flash:
tokens:
saved: Token added
save_error: Unable to add token
withdraw_success: Token withdrawed
withdraw_fail: Unable to withdraw token
activerecord:
models:
token: Token
attributes:
token:
description: Description
status: Status
authentication_token: Token
created_at: Created
updated_at: Updated
creator: Creator
updater: Updater

View File

@ -0,0 +1,32 @@
ru:
layout:
tokens:
header: Токены
new: Новый токен
about: Токен платформы
withdraw: Отозвать
withdraw_confirm: Уверены, что хотите отозвать токен?
statuses:
active: Активный
blocked: Отозван
flash:
tokens:
saved: Токен успешно добавлен
save_error: Не удалось добавить токен
withdraw_success: Токен успешно отозван!
withdraw_fail: Не удалось отозвать токен!
activerecord:
models:
token: Токен
attributes:
token:
description: Описание
status: Статус
authentication_token: Токен
created_at: Создан
updated_at: Обновлен
creator: Создал
updater: Обновил

View File

@ -26,6 +26,7 @@ Rosa::Application.routes.draw do
resources :platforms, :only => [:index, :show, :update, :destroy, :create] do
collection {
get :platforms_for_build
get :allowed
}
member {
get :members
@ -153,8 +154,9 @@ Rosa::Application.routes.draw do
get :clone
get :members
post :remove_members # fixme: change post to delete
post :change_visibility
delete :remove_member
post :add_member
post :add_member
post :make_clone
get :advisories
end
@ -179,6 +181,11 @@ Rosa::Application.routes.draw do
end
end
resources :key_pairs, :only => [:create, :index, :destroy]
resources :tokens, :only => [:create, :index, :show, :new] do
member do
post :withdraw
end
end
resources :products do
resources :product_build_lists, :only => [:create, :destroy, :new, :show, :update] do
member {

View File

@ -0,0 +1,19 @@
class CreateTokens < ActiveRecord::Migration
def change
create_table :tokens do |t|
t.integer :subject_id, :null => false
t.string :subject_type, :null => false
t.integer :creator_id, :null => false
t.integer :updater_id
t.string :status, :default => 'active'
t.text :description
t.string :authentication_token, :null => false
t.timestamps
end
add_index :tokens, :authentication_token, :unique => true
add_index :tokens, [:subject_id, :subject_type]
end
end

View File

@ -499,6 +499,21 @@ ActiveRecord::Schema.define(:version => 20130701121313) do
t.decimal "subscribeable_id", :precision => 50, :scale => 0
end
create_table "tokens", :force => true do |t|
t.integer "subject_id", :null => false
t.string "subject_type", :null => false
t.integer "creator_id", :null => false
t.integer "updater_id"
t.string "status", :default => "active"
t.text "description"
t.string "authentication_token", :null => false
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
end
add_index "tokens", ["authentication_token"], :name => "index_tokens_on_authentication_token", :unique => true
add_index "tokens", ["subject_id", "subject_type"], :name => "index_tokens_on_subject_id_and_subject_type"
create_table "users", :force => true do |t|
t.string "name"
t.string "email", :default => "", :null => false

View File

@ -246,6 +246,67 @@ describe Api::V1::PlatformsController do
it_should_behave_like 'api platform user without member rights'
it_should_behave_like 'api platform user without owner rights'
it_should_behave_like 'api platform user without global admin rights'
context 'perform allowed action' do
it 'ensures that status 200 if platform empty' do
get :allowed
response.status.should == 200
end
it 'ensures that status 403 if platform does not exist' do
get :allowed, :path => "/rosa-server/repository/SRPMS/base/release/repodata/"
response.status.should == 403
end
it 'ensures that status 200 if platform open' do
get :allowed, :path => "/#{@platform.name}/repository/SRPMS/base/release/repodata/"
response.status.should == 200
end
context 'for hidden platform' do
before { @platform.change_visibility }
it 'ensures that status 403 if no token' do
get :allowed, :path => "/#{@platform.name}/repository/SRPMS/base/release/repodata/"
response.status.should == 403
end
it 'ensures that status 403 if wrong token' do
http_login 'KuKu', ''
get :allowed, :path => "/#{@platform.name}/repository/SRPMS/base/release/repodata/"
response.status.should == 403
end
it 'ensures that status 200 if token correct' do
token = FactoryGirl.create(:platform_token, :subject => @platform)
http_login token.authentication_token, ''
get :allowed, :path => "/#{@platform.name}/repository/SRPMS/base/release/repodata/"
response.status.should == 200
end
it 'ensures that status 403 if token correct but blocked' do
token = FactoryGirl.create(:platform_token, :subject => @platform)
token.block
http_login token.authentication_token, ''
get :allowed, :path => "/#{@platform.name}/repository/SRPMS/base/release/repodata/"
response.status.should == 403
end
it 'ensures that status 200 if user token correct and user has ability to read platform' do
http_login @platform.owner.authentication_token, ''
get :allowed, :path => "/#{@platform.name}/repository/SRPMS/base/release/repodata/"
response.status.should == 200
end
it 'ensures that status 403 if user token correct but user has no ability to read platform' do
user = FactoryGirl.create(:user)
http_login user.authentication_token, ''
get :allowed, :path => "/#{@platform.name}/repository/SRPMS/base/release/repodata/"
response.status.should == 403
end
end
end
end
context 'for global admin' do

View File

@ -29,6 +29,22 @@ shared_examples_for 'platform user with owner rights' do
end
end
context 'perform change_visibility action' do
before do
@visibility = @platform.visibility
post :change_visibility, :id => @platform.id
end
it 'should be able to perform action' do
response.should redirect_to(platform_path(@platform))
end
it 'ensures that visibility of platform has been changed' do
@platform.reload
@platform.visibility.should_not == @visibility
end
end
context 'platform user with destroy rights for main platforms only' do
it 'should be able to perform destroy action for main platform' do
delete :destroy, :id => @platform.id
@ -62,6 +78,22 @@ shared_examples_for 'platform user without owner rights' do
end
end
context 'perform change_visibility action' do
before do
@visibility = @platform.visibility
post :change_visibility, :id => @platform.id
end
it 'should not be able to perform action' do
response.should_not be_success
end
it 'ensures that visibility of platform has not been changed' do
@platform.reload
@platform.visibility.should == @visibility
end
end
context 'platform user without destroy rights' do
it 'should not be able to perform destroy action for main platform' do
delete :destroy, :id => @platform.id

View File

@ -0,0 +1,127 @@
require 'spec_helper'
def create_key_pair(repository, user)
@key_pair = FactoryGirl.create(:key_pair, :repository => repository, :user => user)
end
shared_examples_for 'token of platform for owner' do
[:index, :new].each do |action|
it "should be able to perform #{action} action" do
get action, :platform_id => @platform
response.should render_template(action)
end
end
it 'should not be able to perform show action' do
get :show, :platform_id => @platform, :id => @platform_token
response.should render_template(:show)
end
it 'should be able to perform create action' do
post :create, @create_params
response.should redirect_to(platform_tokens_path(@platform))
end
it 'should create key pair into db on create action' do
lambda { post :create, @create_params }.should change{Token.count}.by(1)
end
end
shared_examples_for 'token of platform for simple user or guest' do
[:index, :new].each do |action|
it "should not be able to perform #{ action } action" do
get action, :platform_id => @platform
response.should redirect_to(redirected_url)
end
end
it 'should not be able to perform show action' do
get :show, :platform_id => @platform, :id => @platform_token
response.should redirect_to(redirected_url)
end
it 'should not be able to perform show action' do
post :create, @create_params
response.should redirect_to(redirected_url)
end
it 'should not change objects count on create success' do
lambda { post :create, @create_params }.should change{ Token.count }.by(0)
end
end
describe Platforms::TokensController do
before do
stub_symlink_methods
@platform = FactoryGirl.create(:platform)
@user = FactoryGirl.create(:user)
@platform_token = FactoryGirl.create(:platform_token, :subject => @platform)
@create_params = {
:platform_id => @platform,
:tokens => {
:description => 'description'
}
}
end
it_should_behave_like 'token of platform for simple user or guest' do
let(:redirected_url) { new_user_session_path }
end
context 'for global admin' do
before(:each) do
@admin = FactoryGirl.create(:admin)
@user = FactoryGirl.create(:user)
set_session_for(@admin)
end
it_should_behave_like 'token of platform for owner'
end
context 'for owner user' do
before(:each) do
@user = FactoryGirl.create(:user)
set_session_for(@user)
@platform.owner = @user
@platform.save
end
it_should_behave_like 'token of platform for owner'
end
context 'for admin user' do
before(:each) do
@user = FactoryGirl.create(:user)
set_session_for(@user)
@platform.relations.create!(:actor_type => 'User', :actor_id => @user.id, :role => 'admin')
end
it_should_behave_like 'token of platform for owner'
end
context 'for reader user' do
before do
@user = FactoryGirl.create(:user)
set_session_for(@user)
@platform.relations.create!(:actor_type => 'User', :actor_id => @user.id, :role => 'reader')
end
it_should_behave_like 'token of platform for simple user or guest' do
let(:redirected_url) { forbidden_url }
end
end
context 'for simple user' do
before do
@user = FactoryGirl.create(:user)
set_session_for(@user)
end
it_should_behave_like 'token of platform for simple user or guest' do
let(:redirected_url) { forbidden_url }
end
end
end

10
spec/factories/token.rb Normal file
View File

@ -0,0 +1,10 @@
# -*- encoding : utf-8 -*-
FactoryGirl.define do
factory :token do
association :creator, :factory => :user
end
factory :platform_token, :parent => :token do
association :subject, :factory => :platform
end
end

View File

@ -241,7 +241,7 @@ describe CanCan do
@platform.save
end
[:read, :update, :destroy].each do |action|
[:read, :update, :destroy, :change_visibility].each do |action|
it "should be able to #{action} platform" do
@ability.should be_able_to(action, @platform)
end
@ -270,7 +270,7 @@ describe CanCan do
@repository.platform.save
end
[:read, :create, :update, :destroy, :add_project, :remove_project, :change_visibility, :settings].each do |action|
[:read, :create, :update, :destroy, :add_project, :remove_project, :settings].each do |action|
it "should be able to #{action} repository" do
@ability.should be_able_to(action, @repository)
end

32
spec/models/token_spec.rb Normal file
View File

@ -0,0 +1,32 @@
# -*- encoding : utf-8 -*-
require 'spec_helper'
describe Token do
before { stub_symlink_methods }
describe 'platform token' do
let!(:platform_token) { FactoryGirl.create(:platform_token) }
context 'ensures that validations and associations exist' do
it { should belong_to(:subject) }
it { should belong_to(:creator) }
it { should validate_presence_of(:creator_id) }
it { should validate_presence_of(:subject_id) }
it { should validate_presence_of(:subject_type) }
it { should_not allow_mass_assignment_of(:authentication_token) }
it { should_not allow_mass_assignment_of(:creator_id) }
it { should_not allow_mass_assignment_of(:subject_id) }
it { should_not allow_mass_assignment_of(:subject_type) }
it 'ensures that authentication_token unique' do
token = FactoryGirl.create(:platform_token)
token.authentication_token = platform_token.authentication_token
token.valid?.should be_false
end
end
end
end

View File

@ -38,9 +38,10 @@ def set_session_for(user=nil)
sign_in current_user
end
def http_login(user=nil)
def http_login(user=nil, password = '123456')
# FIXME: password constant is a bad choice...
request.env['HTTP_AUTHORIZATION'] = ActionController::HttpAuthentication::Basic.encode_credentials(user.email,'123456')
email = user.is_a?(String) ? user : user.try(:email)
request.env['HTTP_AUTHORIZATION'] = ActionController::HttpAuthentication::Basic.encode_credentials(email, password)
end
def stub_symlink_methods