mirror of
https://github.com/wahyd4/gitlabhq.git
synced 2026-08-13 22:59:19 +10:00
Merge branch 'upstream-ce' into 'master'
Pull 7.1.0.pre from Community Edition See merge request !126
This commit is contained in:
@@ -7,6 +7,19 @@ v 7.1.0
|
||||
- Add @all mention for comments
|
||||
- Dont show reply button if user is not signed in
|
||||
- Expose more information for issues with webhook
|
||||
- Add a mention of the merge request into the default merge request commit message
|
||||
- Imrpove code highlight, introduce support for more languages like Go, Clojure, Erlang etc
|
||||
- Fix concurrency issue in repository download
|
||||
- Dont allow repository name start with ?
|
||||
- Improve email threading (Pierre de La Morinerie)
|
||||
- Cleaner help page
|
||||
- Group milestones
|
||||
- Improved email notifications
|
||||
- Contributors API (sponsored by Mobbr)
|
||||
- Fix LDAP TLS authentication (Boris HUISGEN)
|
||||
- Show VERSION information on project sidebar
|
||||
- Improve branch removal logic when accept MR
|
||||
- Fix bug where comment form is spawned inside the Reply button
|
||||
|
||||
v 7.0.0
|
||||
- The CPU no longer overheats when you hold down the spacebar
|
||||
|
||||
+1
-1
@@ -42,7 +42,7 @@ Please send a merge request with a tested solution or a merge request with a fai
|
||||
1. **Observed behavior**
|
||||
1. **Relevant logs and/or screenshots:** Please use code blocks (\`\`\`) to format console output, logs, and code as it's very hard to read otherwise.
|
||||
1. **Output of checks**
|
||||
* Results of GitLab [Application Check](doc/install/installation.md#check-application-status) (`sudo -u git -H bundle exec rake gitlab:check RAILS_ENV=production`); we will only investigate if the tests are passing
|
||||
* Results of GitLab [Application Check](doc/install/installation.md#check-application-status) (`sudo -u git -H bundle exec rake gitlab:check RAILS_ENV=production SANITIZE=true`); we will only investigate if the tests are passing
|
||||
* Version of GitLab you are running; we will only investigate issues in the latest stable and development releases as per the [maintenance policy](MAINTENANCE.md)
|
||||
* Add the last commit sha1 of the GitLab version you used to replicate the issue (obtainable from the help page)
|
||||
* Describe your setup (use relevant parts from `sudo -u git -H bundle exec rake gitlab:env:info RAILS_ENV=production`)
|
||||
|
||||
@@ -10,8 +10,6 @@ end
|
||||
|
||||
gem "rails", "~> 4.1.0"
|
||||
|
||||
gem "protected_attributes"
|
||||
|
||||
# Make links from text
|
||||
gem 'rails_autolink', '~> 1.1'
|
||||
|
||||
@@ -23,8 +21,8 @@ gem "mysql2", group: :mysql
|
||||
gem "pg", group: :postgres
|
||||
|
||||
# Auth
|
||||
gem "devise", '3.0.4'
|
||||
gem "devise-async", '0.8.0'
|
||||
gem "devise", '3.2.4'
|
||||
gem "devise-async", '0.9.0'
|
||||
gem 'omniauth', "~> 1.1.3"
|
||||
gem 'omniauth-google-oauth2'
|
||||
gem 'omniauth-twitter'
|
||||
@@ -49,7 +47,6 @@ gem "gitlab-linguist", "~> 3.0.0", require: "linguist"
|
||||
|
||||
# API
|
||||
gem "grape", "~> 0.6.1"
|
||||
# Replace with rubygems when nesteted entities get released
|
||||
gem "grape-entity", "~> 0.4.2"
|
||||
gem 'rack-cors', require: 'rack/cors'
|
||||
|
||||
|
||||
+10
-12
@@ -40,7 +40,7 @@ GEM
|
||||
axiom-types (0.0.5)
|
||||
descendants_tracker (~> 0.0.1)
|
||||
ice_nine (~> 0.9)
|
||||
bcrypt-ruby (3.1.2)
|
||||
bcrypt (3.1.7)
|
||||
better_errors (1.0.1)
|
||||
coderay (>= 1.0.0)
|
||||
erubis (>= 2.6.6)
|
||||
@@ -94,13 +94,14 @@ GEM
|
||||
default_value_for (3.0.0)
|
||||
activerecord (>= 3.2.0, < 5.0)
|
||||
descendants_tracker (0.0.3)
|
||||
devise (3.0.4)
|
||||
bcrypt-ruby (~> 3.0)
|
||||
devise (3.2.4)
|
||||
bcrypt (~> 3.0)
|
||||
orm_adapter (~> 0.1)
|
||||
railties (>= 3.2.6, < 5)
|
||||
thread_safe (~> 0.1)
|
||||
warden (~> 1.2.3)
|
||||
devise-async (0.8.0)
|
||||
devise (>= 2.2, < 3.2)
|
||||
devise-async (0.9.0)
|
||||
devise (~> 3.2)
|
||||
diff-lcs (1.2.5)
|
||||
diffy (3.0.3)
|
||||
docile (1.1.1)
|
||||
@@ -175,7 +176,7 @@ GEM
|
||||
mime-types (~> 1.19)
|
||||
gitlab_emoji (0.0.1.1)
|
||||
emoji (~> 1.0.1)
|
||||
gitlab_git (6.0.0)
|
||||
gitlab_git (6.0.1)
|
||||
activesupport (~> 4.0)
|
||||
charlock_holmes (~> 0.6)
|
||||
gitlab-grit (~> 2.6)
|
||||
@@ -282,7 +283,7 @@ GEM
|
||||
method_source (0.8.2)
|
||||
mime-types (1.25.1)
|
||||
mini_portile (0.6.0)
|
||||
minitest (5.3.4)
|
||||
minitest (5.3.5)
|
||||
multi_json (1.10.1)
|
||||
multi_xml (0.5.5)
|
||||
multipart-post (1.2.0)
|
||||
@@ -331,8 +332,6 @@ GEM
|
||||
websocket-driver (>= 0.2.0)
|
||||
polyglot (0.3.4)
|
||||
posix-spawn (0.3.8)
|
||||
protected_attributes (1.0.5)
|
||||
activemodel (>= 4.0.1, < 5.0)
|
||||
pry (0.9.12.4)
|
||||
coderay (~> 1.0)
|
||||
method_source (~> 0.8)
|
||||
@@ -586,8 +585,8 @@ DEPENDENCIES
|
||||
d3_rails (~> 3.1.4)
|
||||
database_cleaner
|
||||
default_value_for (~> 3.0.0)
|
||||
devise (= 3.0.4)
|
||||
devise-async (= 0.8.0)
|
||||
devise (= 3.2.4)
|
||||
devise-async (= 0.9.0)
|
||||
diffy (~> 3.0.3)
|
||||
dropzonejs-rails
|
||||
email_spec
|
||||
@@ -636,7 +635,6 @@ DEPENDENCIES
|
||||
org-ruby
|
||||
pg
|
||||
poltergeist (~> 1.5.1)
|
||||
protected_attributes
|
||||
pry
|
||||
quiet_assets (~> 1.0.1)
|
||||
rack-attack
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
#= require g.raphael-min
|
||||
#= require g.bar-min
|
||||
#= require branch-graph
|
||||
#= require highlightjs.min
|
||||
#= require highlight.pack
|
||||
#= require ace/ace
|
||||
#= require d3
|
||||
#= require underscore
|
||||
|
||||
@@ -4,4 +4,4 @@ Array.prototype.first = function() {
|
||||
|
||||
Array.prototype.last = function() {
|
||||
return this[this.length-1];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,4 +14,4 @@ $ ->
|
||||
$('.js-group-avatar-input').bind "change", ->
|
||||
form = $(this).closest("form")
|
||||
filename = $(this).val().replace(/^.*[\\\/]/, '')
|
||||
form.find(".js-avatar-filename").text(filename)
|
||||
form.find(".js-avatar-filename").text(filename)
|
||||
|
||||
@@ -182,4 +182,4 @@ $(document).ready ->
|
||||
$(".div-dropzone").click()
|
||||
return
|
||||
|
||||
return
|
||||
return
|
||||
|
||||
@@ -376,7 +376,7 @@ class Notes
|
||||
###
|
||||
replyToDiscussionNote: (e) =>
|
||||
form = $(".js-new-note-form")
|
||||
replyLink = $(e.target)
|
||||
replyLink = $(e.target).closest(".js-discussion-reply-button")
|
||||
replyLink.hide()
|
||||
|
||||
# insert the form after the button
|
||||
|
||||
@@ -27,4 +27,4 @@ $ ->
|
||||
filename = $(this).val().replace(/^.*[\\\/]/, '')
|
||||
form.find(".js-avatar-filename").text(filename)
|
||||
|
||||
$('.profile-groups-avatars').tooltip("placement": "top")
|
||||
$('.profile-groups-avatars').tooltip("placement": "top")
|
||||
|
||||
@@ -152,16 +152,16 @@
|
||||
}
|
||||
|
||||
&.btn-close {
|
||||
color: #B94A48;
|
||||
font-weight: bold;
|
||||
color: $bg_danger;
|
||||
border-color: $border_danger;
|
||||
&:hover {
|
||||
color: #B94A48;
|
||||
}
|
||||
}
|
||||
|
||||
&.btn-reopen {
|
||||
color: #468847;
|
||||
font-weight: bold;
|
||||
color: $bg_success;
|
||||
border-color: $border_success;
|
||||
&:hover {
|
||||
color: #468847;
|
||||
}
|
||||
|
||||
@@ -177,10 +177,18 @@ li.commit {
|
||||
|
||||
.commit-row-description {
|
||||
font-size: 14px;
|
||||
border-left: 1px solid #e5e5e5;
|
||||
padding: 0 15px 0 7px;
|
||||
border-left: 1px solid #EEE;
|
||||
padding: 10px 15px;
|
||||
margin: 5px 0 10px 5px;
|
||||
background: #f9f9f9;
|
||||
display: none;
|
||||
|
||||
pre {
|
||||
border: none;
|
||||
background: inherit;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.commit-row-info {
|
||||
|
||||
@@ -7,3 +7,7 @@
|
||||
.member-search-form {
|
||||
float: left;
|
||||
}
|
||||
|
||||
.milestone-row {
|
||||
@include str-truncated(90%);
|
||||
}
|
||||
|
||||
@@ -53,13 +53,9 @@ header {
|
||||
font-size: 18px;
|
||||
|
||||
.app_logo { margin-left: -15px; }
|
||||
|
||||
.title {
|
||||
display: inline-block;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
vertical-align: top;
|
||||
white-space: nowrap;
|
||||
max-width: 70%;
|
||||
@include str-truncated(70%);
|
||||
}
|
||||
|
||||
.navbar-collapse {
|
||||
@@ -130,6 +126,7 @@ header {
|
||||
margin: 0;
|
||||
margin-left: 5px;
|
||||
@include header-font;
|
||||
@include str-truncated(37%);
|
||||
}
|
||||
|
||||
.profile-pic {
|
||||
@@ -254,7 +251,7 @@ header {
|
||||
.search .search-input {
|
||||
width: 300px;
|
||||
&:focus {
|
||||
width: 400px;
|
||||
width: 330px;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -262,7 +259,7 @@ header {
|
||||
.search .search-input {
|
||||
width: 200px;
|
||||
&:focus {
|
||||
width: 300px;
|
||||
width: 230px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
}
|
||||
td {
|
||||
border-color: #F1F1F1 !important;
|
||||
border-bottom: 1px solid;
|
||||
}
|
||||
&:hover {
|
||||
td {
|
||||
|
||||
@@ -6,7 +6,7 @@ class Admin::BroadcastMessagesController < Admin::ApplicationController
|
||||
end
|
||||
|
||||
def create
|
||||
@broadcast_message = BroadcastMessage.new(params[:broadcast_message])
|
||||
@broadcast_message = BroadcastMessage.new(broadcast_message_params)
|
||||
|
||||
if @broadcast_message.save
|
||||
redirect_to admin_broadcast_messages_path, notice: 'Broadcast Message was successfully created.'
|
||||
@@ -29,4 +29,11 @@ class Admin::BroadcastMessagesController < Admin::ApplicationController
|
||||
def broadcast_messages
|
||||
@broadcast_messages ||= BroadcastMessage.order("starts_at DESC").page(params[:page])
|
||||
end
|
||||
|
||||
def broadcast_message_params
|
||||
params.require(:broadcast_message).permit(
|
||||
:alert_type, :color, :ends_at, :font,
|
||||
:message, :starts_at
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -20,7 +20,7 @@ class Admin::GroupsController < Admin::ApplicationController
|
||||
end
|
||||
|
||||
def create
|
||||
@group = Group.new(params[:group])
|
||||
@group = Group.new(group_params)
|
||||
@group.path = @group.name.dup.parameterize if @group.name
|
||||
|
||||
if @group.save
|
||||
@@ -32,7 +32,7 @@ class Admin::GroupsController < Admin::ApplicationController
|
||||
end
|
||||
|
||||
def update
|
||||
if @group.update_attributes(params[:group])
|
||||
if @group.update_attributes(group_params)
|
||||
redirect_to [:admin, @group], notice: 'Group was successfully updated.'
|
||||
else
|
||||
render "edit"
|
||||
@@ -56,4 +56,8 @@ class Admin::GroupsController < Admin::ApplicationController
|
||||
def group
|
||||
@group = Group.find_by(path: params[:id])
|
||||
end
|
||||
|
||||
def group_params
|
||||
params.require(:group).permit(:name, :description, :path, :avatar)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -5,7 +5,7 @@ class Admin::HooksController < Admin::ApplicationController
|
||||
end
|
||||
|
||||
def create
|
||||
@hook = SystemHook.new(params[:hook])
|
||||
@hook = SystemHook.new(hook_params)
|
||||
|
||||
if @hook.save
|
||||
redirect_to admin_hooks_path, notice: 'Hook was successfully created.'
|
||||
@@ -37,4 +37,8 @@ class Admin::HooksController < Admin::ApplicationController
|
||||
|
||||
redirect_to :back
|
||||
end
|
||||
|
||||
def hook_params
|
||||
params.require(:hook).permit(:url)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -13,7 +13,7 @@ class Admin::UsersController < Admin::ApplicationController
|
||||
end
|
||||
|
||||
def new
|
||||
@user = User.build_user
|
||||
@user = User.new
|
||||
end
|
||||
|
||||
def edit
|
||||
@@ -37,15 +37,12 @@ class Admin::UsersController < Admin::ApplicationController
|
||||
end
|
||||
|
||||
def create
|
||||
admin = params[:user].delete("admin")
|
||||
|
||||
opts = {
|
||||
force_random_password: true,
|
||||
password_expires_at: Time.now
|
||||
}
|
||||
|
||||
@user = User.build_user(params[:user].merge(opts), as: :admin)
|
||||
@user.admin = (admin && admin.to_i > 0)
|
||||
@user = User.new(user_params.merge(opts))
|
||||
@user.created_by_id = current_user.id
|
||||
@user.generate_password
|
||||
@user.skip_confirmation!
|
||||
@@ -62,19 +59,15 @@ class Admin::UsersController < Admin::ApplicationController
|
||||
end
|
||||
|
||||
def update
|
||||
admin = params[:user].delete("admin")
|
||||
|
||||
if params[:user][:password].blank?
|
||||
params[:user].delete(:password)
|
||||
params[:user].delete(:password_confirmation)
|
||||
end
|
||||
|
||||
if admin.present?
|
||||
user.admin = !admin.to_i.zero?
|
||||
if params[:user][:password].present?
|
||||
user_params.merge(
|
||||
password: params[:user][:password],
|
||||
password_confirmation: params[:user][:password_confirmation],
|
||||
)
|
||||
end
|
||||
|
||||
respond_to do |format|
|
||||
if user.update_attributes(params[:user], as: :admin)
|
||||
if user.update_attributes(user_params)
|
||||
user.confirm!
|
||||
format.html { redirect_to [:admin, user], notice: 'User was successfully updated.' }
|
||||
format.json { head :ok }
|
||||
@@ -115,4 +108,13 @@ class Admin::UsersController < Admin::ApplicationController
|
||||
def user
|
||||
@user ||= User.find_by!(username: params[:id])
|
||||
end
|
||||
|
||||
def user_params
|
||||
params.require(:user).permit(
|
||||
:email, :remember_me, :bio, :name, :username,
|
||||
:skype, :linkedin, :twitter, :website_url, :color_scheme_id, :theme_id, :force_random_password,
|
||||
:extern_uid, :provider, :password_expires_at, :avatar, :hide_no_ssh_key,
|
||||
:projects_limit, :can_create_group, :admin
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
require 'gon'
|
||||
|
||||
class ApplicationController < ActionController::Base
|
||||
before_filter :authenticate_user_from_token!
|
||||
before_filter :authenticate_user!
|
||||
before_filter :reject_blocked!
|
||||
before_filter :check_password_expiration
|
||||
@@ -28,6 +29,25 @@ class ApplicationController < ActionController::Base
|
||||
|
||||
protected
|
||||
|
||||
# From https://github.com/plataformatec/devise/wiki/How-To:-Simple-Token-Authentication-Example
|
||||
# https://gist.github.com/josevalim/fb706b1e933ef01e4fb6
|
||||
def authenticate_user_from_token!
|
||||
user_token = if params[:authenticity_token].presence
|
||||
params[:authenticity_token].presence
|
||||
elsif params[:private_token].presence
|
||||
params[:private_token].presence
|
||||
end
|
||||
user = user_token && User.find_by_authentication_token(user_token.to_s)
|
||||
|
||||
if user
|
||||
# Notice we are passing store false, so the user is not
|
||||
# actually stored in the session and a token is needed
|
||||
# for every request. If you want the token to work as a
|
||||
# sign in token, you can simply remove store: false.
|
||||
sign_in user, store: false
|
||||
end
|
||||
end
|
||||
|
||||
def log_exception(exception)
|
||||
application_trace = ActionDispatch::ExceptionWrapper.new(env, exception).application_trace
|
||||
application_trace.map!{ |t| " #{t}\n" }
|
||||
@@ -227,8 +247,7 @@ class ApplicationController < ActionController::Base
|
||||
end
|
||||
|
||||
def configure_permitted_parameters
|
||||
devise_parameter_sanitizer.for(:sign_in) { |u| u.permit(:username, :email, :password, :login, :remember_me) }
|
||||
devise_parameter_sanitizer.for(:sign_up) { |u| u.permit(:username, :email, :name, :password, :password_confirmation) }
|
||||
devise_parameter_sanitizer.sanitize(:sign_in) { |u| u.permit(:username, :email, :password, :login, :remember_me) }
|
||||
end
|
||||
|
||||
def hexdigest(string)
|
||||
|
||||
@@ -0,0 +1,56 @@
|
||||
class Groups::MilestonesController < ApplicationController
|
||||
layout 'group'
|
||||
|
||||
before_filter :authorize_group_milestone!, only: :update
|
||||
|
||||
def index
|
||||
project_milestones = case params[:status]
|
||||
when 'all'; status
|
||||
when 'closed'; status('closed')
|
||||
else status('active')
|
||||
end
|
||||
@group_milestones = Milestones::GroupService.new(project_milestones).execute
|
||||
@group_milestones = Kaminari.paginate_array(@group_milestones).page(params[:page]).per(30)
|
||||
end
|
||||
|
||||
def show
|
||||
project_milestones = Milestone.where(project_id: group.projects).order("due_date ASC")
|
||||
@group_milestone = Milestones::GroupService.new(project_milestones).milestone(title)
|
||||
end
|
||||
|
||||
def update
|
||||
project_milestones = Milestone.where(project_id: group.projects).order("due_date ASC")
|
||||
@group_milestones = Milestones::GroupService.new(project_milestones).milestone(title)
|
||||
|
||||
@group_milestones.milestones.each do |milestone|
|
||||
Milestones::UpdateService.new(milestone.project, current_user, params[:milestone]).execute(milestone)
|
||||
end
|
||||
|
||||
respond_to do |format|
|
||||
format.js
|
||||
format.html do
|
||||
redirect_to group_milestones_path(group)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def group
|
||||
@group ||= Group.find_by(path: params[:group_id])
|
||||
end
|
||||
|
||||
def title
|
||||
params[:title]
|
||||
end
|
||||
|
||||
def status(state = nil)
|
||||
conditions = { project_id: group.projects }
|
||||
conditions.reverse_merge!(state: state) if state
|
||||
Milestone.where(conditions).order("title ASC")
|
||||
end
|
||||
|
||||
def authorize_group_milestone!
|
||||
return render_404 unless can?(current_user, :manage_group, group)
|
||||
end
|
||||
end
|
||||
@@ -22,7 +22,7 @@ class GroupsController < ApplicationController
|
||||
end
|
||||
|
||||
def create
|
||||
@group = Group.new(params[:group])
|
||||
@group = Group.new(group_params)
|
||||
@group.path = @group.name.dup.parameterize if @group.name
|
||||
|
||||
if @group.save
|
||||
@@ -86,7 +86,7 @@ class GroupsController < ApplicationController
|
||||
end
|
||||
|
||||
def update
|
||||
if @group.update_attributes(params[:group])
|
||||
if @group.update_attributes(group_params)
|
||||
redirect_to edit_group_path(@group), notice: 'Group was successfully updated.'
|
||||
else
|
||||
render action: "edit"
|
||||
@@ -161,4 +161,8 @@ class GroupsController < ApplicationController
|
||||
params[:state] = 'opened' if params[:state].blank?
|
||||
params[:group_id] = @group.id
|
||||
end
|
||||
|
||||
def group_params
|
||||
params.require(:group).permit(:name, :description, :path, :avatar, :ldap_access, :ldap_cn)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -7,7 +7,7 @@ class Profiles::EmailsController < ApplicationController
|
||||
end
|
||||
|
||||
def create
|
||||
@email = current_user.emails.new(params[:email])
|
||||
@email = current_user.emails.new(email_params)
|
||||
|
||||
flash[:alert] = @email.errors.full_messages.first unless @email.save
|
||||
|
||||
@@ -23,4 +23,10 @@ class Profiles::EmailsController < ApplicationController
|
||||
format.js { render nothing: true }
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def email_params
|
||||
params.require(:email).permit(:email)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -15,7 +15,7 @@ class Profiles::KeysController < ApplicationController
|
||||
end
|
||||
|
||||
def create
|
||||
@key = current_user.keys.new(params[:key])
|
||||
@key = current_user.keys.new(key_params)
|
||||
|
||||
if @key.save
|
||||
redirect_to profile_key_path(@key)
|
||||
@@ -53,4 +53,9 @@ class Profiles::KeysController < ApplicationController
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def key_params
|
||||
params.require(:key).permit(:title, :key)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -11,8 +11,8 @@ class Profiles::PasswordsController < ApplicationController
|
||||
end
|
||||
|
||||
def create
|
||||
new_password = params[:user][:password]
|
||||
new_password_confirmation = params[:user][:password_confirmation]
|
||||
new_password = user_params[:password]
|
||||
new_password_confirmation = user_params[:password_confirmation]
|
||||
|
||||
result = @user.update_attributes(
|
||||
password: new_password,
|
||||
@@ -31,11 +31,11 @@ class Profiles::PasswordsController < ApplicationController
|
||||
end
|
||||
|
||||
def update
|
||||
password_attributes = params[:user].select do |key, value|
|
||||
password_attributes = user_params.select do |key, value|
|
||||
%w(password password_confirmation).include?(key.to_s)
|
||||
end
|
||||
|
||||
unless @user.valid_password?(params[:user][:current_password])
|
||||
unless @user.valid_password?(user_params[:current_password])
|
||||
redirect_to edit_profile_password_path, alert: 'You must provide a valid current password'
|
||||
return
|
||||
end
|
||||
@@ -74,4 +74,8 @@ class Profiles::PasswordsController < ApplicationController
|
||||
def authorize_change_password!
|
||||
return render_404 if @user.ldap_user?
|
||||
end
|
||||
|
||||
def user_params
|
||||
params.require(:user).permit(:current_password, :password, :password_confirmation)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -14,9 +14,9 @@ class ProfilesController < ApplicationController
|
||||
end
|
||||
|
||||
def update
|
||||
params[:user].delete(:email) if @user.ldap_user?
|
||||
user_params.except!(:email) if @user.ldap_user?
|
||||
|
||||
if @user.update_attributes(params[:user])
|
||||
if @user.update_attributes(user_params)
|
||||
flash[:notice] = "Profile was successfully updated"
|
||||
else
|
||||
flash[:alert] = "Failed to update profile"
|
||||
@@ -41,7 +41,7 @@ class ProfilesController < ApplicationController
|
||||
end
|
||||
|
||||
def update_username
|
||||
@user.update_attributes(username: params[:user][:username])
|
||||
@user.update_attributes(username: user_params[:username])
|
||||
|
||||
respond_to do |format|
|
||||
format.js
|
||||
@@ -57,4 +57,12 @@ class ProfilesController < ApplicationController
|
||||
def authorize_change_username!
|
||||
return render_404 unless @user.can_change_username?
|
||||
end
|
||||
|
||||
def user_params
|
||||
params.require(:user).permit(
|
||||
:email, :password, :password_confirmation, :bio, :name, :username,
|
||||
:skype, :linkedin, :twitter, :website_url, :color_scheme_id, :theme_id,
|
||||
:avatar, :hide_no_ssh_key,
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -30,8 +30,12 @@ class Projects::BlobController < Projects::ApplicationController
|
||||
def blob
|
||||
@blob ||= @repository.blob_at(@commit.id, @path)
|
||||
|
||||
return not_found! unless @blob
|
||||
|
||||
@blob
|
||||
if @blob
|
||||
@blob
|
||||
elsif tree.entries.any?
|
||||
redirect_to project_tree_path(@project, File.join(@ref, @path)) and return
|
||||
else
|
||||
return not_found!
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -22,7 +22,7 @@ class Projects::DeployKeysController < Projects::ApplicationController
|
||||
end
|
||||
|
||||
def create
|
||||
@key = DeployKey.new(params[:deploy_key])
|
||||
@key = DeployKey.new(deploy_key_params)
|
||||
|
||||
if @key.valid? && @project.deploy_keys << @key
|
||||
redirect_to project_deploy_keys_path(@project)
|
||||
@@ -58,4 +58,8 @@ class Projects::DeployKeysController < Projects::ApplicationController
|
||||
def available_keys
|
||||
@available_keys ||= current_user.accessible_deploy_keys
|
||||
end
|
||||
|
||||
def deploy_key_params
|
||||
params.require(:deploy_key).permit(:key, :title)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -28,8 +28,6 @@ class Projects::EditTreeController < Projects::BaseTreeController
|
||||
|
||||
def preview
|
||||
@content = params[:content]
|
||||
#FIXME workaround https://github.com/gitlabhq/gitlabhq/issues/5936
|
||||
@content += "\n" if @blob.data.end_with?("\n")
|
||||
|
||||
diffy = Diffy::Diff.new(@blob.data, @content, diff: '-U 3',
|
||||
include_diff_info: true)
|
||||
|
||||
@@ -14,7 +14,7 @@ class Projects::GitHooksController < Projects::ApplicationController
|
||||
|
||||
def update
|
||||
@pre_receive_hook = project.git_hook
|
||||
@pre_receive_hook.update_attributes(params[:git_hook])
|
||||
@pre_receive_hook.update_attributes(git_hook_params)
|
||||
|
||||
if @pre_receive_hook.valid?
|
||||
redirect_to project_git_hooks_path(@project)
|
||||
@@ -22,4 +22,11 @@ class Projects::GitHooksController < Projects::ApplicationController
|
||||
render :index
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
# Only allow a trusted parameter "white list" through.
|
||||
def git_hook_params
|
||||
params.require(:git_hook).permit(:deny_delete_tag, :delete_branch_regex, :commit_message_regex, :force_push_regex)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -12,7 +12,7 @@ class Projects::HooksController < Projects::ApplicationController
|
||||
end
|
||||
|
||||
def create
|
||||
@hook = @project.hooks.new(params[:hook])
|
||||
@hook = @project.hooks.new(hook_params)
|
||||
@hook.save
|
||||
|
||||
if @hook.valid?
|
||||
@@ -40,4 +40,8 @@ class Projects::HooksController < Projects::ApplicationController
|
||||
def hook
|
||||
@hook ||= @project.hooks.find(params[:id])
|
||||
end
|
||||
|
||||
def hook_params
|
||||
params.require(:hook).permit(:url, :push_events, :issues_events, :merge_requests_events, :tag_push_events)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -42,7 +42,11 @@ class Projects::IssuesController < Projects::ApplicationController
|
||||
end
|
||||
|
||||
def new
|
||||
@issue = @project.issues.new(params[:issue])
|
||||
params[:issue] ||= ActionController::Parameters.new(
|
||||
assignee_id: ""
|
||||
)
|
||||
|
||||
@issue = @project.issues.new(issue_params)
|
||||
respond_with(@issue)
|
||||
end
|
||||
|
||||
@@ -59,7 +63,7 @@ class Projects::IssuesController < Projects::ApplicationController
|
||||
end
|
||||
|
||||
def create
|
||||
@issue = Issues::CreateService.new(project, current_user, params[:issue]).execute
|
||||
@issue = Issues::CreateService.new(project, current_user, issue_params).execute
|
||||
|
||||
respond_to do |format|
|
||||
format.html do
|
||||
@@ -76,7 +80,7 @@ class Projects::IssuesController < Projects::ApplicationController
|
||||
end
|
||||
|
||||
def update
|
||||
@issue = Issues::UpdateService.new(project, current_user, params[:issue]).execute(issue)
|
||||
@issue = Issues::UpdateService.new(project, current_user, issue_params).execute(issue)
|
||||
|
||||
respond_to do |format|
|
||||
format.js
|
||||
@@ -144,4 +148,11 @@ class Projects::IssuesController < Projects::ApplicationController
|
||||
raise ActiveRecord::RecordNotFound.new
|
||||
end
|
||||
end
|
||||
|
||||
def issue_params
|
||||
params.require(:issue).permit(
|
||||
:title, :assignee_id, :position, :description,
|
||||
:milestone_id, :label_list, :state_event
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -60,7 +60,11 @@ class Projects::MergeRequestsController < Projects::ApplicationController
|
||||
end
|
||||
|
||||
def new
|
||||
@merge_request = MergeRequest.new(params[:merge_request])
|
||||
params[:merge_request] ||= ActionController::Parameters.new(
|
||||
source_project: @project
|
||||
)
|
||||
|
||||
@merge_request = MergeRequest.new(merge_request_params)
|
||||
@merge_request.source_project = @project unless @merge_request.source_project
|
||||
@merge_request.target_project ||= (@project.forked_from_project || @project)
|
||||
@target_branches = @merge_request.target_project.nil? ? [] : @merge_request.target_project.repository.branch_names
|
||||
@@ -111,7 +115,7 @@ class Projects::MergeRequestsController < Projects::ApplicationController
|
||||
|
||||
def create
|
||||
@target_branches ||= []
|
||||
@merge_request = MergeRequests::CreateService.new(project, current_user, params[:merge_request]).execute
|
||||
@merge_request = MergeRequests::CreateService.new(project, current_user, merge_request_params).execute
|
||||
|
||||
if @merge_request.valid?
|
||||
redirect_to project_merge_request_path(@merge_request.target_project, @merge_request), notice: 'Merge request was successfully created.'
|
||||
@@ -123,7 +127,7 @@ class Projects::MergeRequestsController < Projects::ApplicationController
|
||||
end
|
||||
|
||||
def update
|
||||
@merge_request = MergeRequests::UpdateService.new(project, current_user, params[:merge_request]).execute(@merge_request)
|
||||
@merge_request = MergeRequests::UpdateService.new(project, current_user, merge_request_params).execute(@merge_request)
|
||||
|
||||
if @merge_request.valid?
|
||||
respond_to do |format|
|
||||
@@ -264,4 +268,12 @@ class Projects::MergeRequestsController < Projects::ApplicationController
|
||||
|
||||
can?(current_user, action, project)
|
||||
end
|
||||
|
||||
def merge_request_params
|
||||
params.require(:merge_request).permit(
|
||||
:title, :assignee_id, :source_project_id, :source_branch,
|
||||
:target_project_id, :target_branch, :milestone_id,
|
||||
:state_event, :description, :label_list
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -37,7 +37,7 @@ class Projects::MilestonesController < Projects::ApplicationController
|
||||
end
|
||||
|
||||
def create
|
||||
@milestone = Milestones::CreateService.new(project, current_user, params[:milestone]).execute
|
||||
@milestone = Milestones::CreateService.new(project, current_user, milestone_params).execute
|
||||
|
||||
if @milestone.save
|
||||
redirect_to project_milestone_path(@project, @milestone)
|
||||
@@ -47,7 +47,7 @@ class Projects::MilestonesController < Projects::ApplicationController
|
||||
end
|
||||
|
||||
def update
|
||||
@milestone = Milestones::UpdateService.new(project, current_user, params[:milestone]).execute(milestone)
|
||||
@milestone = Milestones::UpdateService.new(project, current_user, milestone_params).execute(milestone)
|
||||
|
||||
respond_to do |format|
|
||||
format.js
|
||||
@@ -105,4 +105,8 @@ class Projects::MilestonesController < Projects::ApplicationController
|
||||
def module_enabled
|
||||
return render_404 unless @project.issues_enabled
|
||||
end
|
||||
|
||||
def milestone_params
|
||||
params.require(:milestone).permit(:title, :description, :due_date, :state_event)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -21,7 +21,7 @@ class Projects::NotesController < Projects::ApplicationController
|
||||
end
|
||||
|
||||
def create
|
||||
@note = Notes::CreateService.new(project, current_user, params[:note]).execute
|
||||
@note = Notes::CreateService.new(project, current_user, note_params).execute
|
||||
|
||||
respond_to do |format|
|
||||
format.json { render_note_json(@note) }
|
||||
@@ -30,7 +30,7 @@ class Projects::NotesController < Projects::ApplicationController
|
||||
end
|
||||
|
||||
def update
|
||||
note.update_attributes(params[:note])
|
||||
note.update_attributes(note_params)
|
||||
note.reset_events_cache
|
||||
|
||||
respond_to do |format|
|
||||
@@ -109,4 +109,11 @@ class Projects::NotesController < Projects::ApplicationController
|
||||
def authorize_admin_note!
|
||||
return access_denied! unless can?(current_user, :admin_note, note)
|
||||
end
|
||||
|
||||
def note_params
|
||||
params.require(:note).permit(
|
||||
:note, :noteable, :noteable_id, :noteable_type, :project_id,
|
||||
:attachment, :line_code, :commit_id
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -11,7 +11,7 @@ class Projects::ProtectedBranchesController < Projects::ApplicationController
|
||||
end
|
||||
|
||||
def create
|
||||
@project.protected_branches.create(params[:protected_branch])
|
||||
@project.protected_branches.create(protected_branch_params)
|
||||
redirect_to project_protected_branches_path(@project)
|
||||
end
|
||||
|
||||
@@ -23,4 +23,10 @@ class Projects::ProtectedBranchesController < Projects::ApplicationController
|
||||
format.js { render nothing: true }
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def protected_branch_params
|
||||
params.require(:protected_branch).permit(:name)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -22,6 +22,7 @@ class Projects::RepositoriesController < Projects::ApplicationController
|
||||
|
||||
if file_path
|
||||
# Send file to user
|
||||
response.headers["Content-Length"] = File.open(file_path).size.to_s
|
||||
send_file file_path
|
||||
else
|
||||
render_404
|
||||
|
||||
@@ -16,7 +16,7 @@ class Projects::ServicesController < Projects::ApplicationController
|
||||
end
|
||||
|
||||
def update
|
||||
if @service.update_attributes(params[:service])
|
||||
if @service.update_attributes(service_params)
|
||||
redirect_to edit_project_service_path(@project, @service.to_param)
|
||||
else
|
||||
render 'edit'
|
||||
@@ -36,4 +36,11 @@ class Projects::ServicesController < Projects::ApplicationController
|
||||
def service
|
||||
@service ||= @project.services.find { |service| service.to_param == params[:id] }
|
||||
end
|
||||
|
||||
def service_params
|
||||
params.require(:service).permit(
|
||||
:title, :token, :type, :active, :api_key, :subdomain,
|
||||
:room, :recipients, :project_url, :username, :password, :api_version
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -25,7 +25,7 @@ class Projects::SnippetsController < Projects::ApplicationController
|
||||
end
|
||||
|
||||
def create
|
||||
@snippet = @project.snippets.build(params[:project_snippet])
|
||||
@snippet = @project.snippets.build(snippet_params)
|
||||
@snippet.author = current_user
|
||||
|
||||
if @snippet.save
|
||||
@@ -39,7 +39,7 @@ class Projects::SnippetsController < Projects::ApplicationController
|
||||
end
|
||||
|
||||
def update
|
||||
if @snippet.update_attributes(params[:project_snippet])
|
||||
if @snippet.update_attributes(snippet_params)
|
||||
redirect_to project_snippet_path(@project, @snippet)
|
||||
else
|
||||
respond_with(@snippet)
|
||||
@@ -86,4 +86,8 @@ class Projects::SnippetsController < Projects::ApplicationController
|
||||
def module_enabled
|
||||
return render_404 unless @project.snippets_enabled
|
||||
end
|
||||
|
||||
def snippet_params
|
||||
params.require(:project_snippet).permit(:title, :content, :file_name, :private)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -27,7 +27,7 @@ class Projects::TeamMembersController < Projects::ApplicationController
|
||||
|
||||
def update
|
||||
@user_project_relation = project.users_projects.find_by(user_id: member)
|
||||
@user_project_relation.update_attributes(params[:team_member])
|
||||
@user_project_relation.update_attributes(member_params)
|
||||
|
||||
unless @user_project_relation.valid?
|
||||
flash[:alert] = "User should have at least one role"
|
||||
@@ -67,4 +67,8 @@ class Projects::TeamMembersController < Projects::ApplicationController
|
||||
def member
|
||||
@member ||= User.find_by(username: params[:id])
|
||||
end
|
||||
|
||||
def member_params
|
||||
params.require(:team_member).permit(:user_id, :project_access)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,7 +1,14 @@
|
||||
# Controller for viewing a repository's file structure
|
||||
class Projects::TreeController < Projects::BaseTreeController
|
||||
def show
|
||||
return not_found! if tree.entries.empty?
|
||||
|
||||
if tree.entries.empty?
|
||||
if @repository.blob_at(@commit.id, @path)
|
||||
redirect_to project_blob_path(@project, File.join(@ref, @path)) and return
|
||||
else
|
||||
return not_found!
|
||||
end
|
||||
end
|
||||
|
||||
respond_to do |format|
|
||||
format.html
|
||||
|
||||
@@ -20,7 +20,7 @@ class ProjectsController < ApplicationController
|
||||
end
|
||||
|
||||
def create
|
||||
@project = ::Projects::CreateService.new(current_user, params[:project]).execute
|
||||
@project = ::Projects::CreateService.new(current_user, project_params).execute
|
||||
flash[:notice] = 'Project was successfully created.' if @project.saved?
|
||||
|
||||
respond_to do |format|
|
||||
@@ -29,7 +29,7 @@ class ProjectsController < ApplicationController
|
||||
end
|
||||
|
||||
def update
|
||||
status = ::Projects::UpdateService.new(@project, current_user, params).execute
|
||||
status = ::Projects::UpdateService.new(@project, current_user, project_params).execute
|
||||
|
||||
respond_to do |format|
|
||||
if status
|
||||
@@ -44,7 +44,7 @@ class ProjectsController < ApplicationController
|
||||
end
|
||||
|
||||
def transfer
|
||||
::Projects::TransferService.new(project, current_user, params[:project]).execute
|
||||
::Projects::TransferService.new(project, current_user, project_params).execute
|
||||
end
|
||||
|
||||
def show
|
||||
@@ -85,7 +85,7 @@ class ProjectsController < ApplicationController
|
||||
redirect_to import_project_path(@project)
|
||||
end
|
||||
|
||||
@project.import_url = params[:project][:import_url]
|
||||
@project.import_url = project_params[:import_url]
|
||||
|
||||
if @project.save
|
||||
@project.reload
|
||||
@@ -185,4 +185,12 @@ class ProjectsController < ApplicationController
|
||||
def user_layout
|
||||
current_user ? "projects" : "public_projects"
|
||||
end
|
||||
|
||||
def project_params
|
||||
params.require(:project).permit(
|
||||
:name, :path, :description, :issues_tracker, :label_list,
|
||||
:issues_enabled, :merge_requests_enabled, :snippets_enabled, :issues_tracker_id,
|
||||
:wiki_enabled, :visibility_level, :import_url, :last_activity_at, :namespace_id, :merge_requests_template
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -13,7 +13,14 @@ class RegistrationsController < Devise::RegistrationsController
|
||||
|
||||
def build_resource(hash=nil)
|
||||
super
|
||||
self.resource.with_defaults
|
||||
end
|
||||
|
||||
def after_sign_up_path_for resource
|
||||
new_user_session_path
|
||||
end
|
||||
|
||||
def after_inactive_sign_up_path_for resource
|
||||
new_user_session_path
|
||||
end
|
||||
|
||||
private
|
||||
@@ -21,4 +28,8 @@ class RegistrationsController < Devise::RegistrationsController
|
||||
def signup_enabled?
|
||||
redirect_to new_user_session_path unless Gitlab.config.gitlab.signup_enabled
|
||||
end
|
||||
|
||||
def sign_up_params
|
||||
params.require(:user).permit(:username, :email, :name, :password, :password_confirmation)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -51,7 +51,7 @@ class SnippetsController < ApplicationController
|
||||
end
|
||||
|
||||
def create
|
||||
@snippet = PersonalSnippet.new(params[:personal_snippet])
|
||||
@snippet = PersonalSnippet.new(snippet_params)
|
||||
@snippet.author = current_user
|
||||
|
||||
if @snippet.save
|
||||
@@ -65,7 +65,7 @@ class SnippetsController < ApplicationController
|
||||
end
|
||||
|
||||
def update
|
||||
if @snippet.update_attributes(params[:personal_snippet])
|
||||
if @snippet.update_attributes(snippet_params)
|
||||
redirect_to snippet_path(@snippet)
|
||||
else
|
||||
respond_with @snippet
|
||||
@@ -109,4 +109,8 @@ class SnippetsController < ApplicationController
|
||||
def set_title
|
||||
@title = 'Snippets'
|
||||
end
|
||||
|
||||
def snippet_params
|
||||
params.require(:personal_snippet).permit(:title, :content, :file_name, :private)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -14,7 +14,7 @@ class UsersGroupsController < ApplicationController
|
||||
|
||||
def update
|
||||
@member = @group.users_groups.find(params[:id])
|
||||
@member.update_attributes(params[:users_group])
|
||||
@member.update_attributes(member_params)
|
||||
end
|
||||
|
||||
def destroy
|
||||
@@ -41,4 +41,8 @@ class UsersGroupsController < ApplicationController
|
||||
return render_404
|
||||
end
|
||||
end
|
||||
|
||||
def member_params
|
||||
params.require(:users_group).permit(:group_access, :user_id)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -14,7 +14,7 @@ class NotesFinder
|
||||
project.issues.find(target_id).notes.inc_author.fresh
|
||||
when "merge_request"
|
||||
project.merge_requests.find(target_id).mr_and_commit_notes.inc_author.fresh
|
||||
when "snippet"
|
||||
when "snippet", "project_snippet"
|
||||
project.snippets.find(target_id).notes.fresh
|
||||
else
|
||||
raise 'invalid target_type'
|
||||
|
||||
@@ -180,6 +180,17 @@ module CommitsHelper
|
||||
return old_lines, new_lines
|
||||
end
|
||||
|
||||
def link_to_browse_code(project, commit)
|
||||
if current_controller?(:projects, :commits)
|
||||
if @repo.blob_at(commit.id, @path)
|
||||
return link_to "Browse File »", project_blob_path(project, tree_join(commit.id, @path)), class: "pull-right"
|
||||
elsif @path.present?
|
||||
return link_to "Browse Dir »", project_tree_path(project, tree_join(commit.id, @path)), class: "pull-right"
|
||||
end
|
||||
end
|
||||
link_to "Browse Code »", project_tree_path(project, commit), class: "pull-right"
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
# Private: Returns a link to a person. If the person has a matching user and
|
||||
|
||||
@@ -35,4 +35,42 @@ module DashboardHelper
|
||||
path << "?#{options.to_param}"
|
||||
path
|
||||
end
|
||||
|
||||
def assigned_entities_count(current_user, entity, scope = nil)
|
||||
items = current_user.send("assigned_" + entity.pluralize).opened
|
||||
|
||||
if scope.kind_of?(Group)
|
||||
items = items.of_group(scope)
|
||||
elsif scope.kind_of?(Project)
|
||||
items = items.of_projects(scope)
|
||||
end
|
||||
|
||||
items.count
|
||||
end
|
||||
|
||||
def authored_entities_count(current_user, entity, scope = nil)
|
||||
items = current_user.send(entity.pluralize).opened
|
||||
|
||||
if scope.kind_of?(Group)
|
||||
items = items.of_group(scope)
|
||||
elsif scope.kind_of?(Project)
|
||||
items = items.of_projects(scope)
|
||||
end
|
||||
|
||||
items.count
|
||||
end
|
||||
|
||||
def authorized_entities_count(current_user, entity, scope = nil)
|
||||
items = entity.classify.constantize.opened
|
||||
|
||||
if scope.kind_of?(Group)
|
||||
items = items.of_group(scope)
|
||||
elsif scope.kind_of?(Project)
|
||||
items = items.of_projects(scope)
|
||||
else
|
||||
items = items.of_projects(current_user.authorized_projects)
|
||||
end
|
||||
|
||||
items.count
|
||||
end
|
||||
end
|
||||
|
||||
@@ -64,7 +64,16 @@ module EventsHelper
|
||||
project_issue_url(event.project, event.issue)
|
||||
elsif event.merge_request?
|
||||
project_merge_request_url(event.project, event.merge_request)
|
||||
|
||||
elsif event.note?
|
||||
if event.note_target
|
||||
if event.note_commit?
|
||||
project_commit_path(event.project, event.note_commit_id, anchor: dom_id(event.target))
|
||||
elsif event.note_project_snippet?
|
||||
project_snippet_path(event.project, event.note_target)
|
||||
else
|
||||
event_note_target_path(event)
|
||||
end
|
||||
end
|
||||
elsif event.push?
|
||||
if event.push_with_commits?
|
||||
if event.commits_count > 1
|
||||
@@ -83,6 +92,10 @@ module EventsHelper
|
||||
render "events/event_issue", issue: event.issue
|
||||
elsif event.push?
|
||||
render "events/event_push", event: event
|
||||
elsif event.merge_request?
|
||||
render "events/event_merge_request", merge_request: event.merge_request
|
||||
elsif event.note?
|
||||
render "events/event_note", note: event.note
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@@ -138,7 +138,7 @@ module GitlabMarkdownHelper
|
||||
# If we are at doc/api/README.md and the README.md contains relative links like [Users](users.md)
|
||||
# this takes the request path(doc/api/README.md), and replaces the README.md with users.md so the path looks like doc/api/users.md
|
||||
# If we are at doc/api and the README.md shown in below the tree view
|
||||
# this takes the rquest path(doc/api) and adds users.md so the path looks like doc/api/users.md
|
||||
# this takes the request path(doc/api) and adds users.md so the path looks like doc/api/users.md
|
||||
def build_nested_path(path, request_path)
|
||||
return request_path if path == ""
|
||||
return path unless request_path
|
||||
|
||||
@@ -31,6 +31,17 @@ module GroupsHelper
|
||||
end
|
||||
|
||||
title
|
||||
end
|
||||
|
||||
def group_filter_path(entity, options={})
|
||||
exist_opts = {
|
||||
status: params[:status]
|
||||
}
|
||||
|
||||
options = exist_opts.merge(options)
|
||||
|
||||
path = request.path
|
||||
path << "?#{options.to_param}"
|
||||
path
|
||||
end
|
||||
end
|
||||
|
||||
@@ -4,10 +4,10 @@ module Emails
|
||||
@issue = Issue.find(issue_id)
|
||||
@project = @issue.project
|
||||
@target_url = project_issue_url(@project, @issue)
|
||||
set_message_id("issue_#{issue_id}")
|
||||
mail(from: sender(@issue.author_id),
|
||||
to: recipient(recipient_id),
|
||||
subject: subject("#{@issue.title} (##{@issue.iid})"))
|
||||
mail_new_thread(@issue,
|
||||
from: sender(@issue.author_id),
|
||||
to: recipient(recipient_id),
|
||||
subject: subject("#{@issue.title} (##{@issue.iid})"))
|
||||
end
|
||||
|
||||
def reassigned_issue_email(recipient_id, issue_id, previous_assignee_id, updated_by_user_id)
|
||||
@@ -15,10 +15,10 @@ module Emails
|
||||
@previous_assignee = User.find_by(id: previous_assignee_id) if previous_assignee_id
|
||||
@project = @issue.project
|
||||
@target_url = project_issue_url(@project, @issue)
|
||||
set_reference("issue_#{issue_id}")
|
||||
mail(from: sender(updated_by_user_id),
|
||||
to: recipient(recipient_id),
|
||||
subject: subject("#{@issue.title} (##{@issue.iid})"))
|
||||
mail_answer_thread(@issue,
|
||||
from: sender(updated_by_user_id),
|
||||
to: recipient(recipient_id),
|
||||
subject: subject("#{@issue.title} (##{@issue.iid})"))
|
||||
end
|
||||
|
||||
def closed_issue_email(recipient_id, issue_id, updated_by_user_id)
|
||||
@@ -26,10 +26,10 @@ module Emails
|
||||
@project = @issue.project
|
||||
@updated_by = User.find updated_by_user_id
|
||||
@target_url = project_issue_url(@project, @issue)
|
||||
set_reference("issue_#{issue_id}")
|
||||
mail(from: sender(updated_by_user_id),
|
||||
to: recipient(recipient_id),
|
||||
subject: subject("#{@issue.title} (##{@issue.iid})"))
|
||||
mail_answer_thread(@issue,
|
||||
from: sender(updated_by_user_id),
|
||||
to: recipient(recipient_id),
|
||||
subject: subject("#{@issue.title} (##{@issue.iid})"))
|
||||
end
|
||||
|
||||
def issue_status_changed_email(recipient_id, issue_id, status, updated_by_user_id)
|
||||
@@ -38,10 +38,10 @@ module Emails
|
||||
@project = @issue.project
|
||||
@updated_by = User.find updated_by_user_id
|
||||
@target_url = project_issue_url(@project, @issue)
|
||||
set_reference("issue_#{issue_id}")
|
||||
mail(from: sender(updated_by_user_id),
|
||||
to: recipient(recipient_id),
|
||||
subject: subject("#{@issue.title} (##{@issue.iid})"))
|
||||
mail_answer_thread(@issue,
|
||||
from: sender(updated_by_user_id),
|
||||
to: recipient(recipient_id),
|
||||
subject: subject("#{@issue.title} (##{@issue.iid})"))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -4,10 +4,10 @@ module Emails
|
||||
@merge_request = MergeRequest.find(merge_request_id)
|
||||
@project = @merge_request.project
|
||||
@target_url = project_merge_request_url(@project, @merge_request)
|
||||
set_message_id("merge_request_#{merge_request_id}")
|
||||
mail(from: sender(@merge_request.author_id),
|
||||
to: recipient(recipient_id),
|
||||
subject: subject("#{@merge_request.title} (##{@merge_request.iid})"))
|
||||
mail_new_thread(@merge_request,
|
||||
from: sender(@merge_request.author_id),
|
||||
to: recipient(recipient_id),
|
||||
subject: subject("#{@merge_request.title} (##{@merge_request.iid})"))
|
||||
end
|
||||
|
||||
def reassigned_merge_request_email(recipient_id, merge_request_id, previous_assignee_id, updated_by_user_id)
|
||||
@@ -15,10 +15,10 @@ module Emails
|
||||
@previous_assignee = User.find_by(id: previous_assignee_id) if previous_assignee_id
|
||||
@project = @merge_request.project
|
||||
@target_url = project_merge_request_url(@project, @merge_request)
|
||||
set_reference("merge_request_#{merge_request_id}")
|
||||
mail(from: sender(updated_by_user_id),
|
||||
to: recipient(recipient_id),
|
||||
subject: subject("#{@merge_request.title} (##{@merge_request.iid})"))
|
||||
mail_answer_thread(@merge_request,
|
||||
from: sender(updated_by_user_id),
|
||||
to: recipient(recipient_id),
|
||||
subject: subject("#{@merge_request.title} (##{@merge_request.iid})"))
|
||||
end
|
||||
|
||||
def closed_merge_request_email(recipient_id, merge_request_id, updated_by_user_id)
|
||||
@@ -26,20 +26,32 @@ module Emails
|
||||
@updated_by = User.find updated_by_user_id
|
||||
@project = @merge_request.project
|
||||
@target_url = project_merge_request_url(@project, @merge_request)
|
||||
set_reference("merge_request_#{merge_request_id}")
|
||||
mail(from: sender(updated_by_user_id),
|
||||
to: recipient(recipient_id),
|
||||
subject: subject("#{@merge_request.title} (##{@merge_request.iid})"))
|
||||
mail_answer_thread(@merge_request,
|
||||
from: sender(updated_by_user_id),
|
||||
to: recipient(recipient_id),
|
||||
subject: subject("#{@merge_request.title} (##{@merge_request.iid})"))
|
||||
end
|
||||
|
||||
def merged_merge_request_email(recipient_id, merge_request_id, updated_by_user_id)
|
||||
@merge_request = MergeRequest.find(merge_request_id)
|
||||
@project = @merge_request.project
|
||||
@target_url = project_merge_request_url(@project, @merge_request)
|
||||
mail_answer_thread(@merge_request,
|
||||
from: sender(updated_by_user_id),
|
||||
to: recipient(recipient_id),
|
||||
subject: subject("#{@merge_request.title} (##{@merge_request.iid})"))
|
||||
end
|
||||
|
||||
def merge_request_status_email(recipient_id, merge_request_id, status, updated_by_user_id)
|
||||
@merge_request = MergeRequest.find(merge_request_id)
|
||||
@mr_status = status
|
||||
@project = @merge_request.project
|
||||
@updated_by = User.find updated_by_user_id
|
||||
@target_url = project_merge_request_url(@project, @merge_request)
|
||||
set_reference("merge_request_#{merge_request_id}")
|
||||
mail(from: sender(updated_by_user_id),
|
||||
to: recipient(recipient_id),
|
||||
subject: subject("#{@merge_request.title} (##{@merge_request.iid})"))
|
||||
subject: subject("#{@merge_request.title} (##{@merge_request.iid}) #{@mr_status}"))
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
+12
-11
@@ -5,9 +5,10 @@ module Emails
|
||||
@commit = @note.noteable
|
||||
@project = @note.project
|
||||
@target_url = project_commit_url(@project, @commit, anchor: "note_#{@note.id}")
|
||||
mail(from: sender(@note.author_id),
|
||||
to: recipient(recipient_id),
|
||||
subject: subject("#{@commit.title} (#{@commit.short_id})"))
|
||||
mail_answer_thread(@commit,
|
||||
from: sender(@note.author_id),
|
||||
to: recipient(recipient_id),
|
||||
subject: subject("#{@commit.title} (#{@commit.short_id})"))
|
||||
end
|
||||
|
||||
def note_issue_email(recipient_id, note_id)
|
||||
@@ -15,10 +16,10 @@ module Emails
|
||||
@issue = @note.noteable
|
||||
@project = @note.project
|
||||
@target_url = project_issue_url(@project, @issue, anchor: "note_#{@note.id}")
|
||||
set_reference("issue_#{@issue.id}")
|
||||
mail(from: sender(@note.author_id),
|
||||
to: recipient(recipient_id),
|
||||
subject: subject("#{@issue.title} (##{@issue.iid})"))
|
||||
mail_answer_thread(@issue,
|
||||
from: sender(@note.author_id),
|
||||
to: recipient(recipient_id),
|
||||
subject: subject("#{@issue.title} (##{@issue.iid})"))
|
||||
end
|
||||
|
||||
def note_merge_request_email(recipient_id, note_id)
|
||||
@@ -26,10 +27,10 @@ module Emails
|
||||
@merge_request = @note.noteable
|
||||
@project = @note.project
|
||||
@target_url = project_merge_request_url(@project, @merge_request, anchor: "note_#{@note.id}")
|
||||
set_reference("merge_request_#{@merge_request.id}")
|
||||
mail(from: sender(@note.author_id),
|
||||
to: recipient(recipient_id),
|
||||
subject: subject("#{@merge_request.title} (##{@merge_request.iid})"))
|
||||
mail_answer_thread(@merge_request,
|
||||
from: sender(@note.author_id),
|
||||
to: recipient(recipient_id),
|
||||
subject: subject("#{@merge_request.title} (##{@merge_request.iid})"))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
+38
-8
@@ -1,4 +1,6 @@
|
||||
class Notify < ActionMailer::Base
|
||||
include ActionDispatch::Routing::PolymorphicRoutes
|
||||
|
||||
include Emails::Issues
|
||||
include Emails::MergeRequests
|
||||
include Emails::Notes
|
||||
@@ -53,14 +55,6 @@ class Notify < ActionMailer::Base
|
||||
end
|
||||
end
|
||||
|
||||
# Set the Message-ID header field
|
||||
#
|
||||
# local_part - The local part of the message ID
|
||||
#
|
||||
def set_message_id(local_part)
|
||||
headers["Message-ID"] = "<#{local_part}@#{Gitlab.config.gitlab.host}>"
|
||||
end
|
||||
|
||||
# Set the References header field
|
||||
#
|
||||
# local_part - The local part of the referenced message ID
|
||||
@@ -93,4 +87,40 @@ class Notify < ActionMailer::Base
|
||||
subject << extra.join(' | ') if extra.present?
|
||||
subject
|
||||
end
|
||||
|
||||
# Return a string suitable for inclusion in the 'Message-Id' mail header.
|
||||
#
|
||||
# The message-id is generated from the unique URL to a model object.
|
||||
def message_id(model)
|
||||
model_name = model.class.model_name.singular_route_key
|
||||
"<#{model_name}_#{model.id}@#{Gitlab.config.gitlab.host}>"
|
||||
end
|
||||
|
||||
# Send an email that starts a new conversation thread,
|
||||
# with headers suitable for grouping by thread in email clients.
|
||||
#
|
||||
# See: mail_answer_thread
|
||||
def mail_new_thread(model, headers = {}, &block)
|
||||
headers['Message-ID'] = message_id(model)
|
||||
mail(headers, &block)
|
||||
end
|
||||
|
||||
# Send an email that responds to an existing conversation thread,
|
||||
# with headers suitable for grouping by thread in email clients.
|
||||
#
|
||||
# For grouping emails by thread, email clients heuristics require the answers to:
|
||||
#
|
||||
# * have a subject that begin by 'Re: '
|
||||
# * have a 'In-Reply-To' or 'References' header that references the original 'Message-ID'
|
||||
#
|
||||
def mail_answer_thread(model, headers = {}, &block)
|
||||
headers['In-Reply-To'] = message_id(model)
|
||||
headers['References'] = message_id(model)
|
||||
|
||||
if (headers[:subject])
|
||||
headers[:subject].prepend('Re: ')
|
||||
end
|
||||
|
||||
mail(headers, &block)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,6 +1,4 @@
|
||||
class Appearance < ActiveRecord::Base
|
||||
attr_accessible :title, :description, :logo
|
||||
|
||||
validates :title, presence: true
|
||||
validates :description, presence: true
|
||||
validates :logo, file_size: { maximum: 1000.kilobytes.to_i }
|
||||
|
||||
@@ -14,8 +14,6 @@
|
||||
#
|
||||
|
||||
class BroadcastMessage < ActiveRecord::Base
|
||||
attr_accessible :alert_type, :color, :ends_at, :font, :message, :starts_at
|
||||
|
||||
validates :message, presence: true
|
||||
validates :starts_at, presence: true
|
||||
validates :ends_at, presence: true
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
module TokenAuthenticatable
|
||||
extend ActiveSupport::Concern
|
||||
|
||||
module ClassMethods
|
||||
def find_by_authentication_token(authentication_token = nil)
|
||||
if authentication_token
|
||||
where(authentication_token: authentication_token).first
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def ensure_authentication_token
|
||||
if authentication_token.blank?
|
||||
self.authentication_token = generate_authentication_token
|
||||
end
|
||||
end
|
||||
|
||||
def reset_authentication_token!
|
||||
self.authentication_token = generate_authentication_token
|
||||
save
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def generate_authentication_token
|
||||
loop do
|
||||
token = Devise.friendly_token
|
||||
break token unless self.class.unscoped.where(authentication_token: token).first
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -10,13 +10,10 @@
|
||||
#
|
||||
|
||||
class DeployKeysProject < ActiveRecord::Base
|
||||
attr_accessible :key_id, :project_id
|
||||
|
||||
belongs_to :project
|
||||
belongs_to :deploy_key
|
||||
|
||||
validates :deploy_key_id, presence: true
|
||||
validates :deploy_key_id, uniqueness: { scope: [:project_id], message: "already exists in project" }
|
||||
|
||||
validates :project_id, presence: true
|
||||
end
|
||||
|
||||
@@ -10,16 +10,8 @@
|
||||
#
|
||||
|
||||
class Email < ActiveRecord::Base
|
||||
attr_accessible :email, :user_id
|
||||
|
||||
#
|
||||
# Relations
|
||||
#
|
||||
belongs_to :user
|
||||
|
||||
#
|
||||
# Validations
|
||||
#
|
||||
validates :user_id, presence: true
|
||||
validates :email, presence: true, email: { strict_mode: true }, uniqueness: true
|
||||
validate :unique_email, if: ->(email) { email.email_changed? }
|
||||
|
||||
+5
-3
@@ -15,9 +15,6 @@
|
||||
#
|
||||
|
||||
class Event < ActiveRecord::Base
|
||||
attr_accessible :project, :action, :data, :author_id, :project_id,
|
||||
:target_id, :target_type
|
||||
|
||||
default_scope { where.not(author_id: nil) }
|
||||
|
||||
CREATED = 1
|
||||
@@ -33,6 +30,7 @@ class Event < ActiveRecord::Base
|
||||
delegate :name, :email, to: :author, prefix: true, allow_nil: true
|
||||
delegate :title, to: :issue, prefix: true, allow_nil: true
|
||||
delegate :title, to: :merge_request, prefix: true, allow_nil: true
|
||||
delegate :title, to: :note, prefix: true, allow_nil: true
|
||||
|
||||
belongs_to :author, class_name: "User"
|
||||
belongs_to :project
|
||||
@@ -150,6 +148,10 @@ class Event < ActiveRecord::Base
|
||||
target if target_type == "MergeRequest"
|
||||
end
|
||||
|
||||
def note
|
||||
target if target_type == "Note"
|
||||
end
|
||||
|
||||
def action_name
|
||||
if closed?
|
||||
"closed"
|
||||
|
||||
@@ -10,10 +10,6 @@
|
||||
#
|
||||
|
||||
class ForkedProjectLink < ActiveRecord::Base
|
||||
attr_accessible :forked_from_project_id, :forked_to_project_id
|
||||
|
||||
# Relations
|
||||
belongs_to :forked_to_project, class_name: Project
|
||||
belongs_to :forked_from_project, class_name: Project
|
||||
|
||||
end
|
||||
|
||||
@@ -1,6 +1,4 @@
|
||||
class GitHook < ActiveRecord::Base
|
||||
attr_accessible :deny_delete_tag, :delete_branch_regex, :commit_message_regex, :force_push_regex
|
||||
|
||||
belongs_to :project
|
||||
validates :project, presence: true
|
||||
|
||||
|
||||
@@ -19,19 +19,14 @@ require 'file_size_validator'
|
||||
class Group < Namespace
|
||||
has_many :users_groups, dependent: :destroy
|
||||
has_many :users, through: :users_groups
|
||||
|
||||
has_many :project_group_links, dependent: :destroy
|
||||
has_many :shared_projects, through: :project_group_links, source: :project
|
||||
|
||||
attr_accessible :ldap_cn, :ldap_access
|
||||
|
||||
validates :ldap_access,
|
||||
inclusion: { in: UsersGroup.group_access_roles.values },
|
||||
presence: true,
|
||||
if: ->(group) { group.ldap_cn.present? }
|
||||
|
||||
attr_accessible :avatar
|
||||
|
||||
validate :avatar_type, if: ->(user) { user.avatar_changed? }
|
||||
validates :avatar, file_size: { maximum: 100.kilobytes.to_i }
|
||||
|
||||
|
||||
@@ -0,0 +1,95 @@
|
||||
class GroupMilestone
|
||||
|
||||
def initialize(title, milestones)
|
||||
@title = title
|
||||
@milestones = milestones
|
||||
end
|
||||
|
||||
def title
|
||||
@title
|
||||
end
|
||||
|
||||
def safe_title
|
||||
@title.parameterize
|
||||
end
|
||||
|
||||
def milestones
|
||||
@milestones
|
||||
end
|
||||
|
||||
def projects
|
||||
milestones.map { |milestone| milestone.project }
|
||||
end
|
||||
|
||||
def issue_count
|
||||
milestones.map { |milestone| milestone.issues.count }.sum
|
||||
end
|
||||
|
||||
def merge_requests_count
|
||||
milestones.map { |milestone| milestone.merge_requests.count }.sum
|
||||
end
|
||||
|
||||
def open_items_count
|
||||
milestones.map { |milestone| milestone.open_items_count }.sum
|
||||
end
|
||||
|
||||
def closed_items_count
|
||||
milestones.map { |milestone| milestone.closed_items_count }.sum
|
||||
end
|
||||
|
||||
def total_items_count
|
||||
milestones.map { |milestone| milestone.total_items_count }.sum
|
||||
end
|
||||
|
||||
def percent_complete
|
||||
((closed_items_count * 100) / total_items_count).abs
|
||||
rescue ZeroDivisionError
|
||||
100
|
||||
end
|
||||
|
||||
def state
|
||||
state = milestones.map { |milestone| milestone.state }
|
||||
|
||||
if state.count('active') == state.size
|
||||
'active'
|
||||
else
|
||||
'closed'
|
||||
end
|
||||
end
|
||||
|
||||
def active?
|
||||
state == 'active'
|
||||
end
|
||||
|
||||
def closed?
|
||||
state == 'closed'
|
||||
end
|
||||
|
||||
def issues
|
||||
@group_issues ||= milestones.map { |milestone| milestone.issues }.flatten.group_by(&:state)
|
||||
end
|
||||
|
||||
def merge_requests
|
||||
@group_merge_requests ||= milestones.map { |milestone| milestone.merge_requests }.flatten.group_by(&:state)
|
||||
end
|
||||
|
||||
def participants
|
||||
milestones.map { |milestone| milestone.participants.uniq }.reject(&:empty?).flatten
|
||||
end
|
||||
|
||||
def opened_issues
|
||||
issues.values_at("opened", "reopened").compact.flatten
|
||||
end
|
||||
|
||||
def closed_issues
|
||||
issues['closed']
|
||||
end
|
||||
|
||||
def opened_merge_requests
|
||||
merge_requests.values_at("opened", "reopened").compact.flatten
|
||||
end
|
||||
|
||||
def closed_merge_requests
|
||||
merge_requests.values_at("closed", "merged", "locked").compact.flatten
|
||||
end
|
||||
end
|
||||
@@ -33,9 +33,6 @@ class Issue < ActiveRecord::Base
|
||||
scope :of_group, ->(group) { where(project_id: group.project_ids) }
|
||||
scope :of_user_team, ->(team) { where(project_id: team.project_ids, assignee_id: team.member_ids) }
|
||||
|
||||
attr_accessible :title, :assignee_id, :position, :description,
|
||||
:milestone_id, :label_list, :state_event
|
||||
|
||||
acts_as_taggable_on :labels
|
||||
|
||||
scope :cared, ->(user) { where(assignee_id: user) }
|
||||
|
||||
@@ -19,8 +19,6 @@ class Key < ActiveRecord::Base
|
||||
|
||||
belongs_to :user
|
||||
|
||||
attr_accessible :key, :title
|
||||
|
||||
before_validation :strip_white_space, :generate_fingerpint
|
||||
|
||||
validates :title, presence: true, length: { within: 0..255 }
|
||||
|
||||
@@ -36,10 +36,6 @@ class MergeRequest < ActiveRecord::Base
|
||||
|
||||
delegate :commits, :diffs, :last_commit, :last_commit_short_sha, to: :merge_request_diff, prefix: nil
|
||||
|
||||
attr_accessible :title, :assignee_id, :source_project_id, :source_branch,
|
||||
:target_project_id, :target_branch, :milestone_id,
|
||||
:state_event, :description, :label_list
|
||||
|
||||
attr_accessor :should_remove_source_branch
|
||||
|
||||
# When this attribute is true some MR validation is ignored
|
||||
@@ -62,11 +58,11 @@ class MergeRequest < ActiveRecord::Base
|
||||
transition closed: :reopened
|
||||
end
|
||||
|
||||
event :lock do
|
||||
event :lock_mr do
|
||||
transition [:reopened, :opened] => :locked
|
||||
end
|
||||
|
||||
event :unlock do
|
||||
event :unlock_mr do
|
||||
transition locked: :reopened
|
||||
end
|
||||
|
||||
@@ -297,6 +293,8 @@ class MergeRequest < ActiveRecord::Base
|
||||
message << title.to_s
|
||||
message << "\n\n"
|
||||
message << description.to_s
|
||||
message << "\n\n"
|
||||
message << "See merge request !#{iid}"
|
||||
message
|
||||
end
|
||||
|
||||
|
||||
@@ -22,8 +22,6 @@ class MergeRequestDiff < ActiveRecord::Base
|
||||
|
||||
belongs_to :merge_request
|
||||
|
||||
attr_accessible :state, :st_commits, :st_diffs
|
||||
|
||||
delegate :target_branch, :source_branch, to: :merge_request, prefix: nil
|
||||
|
||||
state_machine :state, initial: :empty do
|
||||
|
||||
@@ -16,8 +16,6 @@
|
||||
class Milestone < ActiveRecord::Base
|
||||
include InternalId
|
||||
|
||||
attr_accessible :title, :description, :due_date, :state_event
|
||||
|
||||
belongs_to :project
|
||||
has_many :issues
|
||||
has_many :merge_requests
|
||||
|
||||
@@ -16,8 +16,6 @@
|
||||
class Namespace < ActiveRecord::Base
|
||||
include Gitlab::ShellAdapter
|
||||
|
||||
attr_accessible :name, :description, :path
|
||||
|
||||
has_many :projects, dependent: :destroy
|
||||
belongs_to :owner, class_name: "User"
|
||||
|
||||
@@ -25,12 +23,12 @@ class Namespace < ActiveRecord::Base
|
||||
validates :name, presence: true, uniqueness: true,
|
||||
length: { within: 0..255 },
|
||||
format: { with: Gitlab::Regex.name_regex,
|
||||
message: "only letters, digits, spaces & '_' '-' '.' allowed." }
|
||||
message: Gitlab::Regex.name_regex_message }
|
||||
validates :description, length: { within: 0..255 }
|
||||
validates :path, uniqueness: { case_sensitive: false }, presence: true, length: { within: 1..255 },
|
||||
exclusion: { in: Gitlab::Blacklist.path },
|
||||
format: { with: Gitlab::Regex.path_regex,
|
||||
message: "only letters, digits & '_' '-' '.' allowed. Letter should be first" }
|
||||
message: Gitlab::Regex.path_regex_message }
|
||||
|
||||
delegate :name, to: :owner, allow_nil: true, prefix: true
|
||||
|
||||
|
||||
+6
-8
@@ -25,8 +25,6 @@ class Note < ActiveRecord::Base
|
||||
|
||||
default_value_for :system, false
|
||||
|
||||
attr_accessible :note, :noteable, :noteable_id, :noteable_type, :project_id,
|
||||
:attachment, :line_code, :commit_id
|
||||
attr_mentionable :note
|
||||
|
||||
belongs_to :project
|
||||
@@ -63,13 +61,13 @@ class Note < ActiveRecord::Base
|
||||
def create_status_change_note(noteable, project, author, status, source)
|
||||
body = "_Status changed to #{status}#{' by ' + source.gfm_reference if source}_"
|
||||
|
||||
create({
|
||||
create(
|
||||
noteable: noteable,
|
||||
project: project,
|
||||
author: author,
|
||||
note: body,
|
||||
system: true
|
||||
}, without_protection: true)
|
||||
)
|
||||
end
|
||||
|
||||
# +noteable+ was referenced from +mentioner+, by including GFM in either +mentioner+'s description or an associated Note.
|
||||
@@ -88,7 +86,7 @@ class Note < ActiveRecord::Base
|
||||
note_options.merge!(noteable: noteable)
|
||||
end
|
||||
|
||||
create(note_options, without_protection: true)
|
||||
create(note_options)
|
||||
end
|
||||
|
||||
def create_milestone_change_note(noteable, project, author, milestone)
|
||||
@@ -98,13 +96,13 @@ class Note < ActiveRecord::Base
|
||||
"_Milestone changed to #{milestone.title}_"
|
||||
end
|
||||
|
||||
create({
|
||||
create(
|
||||
noteable: noteable,
|
||||
project: project,
|
||||
author: author,
|
||||
note: body,
|
||||
system: true
|
||||
}, without_protection: true)
|
||||
)
|
||||
end
|
||||
|
||||
def create_assignee_change_note(noteable, project, author, assignee)
|
||||
@@ -116,7 +114,7 @@ class Note < ActiveRecord::Base
|
||||
author: author,
|
||||
note: body,
|
||||
system: true
|
||||
}, without_protection: true)
|
||||
})
|
||||
end
|
||||
|
||||
def discussions_from_notes(notes)
|
||||
|
||||
+20
-17
@@ -27,24 +27,20 @@
|
||||
class Project < ActiveRecord::Base
|
||||
include Gitlab::ShellAdapter
|
||||
include Gitlab::VisibilityLevel
|
||||
include Gitlab::ConfigHelper
|
||||
extend Gitlab::ConfigHelper
|
||||
extend Enumerize
|
||||
|
||||
default_value_for :archived, false
|
||||
default_value_for :issues_enabled, true
|
||||
default_value_for :merge_requests_enabled, true
|
||||
default_value_for :wiki_enabled, true
|
||||
default_value_for :visibility_level, gitlab_config_features.visibility_level
|
||||
default_value_for :issues_enabled, gitlab_config_features.issues
|
||||
default_value_for :merge_requests_enabled, gitlab_config_features.merge_requests
|
||||
default_value_for :wiki_enabled, gitlab_config_features.wiki
|
||||
default_value_for :wall_enabled, false
|
||||
default_value_for :snippets_enabled, true
|
||||
default_value_for :snippets_enabled, gitlab_config_features.snippets
|
||||
|
||||
ActsAsTaggableOn.strict_case_match = true
|
||||
|
||||
attr_accessible :name, :path, :description, :issues_tracker, :label_list,
|
||||
:issues_enabled, :merge_requests_enabled, :snippets_enabled, :issues_tracker_id,
|
||||
:wiki_enabled, :visibility_level, :import_url, :last_activity_at,
|
||||
:merge_requests_template, as: [:default, :admin]
|
||||
|
||||
attr_accessible :namespace_id, :creator_id, as: :admin
|
||||
|
||||
acts_as_taggable_on :labels, :issues_default_labels
|
||||
|
||||
attr_accessor :new_default_branch
|
||||
@@ -101,13 +97,16 @@ class Project < ActiveRecord::Base
|
||||
validates :description, length: { maximum: 2000 }, allow_blank: true
|
||||
validates :name, presence: true, length: { within: 0..255 },
|
||||
format: { with: Gitlab::Regex.project_name_regex,
|
||||
message: "only letters, digits, spaces & '_' '-' '.' allowed. Letter or digit should be first" }
|
||||
message: Gitlab::Regex.project_regex_message }
|
||||
validates :path, presence: true, length: { within: 0..255 },
|
||||
exclusion: { in: Gitlab::Blacklist.path },
|
||||
format: { with: Gitlab::Regex.path_regex,
|
||||
message: "only letters, digits & '_' '-' '.' allowed. Letter or digit should be first" }
|
||||
message: Gitlab::Regex.path_regex_message }
|
||||
validates :issues_enabled, :merge_requests_enabled,
|
||||
:wiki_enabled, inclusion: { in: [true, false] }
|
||||
validates :visibility_level,
|
||||
exclusion: { in: gitlab_config.restricted_visibility_levels },
|
||||
if: -> { gitlab_config.restricted_visibility_levels.any? }
|
||||
validates :issues_tracker_id, length: { maximum: 255 }, allow_blank: true
|
||||
validates :namespace, presence: true
|
||||
validates_uniqueness_of :name, scope: :namespace_id
|
||||
@@ -251,7 +250,7 @@ class Project < ActiveRecord::Base
|
||||
end
|
||||
|
||||
def check_limit
|
||||
unless creator.can_create_project?
|
||||
unless creator.can_create_project? or namespace.kind == 'group'
|
||||
errors[:limit_reached] << ("Your project limit is #{creator.projects_limit} projects! Please contact your administrator to increase it")
|
||||
end
|
||||
rescue
|
||||
@@ -263,7 +262,7 @@ class Project < ActiveRecord::Base
|
||||
end
|
||||
|
||||
def web_url
|
||||
[Gitlab.config.gitlab.url, path_with_namespace].join("/")
|
||||
[gitlab_config.url, path_with_namespace].join("/")
|
||||
end
|
||||
|
||||
def web_url_without_protocol
|
||||
@@ -403,7 +402,11 @@ class Project < ActiveRecord::Base
|
||||
services.each do |service|
|
||||
|
||||
# Call service hook only if it is active
|
||||
service.execute(data) if service.active
|
||||
begin
|
||||
service.execute(data) if service.active
|
||||
rescue => e
|
||||
logger.error(e)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -488,7 +491,7 @@ class Project < ActiveRecord::Base
|
||||
end
|
||||
|
||||
def http_url_to_repo
|
||||
[Gitlab.config.gitlab.url, "/", path_with_namespace, ".git"].join('')
|
||||
[gitlab_config.url, "/", path_with_namespace, ".git"].join('')
|
||||
end
|
||||
|
||||
# Check if current branch name is marked as protected in the system
|
||||
|
||||
@@ -18,8 +18,6 @@
|
||||
class ProjectHook < WebHook
|
||||
belongs_to :project
|
||||
|
||||
attr_accessible :push_events, :issues_events, :merge_requests_events, :tag_push_events
|
||||
|
||||
scope :push_hooks, -> { where(push_events: true) }
|
||||
scope :tag_push_hooks, -> { where(tag_push_events: true) }
|
||||
scope :issue_hooks, -> { where(issues_events: true) }
|
||||
|
||||
@@ -18,8 +18,6 @@
|
||||
#
|
||||
|
||||
class AssemblaService < Service
|
||||
attr_accessible :subdomain
|
||||
|
||||
include HTTParty
|
||||
|
||||
validates :token, presence: true, if: :activated?
|
||||
|
||||
@@ -18,8 +18,6 @@
|
||||
#
|
||||
|
||||
class CampfireService < Service
|
||||
attr_accessible :subdomain, :room
|
||||
|
||||
validates :token, presence: true, if: :activated?
|
||||
|
||||
def title
|
||||
|
||||
@@ -18,8 +18,6 @@
|
||||
#
|
||||
|
||||
class EmailsOnPushService < Service
|
||||
attr_accessible :recipients
|
||||
|
||||
validates :recipients, presence: true, if: :activated?
|
||||
|
||||
def title
|
||||
|
||||
@@ -18,8 +18,6 @@
|
||||
#
|
||||
|
||||
class GitlabCiService < CiService
|
||||
attr_accessible :project_url
|
||||
|
||||
validates :project_url, presence: true, if: :activated?
|
||||
validates :token, presence: true, if: :activated?
|
||||
|
||||
|
||||
@@ -18,8 +18,6 @@
|
||||
#
|
||||
|
||||
class HipchatService < Service
|
||||
attr_accessible :room
|
||||
|
||||
validates :token, presence: true, if: :activated?
|
||||
|
||||
def title
|
||||
|
||||
@@ -18,8 +18,6 @@
|
||||
#
|
||||
|
||||
class JenkinsService < CiService
|
||||
attr_accessible :project_url
|
||||
|
||||
validates :project_url, presence: true, if: :activated?
|
||||
|
||||
delegate :execute, to: :service_hook, prefix: nil
|
||||
|
||||
@@ -20,9 +20,7 @@
|
||||
# api_version :string(255)
|
||||
|
||||
class JiraService < Service
|
||||
|
||||
include HTTParty
|
||||
attr_accessible :project_url, :username, :password, :api_version
|
||||
|
||||
validates :username, :password, presence: true, if: :activated?
|
||||
before_validation :set_api_version
|
||||
|
||||
@@ -18,9 +18,6 @@
|
||||
#
|
||||
|
||||
class SlackService < Service
|
||||
attr_accessible :room
|
||||
attr_accessible :subdomain
|
||||
|
||||
validates :room, presence: true, if: :activated?
|
||||
validates :subdomain, presence: true, if: :activated?
|
||||
validates :token, presence: true, if: :activated?
|
||||
|
||||
@@ -12,8 +12,6 @@
|
||||
class ProtectedBranch < ActiveRecord::Base
|
||||
include Gitlab::ShellAdapter
|
||||
|
||||
attr_accessible :name
|
||||
|
||||
belongs_to :project
|
||||
validates :name, presence: true
|
||||
validates :project, presence: true
|
||||
|
||||
@@ -242,4 +242,25 @@ class Repository
|
||||
branches
|
||||
end
|
||||
end
|
||||
|
||||
def contributors
|
||||
log = graph_log.group_by { |i| i[:author_email] }
|
||||
|
||||
log.map do |email, contributions|
|
||||
contributor = Gitlab::Contributor.new
|
||||
contributor.email = email
|
||||
|
||||
contributions.each do |contribution|
|
||||
if contributor.name.blank?
|
||||
contributor.name = contribution[:author_name]
|
||||
end
|
||||
|
||||
contributor.commits += 1
|
||||
contributor.additions += contribution[:additions] || 0
|
||||
contributor.deletions += contribution[:deletions] || 0
|
||||
end
|
||||
|
||||
contributor
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -22,8 +22,6 @@
|
||||
class Service < ActiveRecord::Base
|
||||
default_value_for :active, false
|
||||
|
||||
attr_accessible :title, :token, :type, :active, :api_key
|
||||
|
||||
belongs_to :project
|
||||
has_one :service_hook
|
||||
|
||||
|
||||
@@ -18,8 +18,6 @@
|
||||
class Snippet < ActiveRecord::Base
|
||||
include Linguist::BlobHelper
|
||||
|
||||
attr_accessible :title, :content, :file_name, :expires_at, :private
|
||||
|
||||
default_value_for :private, true
|
||||
|
||||
belongs_to :author, class_name: "User"
|
||||
|
||||
+13
-31
@@ -50,31 +50,25 @@ require 'carrierwave/orm/activerecord'
|
||||
require 'file_size_validator'
|
||||
|
||||
class User < ActiveRecord::Base
|
||||
include Gitlab::ConfigHelper
|
||||
extend Gitlab::ConfigHelper
|
||||
include TokenAuthenticatable
|
||||
|
||||
default_value_for :admin, false
|
||||
default_value_for :can_create_group, true
|
||||
default_value_for :can_create_group, gitlab_config.default_can_create_group
|
||||
default_value_for :can_create_team, false
|
||||
default_value_for :hide_no_ssh_key, false
|
||||
default_value_for :projects_limit, gitlab_config.default_projects_limit
|
||||
default_value_for :theme_id, gitlab_config.default_theme
|
||||
|
||||
devise :database_authenticatable, :token_authenticatable, :lockable, :async,
|
||||
devise :database_authenticatable, :lockable, :async,
|
||||
:recoverable, :rememberable, :trackable, :validatable, :omniauthable, :confirmable, :registerable
|
||||
|
||||
attr_accessible :email, :password, :password_confirmation, :remember_me, :bio, :name, :username,
|
||||
:skype, :linkedin, :twitter, :website_url, :color_scheme_id, :theme_id, :force_random_password,
|
||||
:extern_uid, :provider, :password_expires_at, :avatar, :hide_no_ssh_key,
|
||||
as: [:default, :admin]
|
||||
|
||||
attr_accessible :projects_limit, :can_create_group,
|
||||
as: :admin
|
||||
|
||||
attr_accessor :force_random_password
|
||||
|
||||
# Virtual attribute for authenticating by either username or email
|
||||
attr_accessor :login
|
||||
|
||||
# Add login to attr_accessible
|
||||
attr_accessible :login
|
||||
|
||||
|
||||
#
|
||||
# Relations
|
||||
#
|
||||
@@ -120,7 +114,7 @@ class User < ActiveRecord::Base
|
||||
validates :username, presence: true, uniqueness: { case_sensitive: false },
|
||||
exclusion: { in: Gitlab::Blacklist.path },
|
||||
format: { with: Gitlab::Regex.username_regex,
|
||||
message: "only letters, digits & '_' '-' '.' allowed. Letter should be first" }
|
||||
message: Gitlab::Regex.username_regex_message }
|
||||
|
||||
validates :notification_level, inclusion: { in: Notification.notification_levels }, presence: true
|
||||
validate :namespace_uniq, if: ->(user) { user.username_changed? }
|
||||
@@ -223,20 +217,8 @@ class User < ActiveRecord::Base
|
||||
where('users.username = ? OR users.id = ?', name_or_id.to_s, name_or_id.to_i).first
|
||||
end
|
||||
|
||||
def build_user(attrs = {}, options= {})
|
||||
if options[:as] == :admin
|
||||
User.new(defaults.merge(attrs.symbolize_keys), options)
|
||||
else
|
||||
User.new(attrs, options).with_defaults
|
||||
end
|
||||
end
|
||||
|
||||
def defaults
|
||||
{
|
||||
projects_limit: Gitlab.config.gitlab.default_projects_limit,
|
||||
can_create_group: Gitlab.config.gitlab.default_can_create_group,
|
||||
theme_id: Gitlab.config.gitlab.default_theme
|
||||
}
|
||||
def build_user(attrs = {})
|
||||
User.new(attrs)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -315,7 +297,7 @@ class User < ActiveRecord::Base
|
||||
end
|
||||
|
||||
def can_change_username?
|
||||
Gitlab.config.gitlab.username_changing_enabled
|
||||
gitlab_config.username_changing_enabled
|
||||
end
|
||||
|
||||
def can_create_project?
|
||||
@@ -490,7 +472,7 @@ class User < ActiveRecord::Base
|
||||
|
||||
def avatar_url(size = nil)
|
||||
if avatar.present?
|
||||
URI::join(Gitlab.config.gitlab.url, avatar.url).to_s
|
||||
URI::join(gitlab_config.url, avatar.url).to_s
|
||||
else
|
||||
GravatarService.new.execute(email, size)
|
||||
end
|
||||
|
||||
@@ -19,8 +19,6 @@ class UsersGroup < ActiveRecord::Base
|
||||
Gitlab::Access.options_with_owner
|
||||
end
|
||||
|
||||
attr_accessible :group_access, :user_id
|
||||
|
||||
belongs_to :user
|
||||
belongs_to :group
|
||||
|
||||
|
||||
@@ -16,8 +16,6 @@ class UsersProject < ActiveRecord::Base
|
||||
include Notifiable
|
||||
include Gitlab::Access
|
||||
|
||||
attr_accessible :user, :user_id, :project_access
|
||||
|
||||
belongs_to :user
|
||||
belongs_to :project
|
||||
|
||||
@@ -126,7 +124,7 @@ class UsersProject < ActiveRecord::Base
|
||||
author_id: self.user.id
|
||||
)
|
||||
|
||||
notification_service.new_team_member(self)
|
||||
notification_service.new_team_member(self) unless owner?
|
||||
system_hook_service.execute_hooks_for(self, :create)
|
||||
end
|
||||
|
||||
|
||||
@@ -22,8 +22,6 @@ class WebHook < ActiveRecord::Base
|
||||
default_value_for :issues_events, false
|
||||
default_value_for :merge_requests_events, false
|
||||
|
||||
attr_accessible :url
|
||||
|
||||
# HTTParty timeout
|
||||
default_timeout 10
|
||||
|
||||
|
||||
@@ -25,7 +25,10 @@ module Files
|
||||
file_path = path
|
||||
|
||||
unless file_name =~ Gitlab::Regex.path_regex
|
||||
return error("Your changes could not be committed, because file name contains not allowed characters")
|
||||
return error(
|
||||
'Your changes could not be committed, because the file name ' +
|
||||
Gitlab::Regex.path_regex_message
|
||||
)
|
||||
end
|
||||
|
||||
blob = repository.blob_at_branch(ref, file_path)
|
||||
|
||||
@@ -4,6 +4,7 @@ module Issues
|
||||
if issue.reopen
|
||||
event_service.reopen_issue(issue, current_user)
|
||||
create_note(issue)
|
||||
notification_service.reopen_issue(issue, current_user)
|
||||
execute_hooks(issue, 'reopen')
|
||||
end
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
module Issues
|
||||
class UpdateService < Issues::BaseService
|
||||
def execute(issue)
|
||||
state = params.delete('state_event') || params.delete(:state_event)
|
||||
state = params[:state_event]
|
||||
|
||||
case state
|
||||
when 'reopen'
|
||||
@@ -10,7 +10,7 @@ module Issues
|
||||
Issues::CloseService.new(project, current_user, {}).execute(issue)
|
||||
end
|
||||
|
||||
if params.present? && issue.update_attributes(params)
|
||||
if params.present? && issue.update_attributes(params.except(:state_event))
|
||||
issue.reset_events_cache
|
||||
|
||||
if issue.previous_changes.include?('milestone_id')
|
||||
|
||||
@@ -6,7 +6,7 @@ module MergeRequests
|
||||
# Called when you do merge via GitLab UI
|
||||
class AutoMergeService < BaseMergeService
|
||||
def execute(merge_request, current_user, commit_message)
|
||||
merge_request.lock
|
||||
merge_request.lock_mr
|
||||
|
||||
if Gitlab::Satellite::MergeAction.new(current_user, merge_request).merge!(commit_message)
|
||||
merge_request.merge
|
||||
@@ -17,11 +17,11 @@ module MergeRequests
|
||||
|
||||
true
|
||||
else
|
||||
merge_request.unlock
|
||||
merge_request.unlock_mr
|
||||
false
|
||||
end
|
||||
rescue
|
||||
merge_request.unlock if merge_request.locked?
|
||||
merge_request.unlock_mr if merge_request.locked?
|
||||
merge_request.mark_as_unmergeable
|
||||
false
|
||||
end
|
||||
|
||||
@@ -3,6 +3,7 @@ module MergeRequests
|
||||
def execute(merge_request)
|
||||
if merge_request.reopen
|
||||
event_service.reopen_mr(merge_request, current_user)
|
||||
notification_service.reopen_mr(merge_request, current_user)
|
||||
create_note(merge_request)
|
||||
execute_hooks(merge_request)
|
||||
merge_request.reload_code
|
||||
|
||||
@@ -7,10 +7,10 @@ module MergeRequests
|
||||
def execute(merge_request)
|
||||
# We dont allow change of source/target projects
|
||||
# after merge request was created
|
||||
params.delete(:source_project_id)
|
||||
params.delete(:target_project_id)
|
||||
params.except!(:source_project_id)
|
||||
params.except!(:target_project_id)
|
||||
|
||||
state = params.delete('state_event') || params.delete(:state_event)
|
||||
state = params[:state_event]
|
||||
|
||||
case state
|
||||
when 'reopen'
|
||||
@@ -19,7 +19,7 @@ module MergeRequests
|
||||
MergeRequests::CloseService.new(project, current_user, {}).execute(merge_request)
|
||||
end
|
||||
|
||||
if params.present? && merge_request.update_attributes(params)
|
||||
if params.present? && merge_request.update_attributes(params.except(:state_event))
|
||||
merge_request.reset_events_cache
|
||||
|
||||
if merge_request.previous_changes.include?('milestone_id')
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
module Milestones
|
||||
class GroupService < Milestones::BaseService
|
||||
def initialize(project_milestones)
|
||||
@project_milestones = project_milestones.group_by(&:title)
|
||||
end
|
||||
|
||||
def execute
|
||||
build(@project_milestones)
|
||||
end
|
||||
|
||||
def milestone(title)
|
||||
if title
|
||||
group_milestone = @project_milestones[title].group_by(&:title)
|
||||
build(group_milestone).first
|
||||
else
|
||||
nil
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def build(milestone)
|
||||
milestone.map{ |title, milestones| GroupMilestone.new(title, milestones) }
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -1,7 +1,7 @@
|
||||
module Milestones
|
||||
class UpdateService < Milestones::BaseService
|
||||
def execute(milestone)
|
||||
state = params.delete('state_event') || params.delete(:state_event)
|
||||
state = params[:state_event]
|
||||
|
||||
case state
|
||||
when 'activate'
|
||||
@@ -11,7 +11,7 @@ module Milestones
|
||||
end
|
||||
|
||||
if params.present?
|
||||
milestone.update_attributes(params)
|
||||
milestone.update_attributes(params.except(:state_event))
|
||||
end
|
||||
|
||||
milestone
|
||||
|
||||
@@ -80,6 +80,10 @@ class NotificationService
|
||||
close_resource_email(merge_request, merge_request.target_project, current_user, 'closed_merge_request_email')
|
||||
end
|
||||
|
||||
def reopen_issue(issue, current_user)
|
||||
reopen_resource_email(issue, issue.project, current_user, 'issue_status_changed_email', 'reopened')
|
||||
end
|
||||
|
||||
# When we merge a merge request we should send next emails:
|
||||
#
|
||||
# * merge_request author if their notification level is not Disabled
|
||||
@@ -89,12 +93,17 @@ class NotificationService
|
||||
def merge_mr(merge_request, current_user)
|
||||
recipients = reject_muted_users([merge_request.author, merge_request.assignee], merge_request.target_project)
|
||||
recipients = recipients.concat(project_watchers(merge_request.target_project)).uniq
|
||||
recipients.delete(current_user)
|
||||
|
||||
recipients.each do |recipient|
|
||||
mailer.merged_merge_request_email(recipient.id, merge_request.id, current_user.id)
|
||||
end
|
||||
end
|
||||
|
||||
def reopen_mr(merge_request, current_user)
|
||||
reopen_resource_email(merge_request, merge_request.target_project, current_user, 'merge_request_status_email', 'reopened')
|
||||
end
|
||||
|
||||
# Notify new user with email after creation
|
||||
def new_user(user)
|
||||
# Don't email omniauth created users
|
||||
@@ -301,7 +310,9 @@ class NotificationService
|
||||
end
|
||||
|
||||
def reassign_resource_email(target, project, current_user, method)
|
||||
recipients = User.where(id: [target.assignee_id, target.assignee_id_was])
|
||||
assignee_id_was = previous_record(target, "assignee_id")
|
||||
|
||||
recipients = User.where(id: [target.assignee_id, assignee_id_was])
|
||||
|
||||
# Add watchers to email list
|
||||
recipients = recipients.concat(project_watchers(project))
|
||||
@@ -313,11 +324,29 @@ class NotificationService
|
||||
recipients.delete(current_user)
|
||||
|
||||
recipients.each do |recipient|
|
||||
mailer.send(method, recipient.id, target.id, target.assignee_id_was, current_user.id)
|
||||
mailer.send(method, recipient.id, target.id, assignee_id_was, current_user.id)
|
||||
end
|
||||
end
|
||||
|
||||
def reopen_resource_email(target, project, current_user, method, status)
|
||||
recipients = reject_muted_users([target.author, target.assignee], project)
|
||||
recipients = recipients.concat(project_watchers(project)).uniq
|
||||
recipients.delete(current_user)
|
||||
|
||||
recipients.each do |recipient|
|
||||
mailer.send(method, recipient.id, target.id, status, current_user.id)
|
||||
end
|
||||
end
|
||||
|
||||
def mailer
|
||||
Notify.delay
|
||||
end
|
||||
|
||||
def previous_record(object, attribute)
|
||||
if object && attribute
|
||||
if object.previous_changes.include?(attribute)
|
||||
object.previous_changes[attribute].first
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -5,27 +5,13 @@ module Projects
|
||||
end
|
||||
|
||||
def execute
|
||||
# get namespace id
|
||||
namespace_id = params.delete(:namespace_id)
|
||||
@project = Project.new(params)
|
||||
|
||||
# check that user is allowed to set specified visibility_level
|
||||
# Reset visibility levet if is not allowed to set it
|
||||
unless Gitlab::VisibilityLevel.allowed_for?(current_user, params[:visibility_level])
|
||||
params.delete(:visibility_level)
|
||||
@project.visibility_level = default_features.visibility_level
|
||||
end
|
||||
|
||||
# Load default feature settings
|
||||
default_features = Gitlab.config.gitlab.default_projects_features
|
||||
|
||||
default_opts = {
|
||||
issues_enabled: default_features.issues,
|
||||
wiki_enabled: default_features.wiki,
|
||||
snippets_enabled: default_features.snippets,
|
||||
merge_requests_enabled: default_features.merge_requests,
|
||||
visibility_level: default_features.visibility_level
|
||||
}.stringify_keys
|
||||
|
||||
@project = Project.new(default_opts.merge(params))
|
||||
|
||||
# Parametrize path for project
|
||||
#
|
||||
# Ex.
|
||||
@@ -33,13 +19,14 @@ module Projects
|
||||
#
|
||||
@project.path = @project.name.dup.parameterize unless @project.path.present?
|
||||
|
||||
# get namespace id
|
||||
namespace_id = params[:namespace_id]
|
||||
|
||||
if namespace_id
|
||||
# Find matching namespace and check if it allowed
|
||||
# for current user if namespace_id passed.
|
||||
if allowed_namespace?(current_user, namespace_id)
|
||||
@project.namespace_id = namespace_id
|
||||
else
|
||||
unless allowed_namespace?(current_user, namespace_id)
|
||||
@project.namespace_id = nil
|
||||
deny_namespace
|
||||
return @project
|
||||
end
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user