diff options
Diffstat (limited to 'config')
-rw-r--r-- | config/application.rb | 20 | ||||
-rw-r--r-- | config/environments/test.rb | 2 | ||||
-rw-r--r-- | config/gitlab.yml.example | 56 | ||||
-rw-r--r-- | config/initializers/1_settings.rb | 24 | ||||
-rw-r--r-- | config/initializers/4_sidekiq.rb | 3 | ||||
-rw-r--r-- | config/initializers/6_rack_profiler.rb | 2 | ||||
-rw-r--r-- | config/initializers/7_omniauth.rb | 2 | ||||
-rw-r--r-- | config/initializers/acts_as_taggable_on_patch.rb | 35 | ||||
-rw-r--r-- | config/initializers/carrierwave.rb | 28 | ||||
-rw-r--r-- | config/initializers/devise.rb | 3 | ||||
-rw-r--r-- | config/initializers/doorkeeper.rb | 102 | ||||
-rw-r--r-- | config/initializers/gitlab_shell_secret_token.rb | 2 | ||||
-rw-r--r-- | config/initializers/public_key.rb | 2 | ||||
-rw-r--r-- | config/initializers/rack_attack_git_basic_auth.rb | 12 | ||||
-rw-r--r-- | config/initializers/redis-store-fix-expiry.rb | 44 | ||||
-rw-r--r-- | config/initializers/smtp_settings.rb.sample | 5 | ||||
-rw-r--r-- | config/initializers/static_files.rb | 15 | ||||
-rw-r--r-- | config/locales/doorkeeper.en.yml | 73 | ||||
-rw-r--r-- | config/routes.rb | 400 | ||||
-rw-r--r-- | config/unicorn.rb.example | 14 |
20 files changed, 626 insertions, 218 deletions
diff --git a/config/application.rb b/config/application.rb index 44a5d68d126..bd4578848c5 100644 --- a/config/application.rb +++ b/config/application.rb @@ -12,11 +12,11 @@ module Gitlab # -- all .rb files in that directory are automatically loaded. # Custom directories with classes and modules you want to be autoloadable. - config.autoload_paths += %W(#{config.root}/lib - #{config.root}/app/models/hooks - #{config.root}/app/models/concerns - #{config.root}/app/models/project_services - #{config.root}/app/models/members) + config.autoload_paths.push(*%W(#{config.root}/lib + #{config.root}/app/models/hooks + #{config.root}/app/models/concerns + #{config.root}/app/models/project_services + #{config.root}/app/models/members)) # Only load the plugins named here, in the order given (default is alphabetical). # :all can be used as a placeholder for all plugins not explicitly named. @@ -31,7 +31,7 @@ module Gitlab config.encoding = "utf-8" # Configure sensitive parameters which will be filtered from the log file. - config.filter_parameters += [:password] + config.filter_parameters.push(:password, :password_confirmation, :private_token) # Enable escaping HTML in JSON. config.active_support.escape_html_entities_in_json = true @@ -70,7 +70,10 @@ module Gitlab config.middleware.use Rack::Cors do allow do origins '*' - resource '/api/*', headers: :any, methods: [:get, :post, :options, :put, :delete] + resource '/api/*', + headers: :any, + methods: [:get, :post, :options, :put, :delete], + expose: ['Link'] end end @@ -92,5 +95,8 @@ module Gitlab redis_config_hash[:namespace] = 'cache:gitlab' config.cache_store = :redis_store, redis_config_hash + + # This is needed for gitlab-shell + ENV['GITLAB_PATH_OUTSIDE_HOOK'] = ENV['PATH'] end end diff --git a/config/environments/test.rb b/config/environments/test.rb index 25b082b98da..2d5e7addcd3 100644 --- a/config/environments/test.rb +++ b/config/environments/test.rb @@ -5,7 +5,7 @@ Gitlab::Application.configure do # test suite. You never need to work with it otherwise. Remember that # your test database is "scratch space" for the test suite and is wiped # and recreated between test runs. Don't rely on the data there! - config.cache_classes = true + config.cache_classes = false # Configure static asset server for tests with Cache-Control for performance config.serve_static_assets = true diff --git a/config/gitlab.yml.example b/config/gitlab.yml.example index bb0ffae0b70..6dff07cf9df 100644 --- a/config/gitlab.yml.example +++ b/config/gitlab.yml.example @@ -35,7 +35,7 @@ production: &base ## Date & Time settings # Uncomment and customize if you want to change the default time zone of GitLab application. - # To see all available zones, run `bundle exec rake time:zones:all` + # To see all available zones, run `bundle exec rake time:zones:all RAILS_ENV=production` # time_zone: 'UTC' ## Email settings @@ -44,10 +44,8 @@ production: &base # Email address used in the "From" field in mails sent by GitLab email_from: example@example.com - # Email server smtp settings are in [a separate file](initializers/smtp_settings.rb.sample). + # Email server smtp settings are in config/initializers/smtp_settings.rb.sample - ## User settings - default_projects_limit: 10 # default_can_create_group: false # default: true # username_changing_enabled: false # default: true - User can change her username/namespace ## Default theme @@ -58,16 +56,6 @@ production: &base ## COLOR = 5 # default_theme: 2 # default: 2 - ## Users can create accounts - # This also allows normal users to sign up for accounts themselves - # default: false - By default GitLab administrators must create all new accounts - # signup_enabled: true - - ## Standard login settings - # The standard login can be disabled to force login via LDAP - # default: true - If set to false the standard login form won't be shown on the sign-in page - # signin_enabled: false - # Restrict setting visibility levels for non-admin users. # The default is to allow all levels. # restricted_visibility_levels: [ "public" ] @@ -77,7 +65,7 @@ production: &base # This happens when the commit is pushed or merged into the default branch of a project. # When not specified the default issue_closing_pattern as specified below will be used. # Tip: you can test your closing pattern at http://rubular.com - # issue_closing_pattern: '([Cc]lose[sd]|[Ff]ixe[sd]) #(\d+)' + # issue_closing_pattern: '((?:[Cc]los(?:e[sd]|ing)|[Ff]ix(?:e[sd]|ing)?) +(?:(?:issues? +)?#\d+(?:(?:, *| +and +)?))+)' ## Default project features settings default_projects_features: @@ -153,9 +141,9 @@ production: &base label: 'LDAP' host: '_your_ldap_server' - port: 636 + port: 389 uid: 'sAMAccountName' - method: 'ssl' # "tls" or "ssl" or "plain" + method: 'plain' # "tls" or "ssl" or "plain" bind_dn: '_the_full_dn_of_the_user_you_will_bind_with' password: '_the_password_of_the_bind_user' @@ -219,14 +207,19 @@ production: &base # arguments, followed by optional 'args' which can be either a hash or an array. # Documentation for this is available at http://doc.gitlab.com/ce/integration/omniauth.html providers: - # - { name: 'google_oauth2', app_id: 'YOUR APP ID', - # app_secret: 'YOUR APP SECRET', + # - { name: 'google_oauth2', app_id: 'YOUR_APP_ID', + # app_secret: 'YOUR_APP_SECRET', # args: { access_type: 'offline', approval_prompt: '' } } - # - { name: 'twitter', app_id: 'YOUR APP ID', - # app_secret: 'YOUR APP SECRET'} - # - { name: 'github', app_id: 'YOUR APP ID', - # app_secret: 'YOUR APP SECRET', + # - { name: 'twitter', app_id: 'YOUR_APP_ID', + # app_secret: 'YOUR_APP_SECRET'} + # - { name: 'github', app_id: 'YOUR_APP_ID', + # app_secret: 'YOUR_APP_SECRET', # args: { scope: 'user:email' } } + # - { name: 'gitlab', app_id: 'YOUR_APP_ID', + # app_secret: 'YOUR_APP_SECRET', + # args: { scope: 'api' } } + # - { name: 'bitbucket', app_id: 'YOUR_APP_ID', + # app_secret: 'YOUR_APP_SECRET'} @@ -293,10 +286,19 @@ production: &base # piwik_url: '_your_piwik_url' # piwik_site_id: '_your_piwik_site_id' - ## Text under sign-in page (Markdown enabled) - # sign_in_text: | - #  - # [Learn more about CompanyName](http://www.companydomain.com/) + rack_attack: + git_basic_auth: + # Whitelist requests from 127.0.0.1 for web proxies (NGINX/Apache) with incorrect headers + # ip_whitelist: ["127.0.0.1"] + # + # Limit the number of Git HTTP authentication attempts per IP + # maxretry: 10 + # + # Reset the auth attempt counter per IP after 60 seconds + # findtime: 60 + # + # Ban an IP for one hour (3600s) after too many auth attempts + # bantime: 3600 development: <<: *base diff --git a/config/initializers/1_settings.rb b/config/initializers/1_settings.rb index 27bb83784ba..6a8bbb80b9c 100644 --- a/config/initializers/1_settings.rb +++ b/config/initializers/1_settings.rb @@ -13,7 +13,11 @@ class Settings < Settingslogic if gitlab_shell.ssh_port != 22 "ssh://#{gitlab_shell.ssh_user}@#{gitlab_shell.ssh_host}:#{gitlab_shell.ssh_port}/" else - "#{gitlab_shell.ssh_user}@#{gitlab_shell.ssh_host}:" + if gitlab_shell.ssh_host.include? ':' + "[#{gitlab_shell.ssh_user}@#{gitlab_shell.ssh_host}]:" + else + "#{gitlab_shell.ssh_user}@#{gitlab_shell.ssh_host}:" + end end end @@ -87,6 +91,7 @@ Settings['issues_tracker'] ||= {} # Settings['gitlab'] ||= Settingslogic.new({}) Settings.gitlab['default_projects_limit'] ||= 10 +Settings.gitlab['default_branch_protection'] ||= 2 Settings.gitlab['default_can_create_group'] = true if Settings.gitlab['default_can_create_group'].nil? Settings.gitlab['default_theme'] = Gitlab::Theme::MARS if Settings.gitlab['default_theme'].nil? Settings.gitlab['host'] ||= 'localhost' @@ -105,11 +110,12 @@ rescue ArgumentError # no user configured '/home/' + Settings.gitlab['user'] end Settings.gitlab['time_zone'] ||= nil -Settings.gitlab['signup_enabled'] ||= false +Settings.gitlab['signup_enabled'] ||= true if Settings.gitlab['signup_enabled'].nil? Settings.gitlab['signin_enabled'] ||= true if Settings.gitlab['signin_enabled'].nil? +Settings.gitlab['twitter_sharing_enabled'] ||= true if Settings.gitlab['twitter_sharing_enabled'].nil? Settings.gitlab['restricted_visibility_levels'] = Settings.send(:verify_constant_array, Gitlab::VisibilityLevel, Settings.gitlab['restricted_visibility_levels'], []) Settings.gitlab['username_changing_enabled'] = true if Settings.gitlab['username_changing_enabled'].nil? -Settings.gitlab['issue_closing_pattern'] = '([Cc]lose[sd]|[Ff]ixe[sd]) #(\d+)' if Settings.gitlab['issue_closing_pattern'].nil? +Settings.gitlab['issue_closing_pattern'] = '((?:[Cc]los(?:e[sd]?|ing)|[Ff]ix(?:e[sd]|ing)?|[Rr]esolv(?:e[sd]?|ing)) +(?:(?:issues? +)?#\d+(?:(?:, *| +and +)?))+)' if Settings.gitlab['issue_closing_pattern'].nil? Settings.gitlab['default_projects_features'] ||= {} Settings.gitlab['webhook_timeout'] ||= 10 Settings.gitlab.default_projects_features['issues'] = true if Settings.gitlab.default_projects_features['issues'].nil? @@ -148,7 +154,7 @@ Settings.gitlab_shell['ssh_path_prefix'] ||= Settings.send(:build_gitlab_shell_s Settings['backup'] ||= Settingslogic.new({}) Settings.backup['keep_time'] ||= 0 Settings.backup['path'] = File.expand_path(Settings.backup['path'] || "tmp/backups/", Rails.root) -Settings.backup['upload'] ||= Settingslogic.new({'remote_directory' => nil, 'connection' => nil}) +Settings.backup['upload'] ||= Settingslogic.new({ 'remote_directory' => nil, 'connection' => nil }) # Convert upload connection settings to use symbol keys, to make Fog happy if Settings.backup['upload']['connection'] Settings.backup['upload']['connection'] = Hash[Settings.backup['upload']['connection'].map { |k, v| [k.to_sym, v] }] @@ -172,6 +178,16 @@ Settings.satellites['timeout'] ||= 30 Settings['extra'] ||= Settingslogic.new({}) # +# Rack::Attack settings +# +Settings['rack_attack'] ||= Settingslogic.new({}) +Settings.rack_attack['git_basic_auth'] ||= Settingslogic.new({}) +Settings.rack_attack.git_basic_auth['ip_whitelist'] ||= %w{127.0.0.1} +Settings.rack_attack.git_basic_auth['maxretry'] ||= 10 +Settings.rack_attack.git_basic_auth['findtime'] ||= 1.minute +Settings.rack_attack.git_basic_auth['bantime'] ||= 1.hour + +# # Testing settings # if Rails.env.test? diff --git a/config/initializers/4_sidekiq.rb b/config/initializers/4_sidekiq.rb index 228b14cb526..e856499732e 100644 --- a/config/initializers/4_sidekiq.rb +++ b/config/initializers/4_sidekiq.rb @@ -14,7 +14,8 @@ Sidekiq.configure_server do |config| } config.server_middleware do |chain| - chain.add Gitlab::SidekiqMiddleware::ArgumentsLogger + chain.add Gitlab::SidekiqMiddleware::ArgumentsLogger if ENV['SIDEKIQ_LOG_ARGUMENTS'] + chain.add Gitlab::SidekiqMiddleware::MemoryKiller if ENV['SIDEKIQ_MEMORY_KILLER_MAX_RSS'] end end diff --git a/config/initializers/6_rack_profiler.rb b/config/initializers/6_rack_profiler.rb index a7ee3c59822..b6340287569 100644 --- a/config/initializers/6_rack_profiler.rb +++ b/config/initializers/6_rack_profiler.rb @@ -3,4 +3,6 @@ if Rails.env == 'development' # initialization is skipped so trigger it Rack::MiniProfilerRails.initialize!(Rails.application) + Rack::MiniProfiler.config.position = 'right' + Rack::MiniProfiler.config.start_hidden = true end diff --git a/config/initializers/7_omniauth.rb b/config/initializers/7_omniauth.rb index 18759f0cfb0..8f6c5673103 100644 --- a/config/initializers/7_omniauth.rb +++ b/config/initializers/7_omniauth.rb @@ -9,4 +9,4 @@ if Gitlab::LDAP::Config.enabled? server = Gitlab.config.ldap.servers.values.first alias_method server['provider_name'], :ldap end -end
\ No newline at end of file +end diff --git a/config/initializers/acts_as_taggable_on_patch.rb b/config/initializers/acts_as_taggable_on_patch.rb index baa77fde392..0d535cb5cac 100644 --- a/config/initializers/acts_as_taggable_on_patch.rb +++ b/config/initializers/acts_as_taggable_on_patch.rb @@ -42,11 +42,12 @@ module ActsAsTaggableOn::Taggable elsif options.delete(:any) # get tags, drop out if nothing returned (we need at least one) - tags = if options.delete(:wild) - ActsAsTaggableOn::Tag.named_like_any(tag_list) - else - ActsAsTaggableOn::Tag.named_any(tag_list) - end + tags = + if options.delete(:wild) + ActsAsTaggableOn::Tag.named_like_any(tag_list) + else + ActsAsTaggableOn::Tag.named_any(tag_list) + end return empty_result unless tags.length > 0 @@ -68,12 +69,12 @@ module ActsAsTaggableOn::Taggable select_clause = "DISTINCT #{table_name}.*" unless context and tag_types.one? if owned_by - tagging_join << " AND " + - sanitize_sql([ - "#{taggings_alias}.tagger_id = ? AND #{taggings_alias}.tagger_type = ?", - owned_by.id, - owned_by.class.base_class.to_s - ]) + tagging_join << " AND " + + sanitize_sql([ + "#{taggings_alias}.tagger_id = ? AND #{taggings_alias}.tagger_type = ?", + owned_by.id, + owned_by.class.base_class.to_s + ]) end joins << tagging_join @@ -92,12 +93,12 @@ module ActsAsTaggableOn::Taggable tagging_join << " AND " + sanitize_sql(["#{taggings_alias}.context = ?", context.to_s]) if context if owned_by - tagging_join << " AND " + - sanitize_sql([ - "#{taggings_alias}.tagger_id = ? AND #{taggings_alias}.tagger_type = ?", - owned_by.id, - owned_by.class.base_class.to_s - ]) + tagging_join << " AND " + + sanitize_sql([ + "#{taggings_alias}.tagger_id = ? AND #{taggings_alias}.tagger_type = ?", + owned_by.id, + owned_by.class.base_class.to_s + ]) end joins << tagging_join diff --git a/config/initializers/carrierwave.rb b/config/initializers/carrierwave.rb index d0065b63e54..bfb8656df55 100644 --- a/config/initializers/carrierwave.rb +++ b/config/initializers/carrierwave.rb @@ -12,22 +12,30 @@ if File.exists?(aws_file) aws_secret_access_key: AWS_CONFIG['secret_access_key'], # required region: AWS_CONFIG['region'], # optional, defaults to 'us-east-1' } - config.fog_directory = AWS_CONFIG['bucket'] # required - config.fog_public = false # optional, defaults to true - config.fog_attributes = {'Cache-Control'=>'max-age=315576000'} # optional, defaults to {} - config.fog_authenticated_url_expiration = 1 << 29 # optional time (in seconds) that authenticated urls will be valid. - # when fog_public is false and provider is AWS or Google, defaults to 600 + + # required + config.fog_directory = AWS_CONFIG['bucket'] + + # optional, defaults to true + config.fog_public = false + + # optional, defaults to {} + config.fog_attributes = { 'Cache-Control'=>'max-age=315576000' } + + # optional time (in seconds) that authenticated urls will be valid. + # when fog_public is false and provider is AWS or Google, defaults to 600 + config.fog_authenticated_url_expiration = 1 << 29 end # Mocking Fog requests, based on: https://github.com/carrierwaveuploader/carrierwave/wiki/How-to%3A-Test-Fog-based-uploaders if Rails.env.test? Fog.mock! connection = ::Fog::Storage.new( - :aws_access_key_id => AWS_CONFIG['access_key_id'], - :aws_secret_access_key => AWS_CONFIG['secret_access_key'], - :provider => 'AWS', - :region => AWS_CONFIG['region'] + aws_access_key_id: AWS_CONFIG['access_key_id'], + aws_secret_access_key: AWS_CONFIG['secret_access_key'], + provider: 'AWS', + region: AWS_CONFIG['region'] ) - connection.directories.create(:key => AWS_CONFIG['bucket']) + connection.directories.create(key: AWS_CONFIG['bucket']) end end diff --git a/config/initializers/devise.rb b/config/initializers/devise.rb index c6eb3e51036..79abe3c695d 100644 --- a/config/initializers/devise.rb +++ b/config/initializers/devise.rb @@ -145,7 +145,8 @@ Devise.setup do |config| # Time interval you can reset your password with a reset password key. # Don't put a too small interval or your users won't have the time to # change their passwords. - config.reset_password_within = 2.hours + # When someone else invites you to GitLab this time is also used so it should be pretty long. + config.reset_password_within = 2.days # ==> Configuration for :encryptable # Allow you to use another encryption algorithm besides bcrypt (default). You can use diff --git a/config/initializers/doorkeeper.rb b/config/initializers/doorkeeper.rb new file mode 100644 index 00000000000..9da7ebf4290 --- /dev/null +++ b/config/initializers/doorkeeper.rb @@ -0,0 +1,102 @@ +Doorkeeper.configure do + # Change the ORM that doorkeeper will use. + # Currently supported options are :active_record, :mongoid2, :mongoid3, :mongo_mapper + orm :active_record + + # This block will be called to check whether the resource owner is authenticated or not. + resource_owner_authenticator do + # Put your resource owner authentication logic here. + # Example implementation: + current_user || redirect_to(new_user_session_url) + end + + resource_owner_from_credentials do |routes| + u = User.find_by(email: params[:username]) + u if u && u.valid_password?(params[:password]) + end + + # If you want to restrict access to the web interface for adding oauth authorized applications, you need to declare the block below. + # admin_authenticator do + # # Put your admin authentication logic here. + # # Example implementation: + # Admin.find_by_id(session[:admin_id]) || redirect_to(new_admin_session_url) + # end + + # Authorization Code expiration time (default 10 minutes). + # authorization_code_expires_in 10.minutes + + # Access token expiration time (default 2 hours). + # If you want to disable expiration, set this to nil. + access_token_expires_in nil + + # Reuse access token for the same resource owner within an application (disabled by default) + # Rationale: https://github.com/doorkeeper-gem/doorkeeper/issues/383 + # reuse_access_token + + # Issue access tokens with refresh token (disabled by default) + use_refresh_token + + # Forces the usage of the HTTPS protocol in non-native redirect uris (enabled + # by default in non-development environments). OAuth2 delegates security in + # communication to the HTTPS protocol so it is wise to keep this enabled. + # + force_ssl_in_redirect_uri false + + # Provide support for an owner to be assigned to each registered application (disabled by default) + # Optional parameter confirmation: true (default false) if you want to enforce ownership of + # a registered application + # Note: you must also run the rails g doorkeeper:application_owner generator to provide the necessary support + enable_application_owner confirmation: false + + # Define access token scopes for your provider + # For more information go to + # https://github.com/doorkeeper-gem/doorkeeper/wiki/Using-Scopes + default_scopes :api + #optional_scopes :write, :update + + # Change the way client credentials are retrieved from the request object. + # By default it retrieves first from the `HTTP_AUTHORIZATION` header, then + # falls back to the `:client_id` and `:client_secret` params from the `params` object. + # Check out the wiki for more information on customization + # client_credentials :from_basic, :from_params + + # Change the way access token is authenticated from the request object. + # By default it retrieves first from the `HTTP_AUTHORIZATION` header, then + # falls back to the `:access_token` or `:bearer_token` params from the `params` object. + # Check out the wiki for more information on customization + access_token_methods :from_access_token_param, :from_bearer_authorization, :from_bearer_param + + # Change the native redirect uri for client apps + # When clients register with the following redirect uri, they won't be redirected to any server and the authorization code will be displayed within the provider + # The value can be any string. Use nil to disable this feature. When disabled, clients must provide a valid URL + # (Similar behaviour: https://developers.google.com/accounts/docs/OAuth2InstalledApp#choosingredirecturi) + # + native_redirect_uri nil#'urn:ietf:wg:oauth:2.0:oob' + + # Specify what grant flows are enabled in array of Strings. The valid + # strings and the flows they enable are: + # + # "authorization_code" => Authorization Code Grant Flow + # "implicit" => Implicit Grant Flow + # "password" => Resource Owner Password Credentials Grant Flow + # "client_credentials" => Client Credentials Grant Flow + # + # If not specified, Doorkeeper enables all the four grant flows. + # + # grant_flows %w(authorization_code implicit password client_credentials) + + # Under some circumstances you might want to have applications auto-approved, + # so that the user skips the authorization step. + # For example if dealing with trusted a application. + # skip_authorization do |resource_owner, client| + # client.superapp? or resource_owner.admin? + # end + + # WWW-Authenticate Realm (default "Doorkeeper"). + # realm "Doorkeeper" + + # Allow dynamic query parameters (disabled by default) + # Some applications require dynamic query parameters on their request_uri + # set to true if you want this to be allowed + # wildcard_redirect_uri false +end diff --git a/config/initializers/gitlab_shell_secret_token.rb b/config/initializers/gitlab_shell_secret_token.rb index 8d2b771e535..e7c9f0ba7c2 100644 --- a/config/initializers/gitlab_shell_secret_token.rb +++ b/config/initializers/gitlab_shell_secret_token.rb @@ -16,4 +16,4 @@ end if File.exist?(Gitlab.config.gitlab_shell.path) && !File.exist?(gitlab_shell_symlink) FileUtils.symlink(secret_file, gitlab_shell_symlink) -end
\ No newline at end of file +end diff --git a/config/initializers/public_key.rb b/config/initializers/public_key.rb new file mode 100644 index 00000000000..75d74e3625d --- /dev/null +++ b/config/initializers/public_key.rb @@ -0,0 +1,2 @@ +path = File.expand_path("~/.ssh/id_rsa.pub") +Gitlab::BitbucketImport.public_key = File.read(path) if File.exist?(path) diff --git a/config/initializers/rack_attack_git_basic_auth.rb b/config/initializers/rack_attack_git_basic_auth.rb new file mode 100644 index 00000000000..bbbfed68329 --- /dev/null +++ b/config/initializers/rack_attack_git_basic_auth.rb @@ -0,0 +1,12 @@ +unless Rails.env.test? + # Tell the Rack::Attack Rack middleware to maintain an IP blacklist. We will + # update the blacklist from Grack::Auth#authenticate_user. + Rack::Attack.blacklist('Git HTTP Basic Auth') do |req| + Rack::Attack::Allow2Ban.filter(req.ip, Gitlab.config.rack_attack.git_basic_auth) do + # This block only gets run if the IP was not already banned. + # Return false, meaning that we do not see anything wrong with the + # request at this time + false + end + end +end diff --git a/config/initializers/redis-store-fix-expiry.rb b/config/initializers/redis-store-fix-expiry.rb new file mode 100644 index 00000000000..fce0a135330 --- /dev/null +++ b/config/initializers/redis-store-fix-expiry.rb @@ -0,0 +1,44 @@ +# Monkey-patch Redis::Store to make 'setex' and 'expire' work with namespacing + +module Gitlab + class Redis + class Store + module Namespace + # Redis::Store#setex in redis-store 1.1.4 does not respect namespaces; + # this new method does. + def setex(key, expires_in, value, options=nil) + namespace(key) { |key| super(key, expires_in, value) } + end + + # Redis::Store#expire in redis-store 1.1.4 does not respect namespaces; + # this new method does. + def expire(key, expires_in) + namespace(key) { |key| super(key, expires_in) } + end + + private + + # Our new definitions of #setex and #expire above assume that the + # #namespace method exists. Because we cannot be sure of that, we + # re-implement the #namespace method from Redis::Store::Namespace so + # that it is available for all Redis::Store instances, whether they use + # namespacing or not. + # + # Based on lib/redis/store/namespace.rb L49-51 (redis-store 1.1.4) + def namespace(key) + if @namespace + yield interpolate(key) + else + # This Redis::Store instance does not use a namespace so we should + # just pass through the key. + yield key + end + end + end + end + end +end + +Redis::Store.class_eval do + include Gitlab::Redis::Store::Namespace +end diff --git a/config/initializers/smtp_settings.rb.sample b/config/initializers/smtp_settings.rb.sample index 3711b03796e..e00923e7e0c 100644 --- a/config/initializers/smtp_settings.rb.sample +++ b/config/initializers/smtp_settings.rb.sample @@ -1,4 +1,4 @@ -# To enable smtp email delivery for your GitLab instance do next: +# To enable smtp email delivery for your GitLab instance do the following: # 1. Rename this file to smtp_settings.rb # 2. Edit settings inside this file # 3. Restart GitLab instance @@ -13,6 +13,7 @@ if Rails.env.production? password: "123456", domain: "gitlab.company.com", authentication: :login, - enable_starttls_auto: true + enable_starttls_auto: true, + openssl_verify_mode: 'none' } end diff --git a/config/initializers/static_files.rb b/config/initializers/static_files.rb new file mode 100644 index 00000000000..d9042c652bb --- /dev/null +++ b/config/initializers/static_files.rb @@ -0,0 +1,15 @@ +app = Rails.application + +if app.config.serve_static_assets + # The `ActionDispatch::Static` middleware intercepts requests for static files + # by checking if they exist in the `/public` directory. + # We're replacing it with our `Gitlab::Middleware::Static` that does the same, + # except ignoring `/uploads`, letting those go through to the GitLab Rails app. + + app.config.middleware.swap( + ActionDispatch::Static, + Gitlab::Middleware::Static, + app.paths["public"].first, + app.config.static_cache_control + ) +end diff --git a/config/locales/doorkeeper.en.yml b/config/locales/doorkeeper.en.yml new file mode 100644 index 00000000000..c5b6b75e7f6 --- /dev/null +++ b/config/locales/doorkeeper.en.yml @@ -0,0 +1,73 @@ +en: + activerecord: + errors: + models: + application: + attributes: + redirect_uri: + fragment_present: 'cannot contain a fragment.' + invalid_uri: 'must be a valid URI.' + relative_uri: 'must be an absolute URI.' + mongoid: + errors: + models: + application: + attributes: + redirect_uri: + fragment_present: 'cannot contain a fragment.' + invalid_uri: 'must be a valid URI.' + relative_uri: 'must be an absolute URI.' + mongo_mapper: + errors: + models: + application: + attributes: + redirect_uri: + fragment_present: 'cannot contain a fragment.' + invalid_uri: 'must be a valid URI.' + relative_uri: 'must be an absolute URI.' + doorkeeper: + errors: + messages: + # Common error messages + invalid_request: 'The request is missing a required parameter, includes an unsupported parameter value, or is otherwise malformed.' + invalid_redirect_uri: 'The redirect uri included is not valid.' + unauthorized_client: 'The client is not authorized to perform this request using this method.' + access_denied: 'The resource owner or authorization server denied the request.' + invalid_scope: 'The requested scope is invalid, unknown, or malformed.' + server_error: 'The authorization server encountered an unexpected condition which prevented it from fulfilling the request.' + temporarily_unavailable: 'The authorization server is currently unable to handle the request due to a temporary overloading or maintenance of the server.' + + #configuration error messages + credential_flow_not_configured: 'Resource Owner Password Credentials flow failed due to Doorkeeper.configure.resource_owner_from_credentials being unconfigured.' + resource_owner_authenticator_not_configured: 'Resource Owner find failed due to Doorkeeper.configure.resource_owner_authenticator being unconfiged.' + + # Access grant errors + unsupported_response_type: 'The authorization server does not support this response type.' + + # Access token errors + invalid_client: 'Client authentication failed due to unknown client, no client authentication included, or unsupported authentication method.' + invalid_grant: 'The provided authorization grant is invalid, expired, revoked, does not match the redirection URI used in the authorization request, or was issued to another client.' + unsupported_grant_type: 'The authorization grant type is not supported by the authorization server.' + + # Password Access token errors + invalid_resource_owner: 'The provided resource owner credentials are not valid, or resource owner cannot be found' + + invalid_token: + revoked: "The access token was revoked" + expired: "The access token expired" + unknown: "The access token is invalid" + scopes: + api: Access your API + + flash: + applications: + create: + notice: 'Application created.' + destroy: + notice: 'Application deleted.' + update: + notice: 'Application updated.' + authorized_applications: + destroy: + notice: 'Application revoked.' diff --git a/config/routes.rb b/config/routes.rb index 2534153758b..35053bdb20f 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -2,11 +2,16 @@ require 'sidekiq/web' require 'api/api' Gitlab::Application.routes.draw do + use_doorkeeper do + controllers applications: 'oauth/applications', + authorized_applications: 'oauth/authorized_applications', + authorizations: 'oauth/authorizations' + end # # Search # - get 'search' => "search#show" - get 'search/autocomplete' => "search#autocomplete", as: :search_autocomplete + get 'search' => 'search#show' + get 'search/autocomplete' => 'search#autocomplete', as: :search_autocomplete # API API::API.logger Rails.logger @@ -15,9 +20,9 @@ Gitlab::Application.routes.draw do # Get all keys of user get ':username.keys' => 'profiles/keys#get_keys' , constraints: { username: /.*/ } - constraint = lambda { |request| request.env["warden"].authenticate? and request.env['warden'].user.admin? } + constraint = lambda { |request| request.env['warden'].authenticate? and request.env['warden'].user.admin? } constraints constraint do - mount Sidekiq::Web, at: "/admin/sidekiq", as: :sidekiq + mount Sidekiq::Web, at: '/admin/sidekiq', as: :sidekiq end # Enable Grack support @@ -41,13 +46,59 @@ Gitlab::Application.routes.draw do # resources :snippets do member do - get "raw" + get 'raw' + end + end + get '/s/:username' => 'snippets#user_index', as: :user_snippets, constraints: { username: /.*/ } + + + # + # Import + # + namespace :import do + resource :github, only: [:create, :new], controller: :github do + get :status + get :callback + get :jobs + end + + resource :gitlab, only: [:create, :new], controller: :gitlab do + get :status + get :callback + get :jobs + end + + resource :bitbucket, only: [:create, :new], controller: :bitbucket do + get :status + get :callback + get :jobs + end + + resource :gitorious, only: [:create, :new], controller: :gitorious do + get :status + get :callback + get :jobs end end - get "/s/:username" => "snippets#user_index", as: :user_snippets, constraints: { username: /.*/ } # - # Explroe area + # Uploads + # + + scope path: :uploads do + # Note attachments and User/Group/Project avatars + get ":model/:mounted_as/:id/:filename", + to: "uploads#show", + constraints: { model: /note|user|group|project/, mounted_as: /avatar|attachment/, filename: /.+/ } + + # Project markdown uploads + get ":namespace_id/:project_id/:secret/:filename", + to: "projects/uploads#show", + constraints: { namespace_id: /[a-zA-Z.0-9_\-]+/, project_id: /[a-zA-Z.0-9_\-]+/, filename: /.+/ } + end + + # + # Explore area # namespace :explore do resources :projects, only: [:index] do @@ -58,23 +109,19 @@ Gitlab::Application.routes.draw do end resources :groups, only: [:index] - root to: "projects#trending" + root to: 'projects#trending' end # Compatibility with old routing - get 'public' => "explore/projects#index" - get 'public/projects' => "explore/projects#index" - - # - # Attachments serving - # - get 'files/:type/:id/:filename' => 'files#download', constraints: { id: /\d+/, type: /[a-z]+/, filename: /.+/ } + get 'public' => 'explore/projects#index' + get 'public/projects' => 'explore/projects#index' # # Admin Area # namespace :admin do resources :users, constraints: { id: /[a-zA-Z.\/0-9_\-]+/ } do + resources :keys, only: [:show, :destroy] member do put :team_update put :block @@ -83,6 +130,8 @@ Gitlab::Application.routes.draw do end end + resources :applications + resources :groups, constraints: { id: /[^\/]+/ } do member do put :project_teams_update @@ -97,13 +146,26 @@ Gitlab::Application.routes.draw do resource :logs, only: [:show] resource :background_jobs, controller: 'background_jobs', only: [:show] - resources :projects, constraints: { id: /[a-zA-Z.\/0-9_\-]+/ }, only: [:index, :show] do - member do - put :transfer + resources :namespaces, path: '/projects', constraints: { id: /[a-zA-Z.0-9_\-]+/ }, only: [] do + root to: 'projects#index', as: :projects + + resources(:projects, + path: '/', + constraints: { id: /[a-zA-Z.0-9_\-]+/ }, + only: [:index, :show]) do + root to: 'projects#show' + + member do + put :transfer + end end end - root to: "dashboard#index" + resource :application_settings, only: [:show, :update] do + resources :services + end + + root to: 'dashboard#index' end # @@ -113,6 +175,7 @@ Gitlab::Application.routes.draw do member do get :history get :design + get :applications put :reset_private_token put :update_username @@ -137,12 +200,16 @@ Gitlab::Application.routes.draw do end end - match "/u/:username" => "users#show", as: :user, constraints: { username: /.*/ }, via: :get + get 'u/:username/calendar' => 'users#calendar', as: :user_calendar, + constraints: { username: /(?:[^.]|\.(?!atom$))+/, format: /atom/ } + + get '/u/:username' => 'users#show', as: :user, + constraints: { username: /(?:[^.]|\.(?!atom$))+/, format: /atom/ } # # Dashboard Area # - resource :dashboard, controller: "dashboard", only: [:show] do + resource :dashboard, controller: 'dashboard', only: [:show] do member do get :projects get :issues @@ -153,7 +220,7 @@ Gitlab::Application.routes.draw do # # Groups Area # - resources :groups, constraints: {id: /(?:[^.]|\.(?!atom$))+/, format: /atom/} do + resources :groups, constraints: { id: /(?:[^.]|\.(?!atom$))+/, format: /atom/ } do member do get :issues get :merge_requests @@ -173,170 +240,225 @@ Gitlab::Application.routes.draw do devise_for :users, controllers: { omniauth_callbacks: :omniauth_callbacks, registrations: :registrations , passwords: :passwords, sessions: :sessions, confirmations: :confirmations } devise_scope :user do - get "/users/auth/:provider/omniauth_error" => "omniauth_callbacks#omniauth_error", as: :omniauth_error + get '/users/auth/:provider/omniauth_error' => 'omniauth_callbacks#omniauth_error', as: :omniauth_error end + + root to: "dashboard#show" + # # Project Area # - resources :projects, constraints: { id: /[a-zA-Z.0-9_\-]+\/[a-zA-Z.0-9_\-]+/ }, except: [:new, :create, :index], path: "/" do - member do - put :transfer - post :fork - post :archive - post :unarchive - post :upload_image - post :toggle_star - get :autocomplete_sources - get :import - put :retry_import - end - - scope module: :projects do - resources :blob, only: [:show, :destroy], constraints: { id: /.+/ } do - get :diff, on: :member - end - resources :raw, only: [:show], constraints: {id: /.+/} - resources :tree, only: [:show], constraints: {id: /.+/, format: /(html|js)/ } - resources :edit_tree, only: [:show, :update], constraints: { id: /.+/ }, path: 'edit' do - post :preview, on: :member + resources :namespaces, path: '/', constraints: { id: /[a-zA-Z.0-9_\-]+/ }, only: [] do + resources(:projects, constraints: { id: /[a-zA-Z.0-9_\-]+/ }, except: + [:new, :create, :index], path: "/") do + member do + put :transfer + post :archive + post :unarchive + post :toggle_star + post :markdown_preview + get :autocomplete_sources end - resources :new_tree, only: [:show, :update], constraints: {id: /.+/}, path: 'new' - resources :commit, only: [:show], constraints: {id: /[[:alnum:]]{6,40}/} - resources :commits, only: [:show], constraints: {id: /(?:[^.]|\.(?!atom$))+/, format: /atom/} - resources :compare, only: [:index, :create] - resources :blame, only: [:show], constraints: {id: /.+/} - resources :network, only: [:show], constraints: {id: /(?:[^.]|\.(?!json$))+/, format: /json/} - resources :graphs, only: [:show], constraints: {id: /(?:[^.]|\.(?!json$))+/, format: /json/} do - member do - get :commits + + scope module: :projects do + # Blob routes: + get '/new/*id', to: 'blob#new', constraints: { id: /.+/ }, as: 'new_blob' + post '/create/*id', to: 'blob#create', constraints: { id: /.+/ }, as: 'create_blob' + get '/edit/*id', to: 'blob#edit', constraints: { id: /.+/ }, as: 'edit_blob' + put '/update/*id', to: 'blob#update', constraints: { id: /.+/ }, as: 'update_blob' + post '/preview/*id', to: 'blob#preview', constraints: { id: /.+/ }, as: 'preview_blob' + + scope do + get( + '/blob/*id/diff', + to: 'blob#diff', + constraints: { id: /.+/, format: false }, + as: :blob_diff + ) + get( + '/blob/*id', + to: 'blob#show', + constraints: { id: /.+/, format: false }, + as: :blob + ) + delete( + '/blob/*id', + to: 'blob#destroy', + constraints: { id: /.+/, format: false } + ) + end + + scope do + get( + '/raw/*id', + to: 'raw#show', + constraints: { id: /.+/, format: /(html|js)/ }, + as: :raw + ) end - end - match "/compare/:from...:to" => "compare#show", as: "compare", via: [:get, :post], constraints: {from: /.+/, to: /.+/} + scope do + get( + '/tree/*id', + to: 'tree#show', + constraints: { id: /.+/, format: /(html|js)/ }, + as: :tree + ) + end + resource :avatar, only: [:show, :destroy] + + resources :commit, only: [:show], constraints: { id: /[[:alnum:]]{6,40}/ } do + get :branches, on: :member + end - resources :snippets, constraints: {id: /\d+/} do + resources :commits, only: [:show], constraints: { id: /(?:[^.]|\.(?!atom$))+/, format: /atom/ } + resources :compare, only: [:index, :create] + + scope do + get( + '/blame/*id', + to: 'blame#show', + constraints: { id: /.+/, format: /(html|js)/ }, + as: :blame + ) + end + + resources :network, only: [:show], constraints: { id: /(?:[^.]|\.(?!json$))+/, format: /json/ } + resources :graphs, only: [:show], constraints: { id: /(?:[^.]|\.(?!json$))+/, format: /json/ } do member do - get "raw" + get :commits end end - resources :wikis, only: [:show, :edit, :destroy, :create], constraints: {id: /[a-zA-Z.0-9_\-\/]+/} do - collection do - get :pages - put ':id' => 'wikis#update' - get :git_access + get '/compare/:from...:to' => 'compare#show', :as => 'compare', + :constraints => { from: /.+/, to: /.+/ } + + resources :snippets, constraints: { id: /\d+/ } do + member do + get 'raw' + end end - member do - get "history" + resources :wikis, only: [:show, :edit, :destroy, :create], constraints: { id: /[a-zA-Z.0-9_\-\/]+/ } do + collection do + get :pages + put ':id' => 'wikis#update' + get :git_access + end + + member do + get 'history' + end end - end - resource :repository, only: [:show] do - member do - get "archive", constraints: { format: Gitlab::Regex.archive_formats_regex } + resource :repository, only: [:show, :create] do + member do + get 'archive', constraints: { format: Gitlab::Regex.archive_formats_regex } + end end - end - resources :services, constraints: { id: /[^\/]+/ }, only: [:index, :edit, :update] do - member do - get :test + resources :services, constraints: { id: /[^\/]+/ }, only: [:index, :edit, :update] do + member do + get :test + end end - end - resources :deploy_keys, constraints: {id: /\d+/} do - member do - put :enable - put :disable + resources :deploy_keys, constraints: { id: /\d+/ } do + member do + put :enable + put :disable + end end - end - resources :branches, only: [:index, :new, :create, :destroy], constraints: { id: Gitlab::Regex.git_reference_regex } - resources :tags, only: [:index, :new, :create, :destroy], constraints: { id: Gitlab::Regex.git_reference_regex } - resources :protected_branches, only: [:index, :create, :destroy], constraints: { id: Gitlab::Regex.git_reference_regex } + resource :fork, only: [:new, :create] + resource :import, only: [:new, :create, :show] - resources :refs, only: [] do - collection do - get "switch" - end + resources :refs, only: [] do + collection do + get 'switch' + end - member do - # tree viewer logs - get "logs_tree", constraints: { id: Gitlab::Regex.git_reference_regex } - get "logs_tree/:path" => "refs#logs_tree", - as: :logs_file, - constraints: { - id: Gitlab::Regex.git_reference_regex, + member do + # tree viewer logs + get 'logs_tree', constraints: { id: Gitlab::Regex.git_reference_regex } + get 'logs_tree/:path' => 'refs#logs_tree', as: :logs_file, constraints: { + id: Gitlab::Regex.git_reference_regex, path: /.*/ } + end end - end - resources :merge_requests, constraints: {id: /\d+/}, except: [:destroy] do - member do - get :diffs - post :automerge - get :automerge_check - get :ci_status - end + resources :merge_requests, constraints: { id: /\d+/ }, except: [:destroy] do + member do + get :diffs + post :automerge + get :automerge_check + get :ci_status + end - collection do - get :branch_from - get :branch_to - get :update_branches + collection do + get :branch_from + get :branch_to + get :update_branches + end end - end - resources :hooks, only: [:index, :create, :destroy], constraints: {id: /\d+/} do - member do - get :test + resources :branches, only: [:index, :new, :create, :destroy], constraints: { id: Gitlab::Regex.git_reference_regex } + resources :tags, only: [:index, :new, :create, :destroy], constraints: { id: Gitlab::Regex.git_reference_regex } + resources :protected_branches, only: [:index, :create, :update, :destroy], constraints: { id: Gitlab::Regex.git_reference_regex } + + resources :hooks, only: [:index, :create, :destroy], constraints: { id: /\d+/ } do + member do + get :test + end end - end - resources :team, controller: 'team_members', only: [:index] - resources :milestones, except: [:destroy], constraints: {id: /\d+/} do - member do - put :sort_issues - put :sort_merge_requests + resources :team, controller: 'team_members', only: [:index] + resources :milestones, except: [:destroy], constraints: { id: /\d+/ } do + member do + put :sort_issues + put :sort_merge_requests + end end - end - resources :labels, constraints: {id: /\d+/} do - collection do - post :generate + resources :labels, constraints: { id: /\d+/ } do + collection do + post :generate + end end - end - resources :issues, constraints: {id: /\d+/}, except: [:destroy] do - collection do - post :bulk_update + resources :issues, constraints: { id: /\d+/ }, except: [:destroy] do + collection do + post :bulk_update + end end - end - resources :team_members, except: [:index, :edit], constraints: { id: /[a-zA-Z.\/0-9_\-#%+]+/ } do - collection do - delete :leave + resources :team_members, except: [:index, :edit], constraints: { id: /[a-zA-Z.\/0-9_\-#%+]+/ } do + collection do + delete :leave - # Used for import team - # from another project - get :import - post :apply_import + # Used for import team + # from another project + get :import + post :apply_import + end end - end - resources :notes, only: [:index, :create, :destroy, :update], constraints: {id: /\d+/} do - member do - delete :delete_attachment + resources :notes, only: [:index, :create, :destroy, :update], constraints: { id: /\d+/ } do + member do + delete :delete_attachment + end end - collection do - post :preview + resources :uploads, only: [:create] do + collection do + get ":secret/:filename", action: :show, as: :show, constraints: { filename: /.+/ } + end end end + end end - get ':id' => "namespaces#show", constraints: {id: /(?:[^.]|\.(?!atom$))+/, format: /atom/} - - root to: "dashboard#show" + get ':id' => 'namespaces#show', constraints: { id: /(?:[^.]|\.(?!atom$))+/, format: /atom/ } end diff --git a/config/unicorn.rb.example b/config/unicorn.rb.example index ea22744fd90..d8b4f5c7c32 100644 --- a/config/unicorn.rb.example +++ b/config/unicorn.rb.example @@ -13,9 +13,9 @@ # # ENV['RAILS_RELATIVE_URL_ROOT'] = "/gitlab" -# Use at least one worker per core if you're on a dedicated server, -# more will usually help for _short_ waits on databases/caches. -# The minimum is 2 +# Read about unicorn workers here: +# http://doc.gitlab.com/ee/install/requirements.html#unicorn-workers +# worker_processes 2 # Since Unicorn is never exposed to outside clients, it does not need to @@ -37,10 +37,10 @@ listen "127.0.0.1:8080", :tcp_nopush => true # nuke workers after 30 seconds instead of 60 seconds (the default) # -# NOTICE: git push over http depends on this value. -# If you want be able to push huge amount of data to git repository over http -# you will have to increase this value too. -# +# NOTICE: git push over http depends on this value. +# If you want be able to push huge amount of data to git repository over http +# you will have to increase this value too. +# # Example of output if you try to push 1GB repo to GitLab over http. # -> git push http://gitlab.... master # |