diff options
| -rw-r--r-- | app/decorators/commit_decorator.rb | 22 | ||||
| -rw-r--r-- | app/models/commit.rb | 2 | ||||
| -rw-r--r-- | app/models/key.rb | 17 | ||||
| -rw-r--r-- | app/views/commits/_head.html.haml | 4 | ||||
| -rw-r--r-- | doc/api/README.md | 2 | ||||
| -rw-r--r-- | features/steps/profile/profile_ssh_keys.rb | 2 | ||||
| -rw-r--r-- | lib/api/helpers.rb | 2 | ||||
| -rw-r--r-- | spec/factories.rb | 12 | ||||
| -rw-r--r-- | spec/factories_spec.rb | 3 | ||||
| -rw-r--r-- | spec/models/commit_spec.rb | 37 | ||||
| -rw-r--r-- | spec/models/key_spec.rb | 12 | ||||
| -rw-r--r-- | spec/requests/projects_deploy_keys_spec.rb | 2 |
12 files changed, 95 insertions, 22 deletions
diff --git a/app/decorators/commit_decorator.rb b/app/decorators/commit_decorator.rb index c85f740027e..777580a6d5e 100644 --- a/app/decorators/commit_decorator.rb +++ b/app/decorators/commit_decorator.rb @@ -16,13 +16,15 @@ class CommitDecorator < ApplicationDecorator # In case this first line is longer than 80 characters, it is cut off # after 70 characters and ellipses (`&hellp;`) are appended. def title - return no_commit_message if safe_message.blank? + title = safe_message - title_end = safe_message.index(/\n/) - if (!title_end && safe_message.length > 80) || (title_end && title_end > 80) - safe_message[0..69] << "…".html_safe + return no_commit_message if title.blank? + + title_end = title.index(/\n/) + if (!title_end && title.length > 80) || (title_end && title_end > 80) + title[0..69] << "…".html_safe else - safe_message.split(/\n/, 2).first + title.split(/\n/, 2).first end end @@ -30,11 +32,13 @@ class CommitDecorator < ApplicationDecorator # # cut off, ellipses (`&hellp;`) are prepended to the commit message. def description - title_end = safe_message.index(/\n/) - if (!title_end && safe_message.length > 80) || (title_end && title_end > 80) - "…".html_safe << safe_message[70..-1] + description = safe_message + + title_end = description.index(/\n/) + if (!title_end && description.length > 80) || (title_end && title_end > 80) + "…".html_safe << description[70..-1] else - safe_message.split(/\n/, 2)[1].try(:chomp) + description.split(/\n/, 2)[1].try(:chomp) end end diff --git a/app/models/commit.rb b/app/models/commit.rb index aba21762126..a070e830680 100644 --- a/app/models/commit.rb +++ b/app/models/commit.rb @@ -107,7 +107,7 @@ class Commit end def safe_message - utf8 message + @safe_message ||= utf8 message end def created_at diff --git a/app/models/key.rb b/app/models/key.rb index 3ef21811c2d..dc1f3cdb9f9 100644 --- a/app/models/key.rb +++ b/app/models/key.rb @@ -14,7 +14,7 @@ class Key < ActiveRecord::Base before_save :set_identifier before_validation :strip_white_space delegate :name, :email, to: :user, prefix: true - validate :unique_key + validate :unique_key, :fingerprintable_key def strip_white_space self.key = self.key.strip unless self.key.blank? @@ -28,6 +28,21 @@ class Key < ActiveRecord::Base end end + def fingerprintable_key + return true unless key # Don't test if there is no key. + # `ssh-keygen -lf /dev/stdin <<< "#{key}"` errors with: redirection unexpected + file = Tempfile.new('key_file') + begin + file.puts key + file.rewind + fingerprint_output = `ssh-keygen -lf #{file.path} 2>&1` # Catch stderr. + ensure + file.close + file.unlink # deletes the temp file + end + errors.add(:key, "can't be fingerprinted") if fingerprint_output.match("failed") + end + def set_identifier if is_deploy_key self.identifier = "deploy_#{Digest::MD5.hexdigest(key)}" diff --git a/app/views/commits/_head.html.haml b/app/views/commits/_head.html.haml index 26ae32ed144..c001c2f70ce 100644 --- a/app/views/commits/_head.html.haml +++ b/app/views/commits/_head.html.haml @@ -9,12 +9,12 @@ = nav_link(html_options: {class: branches_tab_class}) do = link_to project_repository_path(@project) do Branches - %span.badge= @project.repo.branch_count + %span.badge= @project.branches.length = nav_link(controller: :repositories, action: :tags) do = link_to tags_project_repository_path(@project) do Tags - %span.badge= @project.repo.tag_count + %span.badge= @project.tags.length - if current_controller?(:commits) && current_user.private_token %li.right diff --git a/doc/api/README.md b/doc/api/README.md index 36a36f8f6a4..19b7ff20bf3 100644 --- a/doc/api/README.md +++ b/doc/api/README.md @@ -1,6 +1,6 @@ # GitLab API -All API requests require authentication. You need to pass a `private_token` parameter to authenticate. You can find or reset your private token in your profile. +All API requests require authentication. You need to pass a `private_token` parameter by url or header. You can find or reset your private token in your profile. If no, or an invalid, `private_token` is provided then an error message will be returned with status code 401: diff --git a/features/steps/profile/profile_ssh_keys.rb b/features/steps/profile/profile_ssh_keys.rb index 96df2d7342f..535c3862860 100644 --- a/features/steps/profile/profile_ssh_keys.rb +++ b/features/steps/profile/profile_ssh_keys.rb @@ -13,7 +13,7 @@ class ProfileSshKeys < Spinach::FeatureSteps And 'I submit new ssh key "Laptop"' do fill_in "key_title", :with => "Laptop" - fill_in "key_key", :with => "ssh-rsa publickey234=" + fill_in "key_key", :with => "ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAzrEJUIR6Y03TCE9rIJ+GqTBvgb8t1jI9h5UBzCLuK4VawOmkLornPqLDrGbm6tcwM/wBrrLvVOqi2HwmkKEIecVO0a64A4rIYScVsXIniHRS6w5twyn1MD3sIbN+socBDcaldECQa2u1dI3tnNVcs8wi77fiRe7RSxePsJceGoheRQgC8AZ510UdIlO+9rjIHUdVN7LLyz512auAfYsgx1OfablkQ/XJcdEwDNgi9imI6nAXhmoKUm1IPLT2yKajTIC64AjLOnE0YyCh6+7RFMpiMyu1qiOCpdjYwTgBRiciNRZCH8xIedyCoAmiUgkUT40XYHwLuwiPJICpkAzp7Q== user@laptop" click_button "Save" end diff --git a/lib/api/helpers.rb b/lib/api/helpers.rb index e9fec8b3a92..a339ec4a6fc 100644 --- a/lib/api/helpers.rb +++ b/lib/api/helpers.rb @@ -1,7 +1,7 @@ module Gitlab module APIHelpers def current_user - @current_user ||= User.find_by_authentication_token(params[:private_token] || header["private_token"]) + @current_user ||= User.find_by_authentication_token(params[:private_token] || env["HTTP_PRIVATE_TOKEN"]) end def user_project diff --git a/spec/factories.rb b/spec/factories.rb index 82d73fec5ca..cb3541cc7f2 100644 --- a/spec/factories.rb +++ b/spec/factories.rb @@ -95,11 +95,7 @@ FactoryGirl.define do factory :key do title key do - """ - ssh-rsa AAAAB3NzaC1yc2EAAAABJQAAAIEAiPWx6WM4lhHNedGfBpPJNPpZ7yKu+dnn1SJejgt4 - 596k6YjzGGphH2TUxwKzxcKDKKezwkpfnxPkSMkuEspGRt/aZZ9wa++Oi7Qkr8prgHc4 - soW6NUlfDzpvZK2H5E7eQaSeP3SAwGmQKUFHCddNaP0L+hM7zhFNzjFvpaMgJw0= - """ + "ssh-rsa AAAAB3NzaC1yc2EAAAABJQAAAIEAiPWx6WM4lhHNedGfBpPJNPpZ7yKu+dnn1SJejgt4596k6YjzGGphH2TUxwKzxcKDKKezwkpfnxPkSMkuEspGRt/aZZ9wa++Oi7Qkr8prgHc4soW6NUlfDzpvZK2H5E7eQaSeP3SAwGmQKUFHCddNaP0L+hM7zhFNzjFvpaMgJw0=" end factory :deploy_key do @@ -109,6 +105,12 @@ FactoryGirl.define do factory :personal_key do user end + + factory :key_with_a_space_in_the_middle do + key do + "ssh-rsa AAAAB3NzaC1yc2EAAAABJQAAAIEAiPWx6WM4lhHNedGfBpPJNPpZ7yKu+dnn1SJejgt4596k6YjzGGphH2TUxwKzxcKDKKezwkpfnxPkSMkuEspGRt/aZZ9wa ++Oi7Qkr8prgHc4soW6NUlfDzpvZK2H5E7eQaSeP3SAwGmQKUFHCddNaP0L+hM7zhFNzjFvpaMgJw0=" + end + end end factory :milestone do diff --git a/spec/factories_spec.rb b/spec/factories_spec.rb index 5ccc17bddc9..5ee7354688a 100644 --- a/spec/factories_spec.rb +++ b/spec/factories_spec.rb @@ -1,6 +1,9 @@ require 'spec_helper' +INVALID_FACTORIES = [:key_with_a_space_in_the_middle] + FactoryGirl.factories.map(&:name).each do |factory_name| + next if INVALID_FACTORIES.include?(factory_name) describe "#{factory_name} factory" do it 'should be valid' do build(factory_name).should be_valid diff --git a/spec/models/commit_spec.rb b/spec/models/commit_spec.rb new file mode 100644 index 00000000000..e4bc1936839 --- /dev/null +++ b/spec/models/commit_spec.rb @@ -0,0 +1,37 @@ +require 'spec_helper' + +describe Commit do + let(:commit) { create(:project).commit } + + describe CommitDecorator do + let(:decorator) { CommitDecorator.new(commit) } + + describe '#title' do + it "returns no_commit_message when safe_message is blank" do + decorator.stub(:safe_message).and_return('') + decorator.title.should == "--no commit message" + end + + it "truncates a message without a newline at 70 characters" do + message = commit.safe_message * 10 + + decorator.stub(:safe_message).and_return(message) + decorator.title.should == "#{message[0..69]}…" + end + + it "truncates a message with a newline before 80 characters at the newline" do + message = commit.safe_message.split(" ").first + + decorator.stub(:safe_message).and_return(message + "\n" + message) + decorator.title.should == message + end + + it "truncates a message with a newline after 80 characters at 70 characters" do + message = (commit.safe_message * 10) + "\n" + + decorator.stub(:safe_message).and_return(message) + decorator.title.should == "#{message[0..69]}…" + end + end + end +end diff --git a/spec/models/key_spec.rb b/spec/models/key_spec.rb index 3ccfdf034de..169bd890c3d 100644 --- a/spec/models/key_spec.rb +++ b/spec/models/key_spec.rb @@ -51,4 +51,16 @@ describe Key do end end end + + context "validate it is a fingerprintable key" do + let(:user) { Factory.create(:user) } + + it "accepts the fingerprintable key" do + build(:key, user: user).should be_valid + end + + it "rejects the unfingerprintable key" do + build(:key_with_a_space_in_the_middle).should_not be_valid + end + end end diff --git a/spec/requests/projects_deploy_keys_spec.rb b/spec/requests/projects_deploy_keys_spec.rb index 894aa6d3a8d..df1be79d2f5 100644 --- a/spec/requests/projects_deploy_keys_spec.rb +++ b/spec/requests/projects_deploy_keys_spec.rb @@ -42,7 +42,7 @@ describe "Projects", "DeployKeys" do describe "fill in" do before do fill_in "key_title", with: "laptop" - fill_in "key_key", with: "ssh-rsa publickey234=" + fill_in "key_key", with: "ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAzrEJUIR6Y03TCE9rIJ+GqTBvgb8t1jI9h5UBzCLuK4VawOmkLornPqLDrGbm6tcwM/wBrrLvVOqi2HwmkKEIecVO0a64A4rIYScVsXIniHRS6w5twyn1MD3sIbN+socBDcaldECQa2u1dI3tnNVcs8wi77fiRe7RSxePsJceGoheRQgC8AZ510UdIlO+9rjIHUdVN7LLyz512auAfYsgx1OfablkQ/XJcdEwDNgi9imI6nAXhmoKUm1IPLT2yKajTIC64AjLOnE0YyCh6+7RFMpiMyu1qiOCpdjYwTgBRiciNRZCH8xIedyCoAmiUgkUT40XYHwLuwiPJICpkAzp7Q== user@laptop" end it { expect { click_button "Save" }.to change {Key.count}.by(1) } |
