diff --git a/app/assets/stylesheets/framework/common.scss b/app/assets/stylesheets/framework/common.scss
index 18044b25b8722d26d722afb89025a0946ebaedf2..0931090b8404dab8c59cc95f904ba374effb9d68 100644
--- a/app/assets/stylesheets/framework/common.scss
+++ b/app/assets/stylesheets/framework/common.scss
@@ -383,35 +383,25 @@ table {
   margin-right: -$gl-padding;
   border-top: 1px solid $border-color;
 }
-.message {
-  border: 1px solid #ccc;
-  padding: 10px;
-  color: #333;
-}
-.message {
-  border: 1px solid #ccc;
-  padding: 10px;
-  color: #333;
-}
 
-.group-projects-show-title{
-    h1 {
-      color: #313236;
-      margin: 0;
-      margin-bottom: 6px;
-      font-size: 23px;
-      font-weight: normal;
-    }
+.cover-title{
+  h1 {
+    color: #313236;
+    margin: 0;
+    margin-bottom: 6px;
+    font-size: 23px;
+    font-weight: normal;
+  }
 
-    .visibility-icon {
-      display: inline-block;
-      margin-left: 5px;
-      font-size: 18px;
-      color: $gray;
-    }
+  .visibility-icon {
+    display: inline-block;
+    margin-left: 5px;
+    font-size: 18px;
+    color: $gray;
+  }
 
-    p {
-      padding: 0 $gl-padding;
-      color: #5c5d5e;
-    }
+  p {
+    padding: 0 $gl-padding;
+    color: #5c5d5e;
   }
+}
diff --git a/app/assets/stylesheets/framework/mobile.scss b/app/assets/stylesheets/framework/mobile.scss
index 3bfac2ad9b558871a7fef2ea89e75716899b27ca..d088228fe4c59e4d5015864f1df8c52fd60a0d1b 100644
--- a/app/assets/stylesheets/framework/mobile.scss
+++ b/app/assets/stylesheets/framework/mobile.scss
@@ -48,7 +48,7 @@
       display: block;
     }
 
-    .project-home-desc {
+    #project-home-desc {
       font-size: 21px;
     }
 
diff --git a/app/assets/stylesheets/pages/projects.scss b/app/assets/stylesheets/pages/projects.scss
index b1b76edfb327789c8d732938459ece9349eae982..1a7b0c1e278332969a1cfb8cbedc6ba28882963d 100644
--- a/app/assets/stylesheets/pages/projects.scss
+++ b/app/assets/stylesheets/pages/projects.scss
@@ -61,28 +61,6 @@
     }
   }
 
-  .project-home-desc {
-    h1 {
-      color: #313236;
-      margin: 0;
-      margin-bottom: 6px;
-      font-size: 23px;
-      font-weight: normal;
-    }
-
-    .visibility-icon {
-      display: inline-block;
-      margin-left: 5px;
-      font-size: 18px;
-      color: $gray;
-    }
-
-    p {
-      padding: 0 $gl-padding;
-      color: #5c5d5e;
-    }
-  }
-
   .project-repo-buttons {
     margin-top: 20px;
     margin-bottom: 0px;
diff --git a/app/controllers/groups_controller.rb b/app/controllers/groups_controller.rb
index 54f14e62ead5456703e833745b5823272b553090..5baeb3def0860bc8a5f43b0815a039db81789106 100644
--- a/app/controllers/groups_controller.rb
+++ b/app/controllers/groups_controller.rb
@@ -29,10 +29,8 @@ class GroupsController < Groups::ApplicationController
 
   def create
     @group = Group.new(group_params)
-    @group.name = @group.path.dup unless @group.name
 
-    if @group.save
-      @group.add_owner(current_user)
+    if Groups::CreateService.new(@group, current_user, group_params).execute
       redirect_to @group, notice: "Group '#{@group.name}' was successfully created."
     else
       render action: "new"
diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb
index 7b32572f82295d168104db825f3164d48821284a..481d00d6aaebd804c6a745a50ca4671501cd9553 100644
--- a/app/controllers/users_controller.rb
+++ b/app/controllers/users_controller.rb
@@ -3,13 +3,6 @@ class UsersController < ApplicationController
   before_action :set_user
 
   def show
-    @contributed_projects = contributed_projects.joined(@user).reject(&:forked?)
-
-    @projects = PersonalProjectsFinder.new(@user).execute(current_user)
-    @projects = @projects.page(params[:page]).per(PER_PAGE)
-
-    @groups =  JoinedGroupsFinder.new(@user).execute(current_user)
-
     respond_to do |format|
       format.html
 
@@ -115,7 +108,7 @@ class UsersController < ApplicationController
   end
 
   def load_groups
-    @groups = @user.groups.order_id_desc
+    @groups = JoinedGroupsFinder.new(@user).execute(current_user)
   end
 
   def projects_for_current_user
diff --git a/app/finders/joined_groups_finder.rb b/app/finders/joined_groups_finder.rb
index 131b518563e7c431a1a3cf6bdcff95659b7b6514..fbdf492c9650d8b7a0e298c6d742f667463a8fcc 100644
--- a/app/finders/joined_groups_finder.rb
+++ b/app/finders/joined_groups_finder.rb
@@ -1,6 +1,6 @@
 #Shows only authorized groups of a user
 class JoinedGroupsFinder
-  def initialize(user = nil)
+  def initialize(user)
     @user = user
   end
 
diff --git a/app/models/ability.rb b/app/models/ability.rb
index fe460ccdaca3b12037d0e657e96e64b1124ade1d..bd001ef154525d305e7a2f4da851713a35745753 100644
--- a/app/models/ability.rb
+++ b/app/models/ability.rb
@@ -295,8 +295,8 @@ class Ability
     end
 
     def can_read_group?(user, group)
-      is_project_member = ProjectsFinder.new.execute(user, group: group).any?
-      user.admin? || group.public? || group.internal? || is_project_member || group.users.include?(user)
+      user.admin? || group.public? || group.internal? || group.users.include?(user) ||
+      ProjectsFinder.new.execute(user, group: group).any?
     end
 
     def namespace_abilities(user, namespace)
diff --git a/app/services/groups/base_service.rb b/app/services/groups/base_service.rb
index 5becd475d3a156e68b4737e8879a92af246c2417..644ec7c013e4039262ee397b9f84f5c870947778 100644
--- a/app/services/groups/base_service.rb
+++ b/app/services/groups/base_service.rb
@@ -5,5 +5,9 @@ module Groups
     def initialize(group, user, params = {})
       @group, @current_user, @params = group, user, params.dup
     end
+
+    def add_error_message(message)
+      group.errors.add(:visibility_level, message)
+    end
   end
 end
diff --git a/app/services/groups/create_service.rb b/app/services/groups/create_service.rb
new file mode 100644
index 0000000000000000000000000000000000000000..e2875aafb94708473e18ac4f11b5d38777c82803
--- /dev/null
+++ b/app/services/groups/create_service.rb
@@ -0,0 +1,17 @@
+module Groups
+  class CreateService < Groups::BaseService
+    def execute
+      return false unless visibility_level_allowed?(params[:visibility_level])
+      @group.name = @group.path.dup unless @group.name
+      @group.save(params) && @group.add_owner(current_user)
+    end
+
+    private
+
+    def visibility_level_allowed?(level)
+      allowed = Gitlab::VisibilityLevel.allowed_for?(current_user, params[:visibility_level])
+      add_error_message("Visibility level restricted by admin.") unless allowed
+      allowed
+    end
+  end
+end
diff --git a/app/services/groups/update_service.rb b/app/services/groups/update_service.rb
index acb6c529c173b1735962ae477e34682da0f5d6cc..a7382c1e07cb4393fa43511bab36048b3e1459de 100644
--- a/app/services/groups/update_service.rb
+++ b/app/services/groups/update_service.rb
@@ -5,7 +5,8 @@
 module Groups
   class UpdateService < Groups::BaseService
     def execute
-      visibility_level_allowed?(params[:visibility_level]) ? group.update_attributes(params) : false
+      return false unless visibility_level_allowed?(params[:visibility_level])
+      group.update_attributes(params)
     end
 
     private
@@ -22,7 +23,7 @@ module Groups
     def visibility_by_project(level)
       projects_visibility = group.projects.pluck(:visibility_level)
 
-      allowed_by_projects = !projects_visibility.any?{|project_visibility| level.to_i < project_visibility }
+      allowed_by_projects = !projects_visibility.any?{ |project_visibility| level.to_i < project_visibility }
       add_error_message("Cannot be changed. There are projects with higher visibility permissions.") unless allowed_by_projects
       allowed_by_projects
     end
@@ -32,13 +33,5 @@ module Groups
       add_error_message("You are not authorized to set this permission level.") unless allowed_by_user
       allowed_by_user
     end
-
-    def add_error_message(message)
-      level_name = Gitlab::VisibilityLevel.level_name(params[:visibility_level])
-      group.errors.add(:visibility_level, message)
-    end
   end
 end
-
-
-
diff --git a/app/services/projects/create_service.rb b/app/services/projects/create_service.rb
index 522fae79503f9a6bfbb07ca25958e4718f595781..4c121106bda9590d6670872321ad9580fd8aa59f 100644
--- a/app/services/projects/create_service.rb
+++ b/app/services/projects/create_service.rb
@@ -12,7 +12,7 @@ module Projects
       # Make sure that the user is allowed to use the specified visibility
       # level
 
-      unless Gitlab::VisibilityLevel.allowed_for?(current_user, params[:visibility_level]) && @project.visibility_level_allowed?(@project.visibility_level)
+      unless visibility_level_allowed?
         deny_visibility_level(@project)
         return @project
       end
@@ -100,5 +100,9 @@ module Projects
 
       @project.import_start if @project.import?
     end
+
+    def visibility_level_allowed?
+      Gitlab::VisibilityLevel.allowed_for?(current_user, params[:visibility_level]) && @project.visibility_level_allowed?(@project.visibility_level)
+    end
   end
 end
diff --git a/app/views/groups/show.html.haml b/app/views/groups/show.html.haml
index 0a8c2da72077459b2b85b7d5bf7e9f5a4acf1e8e..641191edf058d9880d27acae073e1cd6845d06dd 100644
--- a/app/views/groups/show.html.haml
+++ b/app/views/groups/show.html.haml
@@ -14,11 +14,11 @@
   .avatar-holder
     = link_to group_icon(@group), target: '_blank' do
       = image_tag group_icon(@group), class: "avatar group-avatar s90"
-  .group-projects-show-title
+  .cover-title
     %h1
       = @group.name
 
-      %span.visibility-icon.has_tooltip{data: { container: 'body', placement: 'left' }, title: "#{visibility_level_label(@group.visibility_level)} - #{project_visibility_level_description(@group.visibility_level)}"}
+      %span.visibility-icon.has_tooltip{data: { container: 'body', placement: 'left' }, title: "#{visibility_level_label(@group.visibility_level)} - #{group_visibility_description(@group)}"}
         = visibility_level_icon(@group.visibility_level, fw: false)
 
   .cover-desc.username
diff --git a/app/views/projects/_home_panel.html.haml b/app/views/projects/_home_panel.html.haml
index dd16f504c92d13bd2fcec8a317a75f52080ba3b2..e8434b5292cb1063016e46420ad4fb0fb2341d39 100644
--- a/app/views/projects/_home_panel.html.haml
+++ b/app/views/projects/_home_panel.html.haml
@@ -2,7 +2,7 @@
 .project-home-panel.cover-block.clearfix{:class => ("empty-project" if empty_repo)}
   .project-identicon-holder
     = project_icon(@project, alt: '', class: 'project-avatar avatar s90')
-  .group-projects-show-title
+  .cover-title#project-home-desc
     %h1
       = @project.name
       %span.visibility-icon.has_tooltip{data: { container: 'body' },
diff --git a/db/migrate/20160308212903_add_default_group_visibility_to_application_settings.rb b/db/migrate/20160308212903_add_default_group_visibility_to_application_settings.rb
index c2bdd7b31faa80a3d5acefa21adc53bdf7d2a81b..b71322376fa8a45d69ca499b96ac99ab35eb8792 100644
--- a/db/migrate/20160308212903_add_default_group_visibility_to_application_settings.rb
+++ b/db/migrate/20160308212903_add_default_group_visibility_to_application_settings.rb
@@ -1,11 +1,27 @@
+#Create visibility level field on DB
+#Sets default_visibility_level to value on settings if not restricted
+#If value is restricted takes higher visibility level allowed
+
 class AddDefaultGroupVisibilityToApplicationSettings < ActiveRecord::Migration
   def up
     add_column :application_settings, :default_group_visibility, :integer
-    visibility = Settings.gitlab.default_groups_features['visibility_level']
-    execute("update application_settings set default_group_visibility = #{visibility}")
+    execute("update application_settings set default_group_visibility = #{allowed_visibility_level}")
   end
 
   def down
     remove_column :application_settings, :default_group_visibility
   end
+
+  private
+  def allowed_visibility_level
+    default_visibility = Settings.gitlab.default_groups_features['visibility_level']
+    restricted_levels  = current_application_settings.restricted_visibility_levels
+    return default_visibility unless restricted_levels.present?
+
+    if restricted_levels.include?(default_visibility)
+      Gitlab::VisibilityLevel.values.select{ |vis_level| vis_level unless restricted_levels.include?(vis_level) }.last
+    else
+      default_visibility
+    end
+  end
 end
diff --git a/db/schema.rb b/db/schema.rb
index 082d681a1763a581856e179a4c36974e9895330e..292a9100d9c40a212ff1488e2e7dc913e70b0458 100644
--- a/db/schema.rb
+++ b/db/schema.rb
@@ -11,7 +11,7 @@
 #
 # It's strongly recommended that you check this file into your version control system.
 
-ActiveRecord::Schema.define(version: 20160308212903) do
+ActiveRecord::Schema.define(version: 20160309140734) do
 
   # These are extensions that must be enabled in order to support this database
   enable_extension "plpgsql"
diff --git a/spec/features/security/group/internal_access_spec.rb b/spec/features/security/group/internal_access_spec.rb
index 69a0fbb446845503102ae6d5a81cd6a50ea0d829..4e781c23ee04f54b7eba8d2eae558beec910f11e 100644
--- a/spec/features/security/group/internal_access_spec.rb
+++ b/spec/features/security/group/internal_access_spec.rb
@@ -4,8 +4,6 @@ describe 'Internal group access', feature: true do
   include AccessMatchers
   include GroupAccessHelper
 
-
-
   describe 'GET /groups/:path' do
     subject { group_path(group(Gitlab::VisibilityLevel::INTERNAL)) }
 
diff --git a/spec/services/groups/create_service_spec.rb b/spec/services/groups/create_service_spec.rb
new file mode 100644
index 0000000000000000000000000000000000000000..7dbc529797871087a14d741c6117934c9b1289eb
--- /dev/null
+++ b/spec/services/groups/create_service_spec.rb
@@ -0,0 +1,22 @@
+require 'spec_helper'
+
+describe Groups::CreateService, services: true do
+    let!(:user)    { create(:user) }
+    let!(:private_group)    { create(:group, visibility_level: Gitlab::VisibilityLevel::PRIVATE) }
+    let!(:internal_group)   { create(:group, visibility_level: Gitlab::VisibilityLevel::INTERNAL) }
+    let!(:public_group)     { create(:group, visibility_level: Gitlab::VisibilityLevel::PUBLIC) }
+
+  describe "execute" do
+    let!(:service) { described_class.new(public_group, user, visibility_level: Gitlab::VisibilityLevel::PUBLIC ) }
+    subject { service.execute }
+
+    context "create groups without restricted visibility level" do
+      it { is_expected.to be_truthy }
+    end
+
+    context "cannot create group with restricted visibility level" do
+      before { allow(current_application_settings).to receive(:restricted_visibility_levels).and_return([Gitlab::VisibilityLevel::PUBLIC]) }
+      it { is_expected.to be_falsy }
+    end
+  end
+end