aboutsummaryrefslogtreecommitdiffstats
path: root/sonar-server
diff options
context:
space:
mode:
authorSimon Brandhof <simon.brandhof@gmail.com>2012-07-11 20:29:18 +0200
committerSimon Brandhof <simon.brandhof@gmail.com>2012-07-11 20:29:35 +0200
commit3869be4f9026d8b677a98041d7591586e35b2942 (patch)
treec07539ed52b22af0592caeeacdc37b1f38f03b76 /sonar-server
parentaceadd9dd9a7b835ce67c505013f090f06ebe642 (diff)
downloadsonarqube-3869be4f9026d8b677a98041d7591586e35b2942.tar.gz
sonarqube-3869be4f9026d8b677a98041d7591586e35b2942.zip
SONAR-3646 API : new extension point to be notified on user creation
Diffstat (limited to 'sonar-server')
-rw-r--r--sonar-server/src/main/java/org/sonar/server/platform/NewUserNotifier.java47
-rw-r--r--sonar-server/src/main/java/org/sonar/server/platform/Platform.java1
-rw-r--r--sonar-server/src/main/java/org/sonar/server/ui/JRubyFacade.java26
-rw-r--r--sonar-server/src/main/webapp/WEB-INF/app/controllers/users_controller.rb3
-rw-r--r--sonar-server/src/main/webapp/WEB-INF/app/models/user.rb40
-rw-r--r--sonar-server/src/test/java/org/sonar/server/platform/NewUserNotifierTest.java51
6 files changed, 139 insertions, 29 deletions
diff --git a/sonar-server/src/main/java/org/sonar/server/platform/NewUserNotifier.java b/sonar-server/src/main/java/org/sonar/server/platform/NewUserNotifier.java
new file mode 100644
index 00000000000..a6f1d22869b
--- /dev/null
+++ b/sonar-server/src/main/java/org/sonar/server/platform/NewUserNotifier.java
@@ -0,0 +1,47 @@
+/*
+ * Sonar, open source software quality management tool.
+ * Copyright (C) 2008-2012 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * Sonar is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * Sonar is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Sonar; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
+ */
+package org.sonar.server.platform;
+
+import org.slf4j.LoggerFactory;
+import org.sonar.api.ServerComponent;
+import org.sonar.api.platform.NewUserHandler;
+
+/**
+ * @since 3.2
+ */
+public class NewUserNotifier implements ServerComponent {
+
+ private NewUserHandler[] handlers;
+
+ public NewUserNotifier(NewUserHandler[] handlers) {
+ this.handlers = handlers;
+ }
+
+ public NewUserNotifier() {
+ this(new NewUserHandler[0]);
+ }
+
+ public void onNewUser(NewUserHandler.Context context) {
+ LoggerFactory.getLogger(NewUserNotifier.class).debug("User created: " + context.getLogin() + ". Notifying " + NewUserHandler.class.getSimpleName() + " handlers...");
+ for (NewUserHandler handler : handlers) {
+ handler.doOnNewUser(context);
+ }
+ }
+} \ No newline at end of file
diff --git a/sonar-server/src/main/java/org/sonar/server/platform/Platform.java b/sonar-server/src/main/java/org/sonar/server/platform/Platform.java
index 2ce18b2e881..e20fed0c4c0 100644
--- a/sonar-server/src/main/java/org/sonar/server/platform/Platform.java
+++ b/sonar-server/src/main/java/org/sonar/server/platform/Platform.java
@@ -241,6 +241,7 @@ public final class Platform {
servicesContainer.addSingleton(RuleI18nManager.class);
servicesContainer.addSingleton(GwtI18n.class);
servicesContainer.addSingleton(ResourceTypes.class);
+ servicesContainer.addSingleton(NewUserNotifier.class);
// Notifications
servicesContainer.addSingleton(EmailSettings.class);
diff --git a/sonar-server/src/main/java/org/sonar/server/ui/JRubyFacade.java b/sonar-server/src/main/java/org/sonar/server/ui/JRubyFacade.java
index 76ba04b7168..d2f4a2bb449 100644
--- a/sonar-server/src/main/java/org/sonar/server/ui/JRubyFacade.java
+++ b/sonar-server/src/main/java/org/sonar/server/ui/JRubyFacade.java
@@ -27,6 +27,7 @@ import org.sonar.api.config.License;
import org.sonar.api.config.PropertyDefinitions;
import org.sonar.api.config.Settings;
import org.sonar.api.platform.ComponentContainer;
+import org.sonar.api.platform.NewUserHandler;
import org.sonar.api.platform.PluginMetadata;
import org.sonar.api.platform.PluginRepository;
import org.sonar.api.profiles.ProfileExporter;
@@ -37,11 +38,7 @@ import org.sonar.api.resources.ResourceTypes;
import org.sonar.api.rules.RulePriority;
import org.sonar.api.rules.RuleRepository;
import org.sonar.api.utils.ValidationMessages;
-import org.sonar.api.web.Footer;
-import org.sonar.api.web.NavigationSection;
-import org.sonar.api.web.Page;
-import org.sonar.api.web.RubyRailsWebservice;
-import org.sonar.api.web.Widget;
+import org.sonar.api.web.*;
import org.sonar.api.workflow.Review;
import org.sonar.api.workflow.internal.DefaultReview;
import org.sonar.api.workflow.internal.DefaultWorkflowContext;
@@ -61,19 +58,15 @@ import org.sonar.server.filters.FilterExecutor;
import org.sonar.server.filters.FilterResult;
import org.sonar.server.notifications.reviews.ReviewsNotificationManager;
import org.sonar.server.platform.GlobalSettingsUpdater;
+import org.sonar.server.platform.NewUserNotifier;
import org.sonar.server.platform.Platform;
import org.sonar.server.platform.ServerIdGenerator;
-import org.sonar.server.plugins.DefaultServerPluginRepository;
-import org.sonar.server.plugins.PluginDeployer;
-import org.sonar.server.plugins.PluginDownloader;
-import org.sonar.server.plugins.UpdateCenterMatrix;
-import org.sonar.server.plugins.UpdateCenterMatrixFactory;
+import org.sonar.server.plugins.*;
import org.sonar.server.rules.ProfilesConsole;
import org.sonar.server.rules.RulesConsole;
import org.sonar.updatecenter.common.Version;
import javax.annotation.Nullable;
-
import java.net.InetAddress;
import java.sql.Connection;
import java.util.Collection;
@@ -319,7 +312,7 @@ public final class JRubyFacade {
public void ruleSeverityChanged(int parentProfileId, int activeRuleId, int oldSeverityId, int newSeverityId, String userName) {
getProfilesManager().ruleSeverityChanged(parentProfileId, activeRuleId, RulePriority.values()[oldSeverityId],
- RulePriority.values()[newSeverityId], userName);
+ RulePriority.values()[newSeverityId], userName);
}
public void ruleDeactivated(int parentProfileId, int deactivatedRuleId, String userName) {
@@ -524,4 +517,13 @@ public final class JRubyFacade {
getContainer().getComponentByType(ResourceKeyUpdaterDao.class).bulkUpdateKey(projectId, stringToReplace, replacementString);
}
+
+ // USERS
+ public void onNewUser(Map<String, String> fields) {
+ getContainer().getComponentByType(NewUserNotifier.class).onNewUser(NewUserHandler.Context.builder()
+ .setLogin(fields.get("login"))
+ .setName(fields.get("name"))
+ .setEmail(fields.get("email"))
+ .build());
+ }
}
diff --git a/sonar-server/src/main/webapp/WEB-INF/app/controllers/users_controller.rb b/sonar-server/src/main/webapp/WEB-INF/app/controllers/users_controller.rb
index b238a0bf709..a187754727c 100644
--- a/sonar-server/src/main/webapp/WEB-INF/app/controllers/users_controller.rb
+++ b/sonar-server/src/main/webapp/WEB-INF/app/controllers/users_controller.rb
@@ -116,8 +116,7 @@ class UsersController < ApplicationController
def reactivate
user = User.find_by_login(params[:user][:login])
if user
- user.reactivate(java_facade.getSettings().getString('sonar.defaultGroup'))
- user.save!
+ user.reactivate!(java_facade.getSettings().getString('sonar.defaultGroup'))
flash[:notice] = 'User was successfully reactivated.'
else
flash[:error] = "A user with login #{params[:user][:login]} does not exist."
diff --git a/sonar-server/src/main/webapp/WEB-INF/app/models/user.rb b/sonar-server/src/main/webapp/WEB-INF/app/models/user.rb
index 2e25ac4dad7..c70d33985a4 100644
--- a/sonar-server/src/main/webapp/WEB-INF/app/models/user.rb
+++ b/sonar-server/src/main/webapp/WEB-INF/app/models/user.rb
@@ -23,6 +23,7 @@ class User < ActiveRecord::Base
FAVOURITE_PROPERTY_KEY='favourite'
+ after_create :on_create
has_and_belongs_to_many :groups
has_many :user_roles, :dependent => :delete_all
@@ -37,17 +38,17 @@ class User < ActiveRecord::Base
include NeedAuthorization::ForUser
include NeedAuthentication::ForUser
- validates_length_of :name, :maximum => 200, :allow_blank => true, :allow_nil => true
- validates_length_of :email, :maximum => 100, :allow_blank => true, :allow_nil => true
+ validates_length_of :name, :maximum => 200, :allow_blank => true, :allow_nil => true
+ validates_length_of :email, :maximum => 100, :allow_blank => true, :allow_nil => true
# The following two validations not needed, because they come with Authentication::ByPassword - see SONAR-2656
#validates_length_of :password, :within => 4..40, :if => :password_required?
#validates_confirmation_of :password, :if => :password_required?
- validates_presence_of :login
- validates_length_of :login, :within => 2..40
- validates_uniqueness_of :login, :case_sensitive => true
- validates_format_of :login, :with => Authentication.login_regex, :message => Authentication.bad_login_message
+ validates_presence_of :login
+ validates_length_of :login, :within => 2..40
+ validates_uniqueness_of :login, :case_sensitive => true
+ validates_format_of :login, :with => Authentication.login_regex, :message => Authentication.bad_login_message
# HACK HACK HACK -- how to do attr_accessible from here?
@@ -90,20 +91,22 @@ class User < ActiveRecord::Base
# do not validate user, for example when user created via SSO has no password
self.save(false)
- self.user_roles.each {|role| role.delete}
- self.properties.each {|prop| prop.delete}
- self.filters.each {|f| f.destroy}
- self.dashboards.each {|d| d.destroy}
- self.active_dashboards.each {|ad| ad.destroy}
+ self.user_roles.each { |role| role.delete }
+ self.properties.each { |prop| prop.delete }
+ self.filters.each { |f| f.destroy }
+ self.dashboards.each { |d| d.destroy }
+ self.active_dashboards.each { |ad| ad.destroy }
end
# SONAR-3258
- def reactivate(default_group_name)
+ def reactivate!(default_group_name)
if default_group_name
default_group=Group.find_by_name(default_group_name)
self.groups<<default_group if default_group
end
self.active = true
+ save!
+ on_create
end
def self.find_active_by_login(login)
@@ -149,7 +152,7 @@ class User < ActiveRecord::Base
def self.logins_to_ids(logins=[])
if logins.size>0
- User.find(:all, :select => 'id', :conditions => ['login in (?)', logins]).map{|user| user.id}
+ User.find(:all, :select => 'id', :conditions => ['login in (?)', logins]).map { |user| user.id }
else
[]
end
@@ -162,7 +165,7 @@ class User < ActiveRecord::Base
def favourite_ids
@favourite_ids ||=
begin
- properties().select{|p| p.key==FAVOURITE_PROPERTY_KEY}.map{|p| p.resource_id}
+ properties().select { |p| p.key==FAVOURITE_PROPERTY_KEY }.map { |p| p.resource_id }
end
@favourite_ids
end
@@ -187,7 +190,7 @@ class User < ActiveRecord::Base
rid = resource.id if resource
end
if rid
- props=properties().select{|p| p.key==FAVOURITE_PROPERTY_KEY && p.resource_id==rid}
+ props=properties().select { |p| p.key==FAVOURITE_PROPERTY_KEY && p.resource_id==rid }
if props.size>0
properties().delete(props)
return true
@@ -199,4 +202,11 @@ class User < ActiveRecord::Base
def favourite?(resource_id)
favourite_ids().include?(resource_id.to_i)
end
+
+
+ private
+
+ def on_create
+ Java::OrgSonarServerUi::JRubyFacade.getInstance().onNewUser({'login' => self.login, 'name' => self.name, 'email' => self.email})
+ end
end
diff --git a/sonar-server/src/test/java/org/sonar/server/platform/NewUserNotifierTest.java b/sonar-server/src/test/java/org/sonar/server/platform/NewUserNotifierTest.java
new file mode 100644
index 00000000000..62618af3936
--- /dev/null
+++ b/sonar-server/src/test/java/org/sonar/server/platform/NewUserNotifierTest.java
@@ -0,0 +1,51 @@
+/*
+ * Sonar, open source software quality management tool.
+ * Copyright (C) 2008-2012 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * Sonar is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * Sonar is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Sonar; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
+ */
+package org.sonar.server.platform;
+
+import org.junit.Test;
+import org.sonar.api.platform.NewUserHandler;
+
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+
+public class NewUserNotifierTest {
+
+ private NewUserHandler.Context context = NewUserHandler.Context.builder().setLogin("marius").setName("Marius").build();
+
+ @Test
+ public void do_not_fail_if_no_handlers() {
+ NewUserNotifier notifier = new NewUserNotifier();
+
+ notifier.onNewUser(context);
+ }
+
+ @Test
+ public void execute_handlers_on_new_user() {
+ NewUserHandler handler1 = mock(NewUserHandler.class);
+ NewUserHandler handler2 = mock(NewUserHandler.class);
+ NewUserNotifier notifier = new NewUserNotifier(new NewUserHandler[]{handler1, handler2});
+
+
+ notifier.onNewUser(context);
+
+ verify(handler1).doOnNewUser(context);
+ verify(handler2).doOnNewUser(context);
+ }
+}