import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.MethodSource;
import org.sonar.api.impl.utils.AlwaysIncreasingSystem2;
-import org.sonar.db.component.ComponentQualifiers;
import org.sonar.db.DbClient;
import org.sonar.db.DbSession;
import org.sonar.db.DbTester;
import org.sonar.db.EmailSubscriberDto;
import org.sonar.db.audit.AuditPersister;
import org.sonar.db.component.ComponentDto;
+import org.sonar.db.component.ComponentQualifiers;
import org.sonar.db.portfolio.PortfolioDto;
import org.sonar.db.project.ProjectDto;
import org.sonar.db.user.UserDto;
String projectKey = secure().nextAlphabetic(4);
String projectName = secure().nextAlphabetic(4);
-
// global subscription
insertProperty("notification.DispatcherWithGlobalSubscribers.Email", "true", null,
user2.getUuid(), user2.getLogin(), null, null);
// Global + Project subscribers
assertThat(underTest.hasProjectNotificationSubscribersForDispatchers(projectUuid, singletonList(
"DispatcherWithGlobalAndProjectSubscribers")))
- .isTrue();
+ .isTrue();
assertThat(underTest.hasProjectNotificationSubscribersForDispatchers("PROJECT_B", singletonList(
"DispatcherWithGlobalAndProjectSubscribers")))
- .isTrue();
+ .isTrue();
}
@Test
String channelKey = secure().nextAlphabetic(6);
String projectKey = secure().nextAlphabetic(7);
- Set<EmailSubscriberDto> subscribers = underTest.findEmailSubscribersForNotification(db.getSession(), dispatcherKey, channelKey,
+ Set<EmailSubscriberDto> subscribers = underTest.findEnabledEmailSubscribersForNotification(db.getSession(), dispatcherKey, channelKey,
projectKey);
assertThat(subscribers).isEmpty();
String projectKey = secure().nextAlphabetic(7);
Set<String> logins = of("user1", "user2");
- Set<EmailSubscriberDto> subscribers = underTest.findEmailSubscribersForNotification(db.getSession(), dispatcherKey, channelKey,
+ Set<EmailSubscriberDto> subscribers = underTest.findEnabledEmailSubscribersForNotification(db.getSession(), dispatcherKey, channelKey,
projectKey, logins);
assertThat(subscribers).isEmpty();
}
@Test
- void findEmailRecipientsForNotification_finds_only_globally_subscribed_users_if_projectKey_is_null() {
+ void findEnabledEmailSubscribersForNotification_finds_only_globally_subscribed_users_if_projectKey_is_null() {
UserDto user1 = db.users().insertUser(withEmail("user1"));
UserDto user2 = db.users().insertUser(withEmail("user2"));
UserDto user3 = db.users().insertUser(withEmail("user3"));
insertProperty(propertyKeyOf(dispatcherKey, channelKey), "false", project.getUuid(), user4.getUuid(), user4.getLogin(),
project.getKey(), project.getName());
- assertThat(underTest.findEmailSubscribersForNotification(db.getSession(), dispatcherKey, channelKey, null))
+ assertThat(underTest.findEnabledEmailSubscribersForNotification(db.getSession(), dispatcherKey, channelKey, null))
.containsOnly(EmailSubscriberDto.create("user1", true, emailOf("user1")), EmailSubscriberDto.create("user2", true, emailOf("user2")));
- assertThat(underTest.findEmailSubscribersForNotification(db.getSession(), dispatcherKey, otherChannelKey, null))
+ assertThat(underTest.findEnabledEmailSubscribersForNotification(db.getSession(), dispatcherKey, otherChannelKey, null))
.isEmpty();
- assertThat(underTest.findEmailSubscribersForNotification(db.getSession(), otherDispatcherKey, channelKey, null))
+ assertThat(underTest.findEnabledEmailSubscribersForNotification(db.getSession(), otherDispatcherKey, channelKey, null))
.isEmpty();
- assertThat(underTest.findEmailSubscribersForNotification(db.getSession(), channelKey, dispatcherKey, null))
+ assertThat(underTest.findEnabledEmailSubscribersForNotification(db.getSession(), channelKey, dispatcherKey, null))
.isEmpty();
}
@Test
- void findEmailRecipientsForNotification_with_logins_finds_only_globally_subscribed_specified_users_if_projectKey_is_null() {
+ void findEnabledEmailSubscribersForNotification_with_logins_finds_only_globally_subscribed_specified_users_if_projectKey_is_null() {
UserDto user1 = db.users().insertUser(withEmail("user1"));
UserDto user2 = db.users().insertUser(withEmail("user2"));
UserDto user3 = db.users().insertUser(withEmail("user3"));
project.getKey(), project.getName());
Set<String> allLogins = of("user1", "user2", "user3", "user4");
- assertThat(underTest.findEmailSubscribersForNotification(db.getSession(), dispatcherKey, channelKey, null, allLogins))
+ assertThat(underTest.findEnabledEmailSubscribersForNotification(db.getSession(), dispatcherKey, channelKey, null, allLogins))
.containsOnly(EmailSubscriberDto.create("user1", true, emailOf("user1")), EmailSubscriberDto.create("user2", true, emailOf("user2")));
- assertThat(underTest.findEmailSubscribersForNotification(db.getSession(), dispatcherKey, channelKey, null, of("user1", "user2")))
+ assertThat(underTest.findEnabledEmailSubscribersForNotification(db.getSession(), dispatcherKey, channelKey, null, of("user1", "user2")))
.containsOnly(EmailSubscriberDto.create("user1", true, emailOf("user1")), EmailSubscriberDto.create("user2", true, emailOf("user2")));
- assertThat(underTest.findEmailSubscribersForNotification(db.getSession(), dispatcherKey, channelKey, null, of("user2")))
+ assertThat(underTest.findEnabledEmailSubscribersForNotification(db.getSession(), dispatcherKey, channelKey, null, of("user2")))
.containsOnly(EmailSubscriberDto.create("user2", true, emailOf("user2")));
- assertThat(underTest.findEmailSubscribersForNotification(db.getSession(), dispatcherKey, channelKey, null, of("user1")))
+ assertThat(underTest.findEnabledEmailSubscribersForNotification(db.getSession(), dispatcherKey, channelKey, null, of("user1")))
.containsOnly(EmailSubscriberDto.create("user1", true, emailOf("user1")));
- assertThat(underTest.findEmailSubscribersForNotification(db.getSession(), dispatcherKey, channelKey, null, of()))
+ assertThat(underTest.findEnabledEmailSubscribersForNotification(db.getSession(), dispatcherKey, channelKey, null, of()))
.isEmpty();
- assertThat(underTest.findEmailSubscribersForNotification(db.getSession(), dispatcherKey, otherChannelKey, null, allLogins))
+ assertThat(underTest.findEnabledEmailSubscribersForNotification(db.getSession(), dispatcherKey, otherChannelKey, null, allLogins))
.isEmpty();
- assertThat(underTest.findEmailSubscribersForNotification(db.getSession(), otherDispatcherKey, channelKey, null, allLogins))
+ assertThat(underTest.findEnabledEmailSubscribersForNotification(db.getSession(), otherDispatcherKey, channelKey, null, allLogins))
.isEmpty();
- assertThat(underTest.findEmailSubscribersForNotification(db.getSession(), channelKey, dispatcherKey, null, allLogins))
+ assertThat(underTest.findEnabledEmailSubscribersForNotification(db.getSession(), channelKey, dispatcherKey, null, allLogins))
.isEmpty();
}
}
@Test
- void findEmailRecipientsForNotification_finds_global_and_project_subscribed_users_when_projectKey_is_non_null() {
+ void findEnabledEmailSubscribersForNotification_finds_global_and_project_subscribed_users_when_projectKey_is_non_null() {
UserDto user1 = db.users().insertUser(withEmail("user1"));
UserDto user2 = db.users().insertUser(withEmail("user2"));
UserDto user3 = db.users().insertUser(withEmail("user3"));
insertProperty(propertyKeyOf(dispatcherKey, channelKey), "false", project.getUuid(), user4.getUuid(), user4.getLogin(),
project.getKey(), project.getName());
- assertThat(underTest.findEmailSubscribersForNotification(db.getSession(), dispatcherKey, channelKey, projectKey))
+ assertThat(underTest.findEnabledEmailSubscribersForNotification(db.getSession(), dispatcherKey, channelKey, projectKey))
.containsOnly(
EmailSubscriberDto.create("user1", true, emailOf("user1")),
EmailSubscriberDto.create("user2", true, emailOf("user2")), EmailSubscriberDto.create("user2", false, "user2@foo"),
EmailSubscriberDto.create("user3", false, emailOf("user3")));
- assertThat(underTest.findEmailSubscribersForNotification(db.getSession(), dispatcherKey, channelKey, otherProjectKey))
+ assertThat(underTest.findEnabledEmailSubscribersForNotification(db.getSession(), dispatcherKey, channelKey, otherProjectKey))
.containsOnly(
EmailSubscriberDto.create("user1", true, emailOf("user1")),
EmailSubscriberDto.create("user2", true, emailOf("user2")));
- assertThat(underTest.findEmailSubscribersForNotification(db.getSession(), dispatcherKey, otherChannelKey, otherProjectKey))
+ assertThat(underTest.findEnabledEmailSubscribersForNotification(db.getSession(), dispatcherKey, otherChannelKey, otherProjectKey))
.isEmpty();
- assertThat(underTest.findEmailSubscribersForNotification(db.getSession(), otherDispatcherKey, channelKey, otherProjectKey))
+ assertThat(underTest.findEnabledEmailSubscribersForNotification(db.getSession(), otherDispatcherKey, channelKey, otherProjectKey))
.isEmpty();
}
@Test
- void findEmailRecipientsForNotification_with_logins_finds_global_and_project_subscribed_specified_users_when_projectKey_is_non_null() {
+ void findEnabledEmailSubscribersForNotification_with_logins_finds_global_and_project_subscribed_specified_users_when_projectKey_is_non_null() {
UserDto user1 = db.users().insertUser(withEmail("user1"));
UserDto user2 = db.users().insertUser(withEmail("user2"));
UserDto user3 = db.users().insertUser(withEmail("user3"));
project.getKey(), project.getName());
Set<String> allLogins = of("user1", "user2", "user3", "user4");
- assertThat(underTest.findEmailSubscribersForNotification(db.getSession(), dispatcherKey, channelKey, projectKey, allLogins))
+ assertThat(underTest.findEnabledEmailSubscribersForNotification(db.getSession(), dispatcherKey, channelKey, projectKey, allLogins))
.containsOnly(
EmailSubscriberDto.create("user1", true, emailOf("user1")),
EmailSubscriberDto.create("user2", true, emailOf("user2")), EmailSubscriberDto.create("user2", false, "user2@foo"),
EmailSubscriberDto.create("user3", false, emailOf("user3")));
- assertThat(underTest.findEmailSubscribersForNotification(db.getSession(), dispatcherKey, channelKey, projectKey, of("user1")))
+ assertThat(underTest.findEnabledEmailSubscribersForNotification(db.getSession(), dispatcherKey, channelKey, projectKey, of("user1")))
.containsOnly(
EmailSubscriberDto.create("user1", true, emailOf("user1")));
- assertThat(underTest.findEmailSubscribersForNotification(db.getSession(), dispatcherKey, channelKey, projectKey, of("user2")))
+ assertThat(underTest.findEnabledEmailSubscribersForNotification(db.getSession(), dispatcherKey, channelKey, projectKey, of("user2")))
.containsOnly(
EmailSubscriberDto.create("user2", true, emailOf("user2")), EmailSubscriberDto.create("user2", false, "user2@foo"));
- assertThat(underTest.findEmailSubscribersForNotification(db.getSession(), dispatcherKey, channelKey, projectKey, of("user3")))
+ assertThat(underTest.findEnabledEmailSubscribersForNotification(db.getSession(), dispatcherKey, channelKey, projectKey, of("user3")))
.containsOnly(EmailSubscriberDto.create("user3", false, emailOf("user3")));
- assertThat(underTest.findEmailSubscribersForNotification(db.getSession(), dispatcherKey, channelKey, projectKey, of()))
+ assertThat(underTest.findEnabledEmailSubscribersForNotification(db.getSession(), dispatcherKey, channelKey, projectKey, of()))
.isEmpty();
- assertThat(underTest.findEmailSubscribersForNotification(db.getSession(), dispatcherKey, channelKey, otherProjectKey, allLogins))
+ assertThat(underTest.findEnabledEmailSubscribersForNotification(db.getSession(), dispatcherKey, channelKey, otherProjectKey, allLogins))
.containsOnly(
EmailSubscriberDto.create("user1", true, emailOf("user1")),
EmailSubscriberDto.create("user2", true, emailOf("user2")));
- assertThat(underTest.findEmailSubscribersForNotification(db.getSession(), dispatcherKey, otherChannelKey, otherProjectKey, allLogins))
+ assertThat(underTest.findEnabledEmailSubscribersForNotification(db.getSession(), dispatcherKey, otherChannelKey, otherProjectKey, allLogins))
.isEmpty();
- assertThat(underTest.findEmailSubscribersForNotification(db.getSession(), otherDispatcherKey, channelKey, otherProjectKey, allLogins))
+ assertThat(underTest.findEnabledEmailSubscribersForNotification(db.getSession(), otherDispatcherKey, channelKey, otherProjectKey, allLogins))
.isEmpty();
}
@Test
- void findEmailRecipientsForNotification_ignores_subscribed_users_without_email() {
+ void findDisabledEmailSubscribersForNotification_shouldReturnDisabledNotificationForUser() {
+ UserDto user1 = db.users().insertUser(withEmail("user1"));
+ UserDto user2 = db.users().insertUser(withEmail("user2"));
+ String projectKey = secure().nextAlphabetic(3);
+ insertPrivateProject(projectKey);
+ String dispatcherKey = secure().nextAlphabetic(4);
+ String channelKey = secure().nextAlphabetic(5);
+ // user1 and user2 subscribed on project and globally
+ insertProperty(propertyKeyOf(dispatcherKey, channelKey), "false", null, user1.getUuid(), user1.getLogin(),
+ null, null);
+ insertProperty(propertyKeyOf(dispatcherKey, channelKey), "true", null, user2.getUuid(), user2.getLogin(),
+ null, null);
+
+ assertThat(underTest.findDisabledEmailSubscribersForNotification(db.getSession(), dispatcherKey, channelKey, projectKey, of("user1", "user2")))
+ .containsOnly(
+ EmailSubscriberDto.create("user1", true, emailOf("user1")));
+ }
+
+ @Test
+ void findEnabledEmailSubscribersForNotification_with_logins_ignores_subscribed_users_without_email() {
UserDto user1 = db.users().insertUser(withEmail("user1"));
UserDto user2 = db.users().insertUser(noEmail("user2"));
UserDto user3 = db.users().insertUser(withEmail("user3"));
UserDto user4 = db.users().insertUser(noEmail("user4"));
+ Set<String> allLogins = of("user1", "user2", "user3");
String projectKey = secure().nextAlphabetic(3);
ProjectDto project = insertPrivateProject(projectKey);
String dispatcherKey = secure().nextAlphabetic(4);
insertProperty(propertyKeyOf(dispatcherKey, channelKey), "true", project.getUuid(), user1.getUuid(), user1.getLogin(),
project.getKey(), project.getName());
insertProperty(propertyKeyOf(dispatcherKey, channelKey), "true", null, user2.getUuid(), user2.getLogin(),
- null, null);
+ project.getKey(), null);
insertProperty(propertyKeyOf(dispatcherKey, channelKey), "true", project.getUuid(), user2.getUuid(), user2.getLogin(),
project.getKey(), project.getName());
// user3 and user4 subscribed only globally
insertProperty(propertyKeyOf(dispatcherKey, channelKey), "true", null, user3.getUuid(), user3.getLogin(),
- null, null);
+ project.getKey(), null);
insertProperty(propertyKeyOf(dispatcherKey, channelKey), "true", null, user4.getUuid(), user4.getLogin(),
null, null);
- assertThat(underTest.findEmailSubscribersForNotification(db.getSession(), dispatcherKey, channelKey, projectKey))
+ assertThat(underTest.findEnabledEmailSubscribersForNotification(db.getSession(), dispatcherKey, channelKey, projectKey, allLogins))
.containsOnly(
EmailSubscriberDto.create("user1", true, emailOf("user1")), EmailSubscriberDto.create("user1", false, emailOf("user1")),
EmailSubscriberDto.create("user3", true, emailOf("user3")));
- assertThat(underTest.findEmailSubscribersForNotification(db.getSession(), dispatcherKey, channelKey, null))
+ assertThat(underTest.findEnabledEmailSubscribersForNotification(db.getSession(), dispatcherKey, channelKey, null, allLogins))
.containsOnly(
EmailSubscriberDto.create("user1", true, emailOf("user1")),
EmailSubscriberDto.create("user3", true, emailOf("user3")));
}
@Test
- void findEmailRecipientsForNotification_with_logins_ignores_subscribed_users_without_email() {
+ void findDisabledEmailSubscribersForNotification_() {
UserDto user1 = db.users().insertUser(withEmail("user1"));
UserDto user2 = db.users().insertUser(noEmail("user2"));
UserDto user3 = db.users().insertUser(withEmail("user3"));
String dispatcherKey = secure().nextAlphabetic(4);
String channelKey = secure().nextAlphabetic(5);
// user1 and user2 subscribed on project and globally
- insertProperty(propertyKeyOf(dispatcherKey, channelKey), "true", null, user1.getUuid(), user1.getLogin(),
+ insertProperty(propertyKeyOf(dispatcherKey, channelKey), "false", null, user1.getUuid(), user1.getLogin(),
null, null);
- insertProperty(propertyKeyOf(dispatcherKey, channelKey), "true", project.getUuid(), user1.getUuid(), user1.getLogin(),
+ insertProperty(propertyKeyOf(dispatcherKey, channelKey), "false", project.getUuid(), user1.getUuid(), user1.getLogin(),
project.getKey(), project.getName());
- insertProperty(propertyKeyOf(dispatcherKey, channelKey), "true", null, user2.getUuid(), user2.getLogin(),
+ insertProperty(propertyKeyOf(dispatcherKey, channelKey), "false", null, user2.getUuid(), user2.getLogin(),
project.getKey(), null);
- insertProperty(propertyKeyOf(dispatcherKey, channelKey), "true", project.getUuid(), user2.getUuid(), user2.getLogin(),
+ insertProperty(propertyKeyOf(dispatcherKey, channelKey), "false", project.getUuid(), user2.getUuid(), user2.getLogin(),
project.getKey(), project.getName());
// user3 and user4 subscribed only globally
- insertProperty(propertyKeyOf(dispatcherKey, channelKey), "true", null, user3.getUuid(), user3.getLogin(),
+ insertProperty(propertyKeyOf(dispatcherKey, channelKey), "false", null, user3.getUuid(), user3.getLogin(),
project.getKey(), null);
- insertProperty(propertyKeyOf(dispatcherKey, channelKey), "true", null, user4.getUuid(), user4.getLogin(),
+ insertProperty(propertyKeyOf(dispatcherKey, channelKey), "false", null, user4.getUuid(), user4.getLogin(),
null, null);
- assertThat(underTest.findEmailSubscribersForNotification(db.getSession(), dispatcherKey, channelKey, projectKey, allLogins))
+ assertThat(underTest.findDisabledEmailSubscribersForNotification(db.getSession(), dispatcherKey, channelKey, projectKey, allLogins))
.containsOnly(
EmailSubscriberDto.create("user1", true, emailOf("user1")), EmailSubscriberDto.create("user1", false, emailOf("user1")),
EmailSubscriberDto.create("user3", true, emailOf("user3")));
- assertThat(underTest.findEmailSubscribersForNotification(db.getSession(), dispatcherKey, channelKey, null, allLogins))
+ assertThat(underTest.findDisabledEmailSubscribersForNotification(db.getSession(), dispatcherKey, channelKey, null, allLogins))
.containsOnly(
EmailSubscriberDto.create("user1", true, emailOf("user1")),
EmailSubscriberDto.create("user3", true, emailOf("user3")));
}
private static Object[][] allValuesForSelect() {
- return new Object[][]{
+ return new Object[][] {
{null, ""},
{"", ""},
{"some value", "some value"},
tuple(key, project2.getUuid()));
assertThat(underTest.selectPropertiesByKeysAndEntityUuids(session, newHashSet(key, anotherKey), newHashSet(project.getUuid(),
project2.getUuid())))
- .extracting(PropertyDto::getKey, PropertyDto::getEntityUuid).containsOnly(
- tuple(key, project.getUuid()),
- tuple(key, project2.getUuid()),
- tuple(anotherKey, project2.getUuid()));
+ .extracting(PropertyDto::getKey, PropertyDto::getEntityUuid).containsOnly(
+ tuple(key, project.getUuid()),
+ tuple(key, project2.getUuid()),
+ tuple(anotherKey, project2.getUuid()));
assertThat(underTest.selectPropertiesByKeysAndEntityUuids(session, newHashSet("unknown"), newHashSet(project.getUuid()))).isEmpty();
assertThat(underTest.selectPropertiesByKeysAndEntityUuids(session, newHashSet("key"), newHashSet("uuid123456789"))).isEmpty();
}
static Object[][] valueUpdatesDataProvider() {
- return new Object[][]{
+ return new Object[][] {
{null, null},
{null, ""},
{null, "some value"},
assertThat(db.select("select prop_key as \"key\", text_value as \"value\", entity_uuid as \"projectUuid\", user_uuid as \"userUuid\" " +
"from properties"))
- .extracting((row) -> row.get("key"), (row) -> row.get("value"), (row) -> row.get("projectUuid"), (row) -> row.get("userUuid"))
- .containsOnly(tuple("KEY", "ANOTHER_VALUE", null, null), tuple("ANOTHER_KEY", "VALUE", project.uuid(), "100"));
+ .extracting((row) -> row.get("key"), (row) -> row.get("value"), (row) -> row.get("projectUuid"), (row) -> row.get("userUuid"))
+ .containsOnly(tuple("KEY", "ANOTHER_VALUE", null, null), tuple("ANOTHER_KEY", "VALUE", project.uuid(), "100"));
}
private static Map<String, String> mapOf(String... values) {
this.auditPersister = auditPersister;
}
- public Set<EmailSubscriberDto> findEmailSubscribersForNotification(DbSession dbSession, String notificationDispatcherKey, String notificationChannelKey,
+ public Set<EmailSubscriberDto> findEnabledEmailSubscribersForNotification(DbSession dbSession, String notificationDispatcherKey, String notificationChannelKey,
@Nullable String projectKey) {
- return getMapper(dbSession).findEmailRecipientsForNotification(NOTIFICATION_PREFIX + notificationDispatcherKey + "." + notificationChannelKey, projectKey, null);
+ return getMapper(dbSession).findEmailRecipientsForNotification(NOTIFICATION_PREFIX + notificationDispatcherKey + "." + notificationChannelKey, projectKey, null,
+ Boolean.toString(true));
}
- public Set<EmailSubscriberDto> findEmailSubscribersForNotification(DbSession dbSession, String notificationDispatcherKey, String notificationChannelKey,
+ public Set<EmailSubscriberDto> findEnabledEmailSubscribersForNotification(DbSession dbSession, String notificationDispatcherKey, String notificationChannelKey,
+ @Nullable String projectKey, Set<String> logins) {
+ return findEmailSubscribersForNotification(dbSession, notificationDispatcherKey, notificationChannelKey, projectKey, logins, true);
+ }
+
+ public Set<EmailSubscriberDto> findDisabledEmailSubscribersForNotification(DbSession dbSession, String notificationDispatcherKey, String notificationChannelKey,
@Nullable String projectKey, Set<String> logins) {
+ return findEmailSubscribersForNotification(dbSession, notificationDispatcherKey, notificationChannelKey, projectKey, logins, false);
+ }
+
+ public Set<EmailSubscriberDto> findEmailSubscribersForNotification(DbSession dbSession, String notificationDispatcherKey, String notificationChannelKey,
+ @Nullable String projectKey, Set<String> logins, boolean enabled) {
if (logins.isEmpty()) {
return Collections.emptySet();
}
logins,
loginsPartition -> {
String notificationKey = NOTIFICATION_PREFIX + notificationDispatcherKey + "." + notificationChannelKey;
- return getMapper(dbSession).findEmailRecipientsForNotification(notificationKey, projectKey, loginsPartition);
+ return getMapper(dbSession).findEmailRecipientsForNotification(notificationKey, projectKey, loginsPartition, Boolean.toString(enabled));
},
partitionSize -> projectKey == null ? partitionSize : (partitionSize / 2));
}
public interface PropertiesMapper {
Set<EmailSubscriberDto> findEmailRecipientsForNotification(@Param("notifKey") String notificationKey, @Nullable @Param("projectKey") String projectKey,
- @Nullable @Param("logins") List<String> logins);
+ @Nullable @Param("logins") List<String> logins, @Param("notifValue") String notificationValue);
List<PropertyDto> selectGlobalProperties();
INNER JOIN properties p ON
p.user_uuid = u.uuid
and p.prop_key = #{notifKey,jdbcType=VARCHAR}
- and p.text_value = 'true'
+ and p.text_value = #{notifValue,jdbcType=VARCHAR}
and p.entity_uuid IS NULL
WHERE
u.email is not null
INNER JOIN properties p ON
p.user_uuid = u.uuid
and p.prop_key = #{notifKey,jdbcType=VARCHAR}
- and p.text_value = 'true'
+ and p.text_value = #{notifValue,jdbcType=VARCHAR}
and p.entity_uuid = proj.uuid
WHERE
u.email is not null
import java.util.List;
import javax.annotation.Nullable;
import org.sonar.db.DbClient;
-import org.sonar.db.DbSession;
import org.sonar.db.DbTester;
import org.sonar.db.project.ProjectDto;
import org.sonar.db.property.PropertyDto;
this.db = db;
}
- public void assertExists(String channel, String dispatcher, String userUuid, @Nullable ProjectDto project) {
+ public void assertExists(String channel, String dispatcher, String userUuid, @Nullable ProjectDto project, boolean enabled) {
List<PropertyDto> result = dbClient.propertiesDao().selectByQuery(PropertyQuery.builder()
- .setKey(String.join(".", PROP_NOTIFICATION_PREFIX, dispatcher, channel))
- .setEntityUuid(project == null ? null : project.getUuid())
- .setUserUuid(userUuid)
- .build(), db.getSession()).stream()
+ .setKey(String.join(".", PROP_NOTIFICATION_PREFIX, dispatcher, channel))
+ .setEntityUuid(project == null ? null : project.getUuid())
+ .setUserUuid(userUuid)
+ .build(), db.getSession()).stream()
.filter(prop -> project == null ? prop.getEntityUuid() == null : prop.getEntityUuid() != null)
.toList();
assertThat(result).hasSize(1);
- assertThat(result.get(0).getValue()).isEqualTo("true");
+ assertThat(result.get(0).getValue()).isEqualTo(Boolean.toString(enabled));
}
public void assertDoesNotExist(String channel, String dispatcher, String userUuid, @Nullable ProjectDto project) {
import org.sonar.db.DbClient;
import org.sonar.db.DbSession;
import org.sonar.db.EmailSubscriberDto;
+import org.sonar.db.permission.GlobalPermission;
import org.sonar.server.notification.EmailNotificationHandler;
import org.sonar.server.notification.NotificationDispatcherMetadata;
import org.sonar.server.notification.email.EmailNotificationChannel;
static final String KEY = "QualityGateConditionsMismatch";
private static final NotificationDispatcherMetadata METADATA = NotificationDispatcherMetadata.create(KEY)
.setProperty(NotificationDispatcherMetadata.GLOBAL_NOTIFICATION, String.valueOf(true))
- .setProperty(NotificationDispatcherMetadata.PER_PROJECT_NOTIFICATION, String.valueOf(false));
+ .setProperty(NotificationDispatcherMetadata.PER_PROJECT_NOTIFICATION, String.valueOf(false))
+ .setProperty(NotificationDispatcherMetadata.ENABLED_BY_DEFAULT_NOTIFICATION, String.valueOf(true))
+ .setProperty(NotificationDispatcherMetadata.PERMISSION_RESTRICTION, GlobalPermission.ADMINISTER_QUALITY_GATES.getKey());
private final DbClient dbClient;
protected Set<EmailNotificationChannel.EmailDeliveryRequest> toEmailDeliveryRequests(Collection<QualityGateMetricsUpdateNotification> notifications) {
try (DbSession session = dbClient.openSession(false)) {
- Set<String> logins = dbClient.authorizationDao()
- .selectQualityGateAdministratorLogins(session).stream()
- .map(EmailSubscriberDto::getLogin)
- .collect(toSet());
+ Set<EmailSubscriberDto> subscriptions = dbClient.authorizationDao()
+ .selectQualityGateAdministratorLogins(session);
- if (logins.isEmpty()) {
+ if (subscriptions.isEmpty()) {
return Set.of();
}
- Set<EmailSubscriberDto> emailSubscribers = dbClient.propertiesDao().findEmailSubscribersForNotification(
- session, KEY, EmailNotificationChannel.class.getSimpleName(), null, logins);
+ Set<String> disabledLogins = dbClient.propertiesDao().findDisabledEmailSubscribersForNotification(
+ session, KEY, EmailNotificationChannel.class.getSimpleName(), null,
+ subscriptions.stream().map(EmailSubscriberDto::getLogin).collect(toSet()))
+ .stream()
+ .map(EmailSubscriberDto::getLogin)
+ .collect(toSet());
- return emailSubscribers
+ return subscriptions
.stream()
- .flatMap(t -> notifications.stream().map(notification -> new EmailNotificationChannel.EmailDeliveryRequest(t.getEmail(), notification)))
+ .filter(s -> !disabledLogins.contains(s.getLogin()))
+ .flatMap(s -> notifications.stream().map(notification -> new EmailNotificationChannel.EmailDeliveryRequest(s.getEmail(), notification)))
.collect(toSet());
}
}
verifyProjectKey(projectKey);
try (DbSession dbSession = dbClient.openSession(false)) {
- Set<EmailSubscriberDto> emailSubscribers = dbClient.propertiesDao().findEmailSubscribersForNotification(
+ Set<EmailSubscriberDto> emailSubscribers = dbClient.propertiesDao().findEnabledEmailSubscribersForNotification(
dbSession, dispatcherKey, EmailNotificationChannel.class.getSimpleName(), projectKey);
return keepAuthorizedEmailSubscribers(dbSession, projectKey, subscriberPermissionsOnProject, emailSubscribers);
}
try (DbSession dbSession = dbClient.openSession(false)) {
- Set<EmailSubscriberDto> emailSubscribers = dbClient.propertiesDao().findEmailSubscribersForNotification(
+ Set<EmailSubscriberDto> emailSubscribers = dbClient.propertiesDao().findEnabledEmailSubscribersForNotification(
dbSession, dispatcherKey, EmailNotificationChannel.class.getSimpleName(), projectKey, logins);
return keepAuthorizedEmailSubscribers(dbSession, projectKey, subscriberPermissionsOnProject, emailSubscribers);
public static final String GLOBAL_NOTIFICATION = "globalNotification";
public static final String PER_PROJECT_NOTIFICATION = "perProjectNotification";
+ public static final String ENABLED_BY_DEFAULT_NOTIFICATION = "enabledByDefaultNotification";
+ public static final String PERMISSION_RESTRICTION = "permissionRestriction";
private String dispatcherKey;
private Map<String, String> properties;
when(authorizationDao.selectQualityGateAdministratorLogins(dbSession))
.thenReturn(Set.of(new EmailSubscriberDto().setLogin("login1").setEmail("email@email.com"), new EmailSubscriberDto().setLogin("login2").setEmail("email2@email.com")));
- when(propertiesDao.findEmailSubscribersForNotification(eq(dbSession), eq(QualityGateMetricsUpdateNotificationHandler.KEY), any(), isNull(), eq(Set.of("login1", "login2"))))
- .thenReturn(Set.of(new EmailSubscriberDto().setLogin("login1").setEmail("email@email.com"), new EmailSubscriberDto().setLogin("login2").setEmail("email2@email.com")));
+ when(
+ propertiesDao.findDisabledEmailSubscribersForNotification(eq(dbSession), eq(QualityGateMetricsUpdateNotificationHandler.KEY), any(), isNull(),
+ eq(Set.of("login1", "login2"))))
+ .thenReturn(Set.of());
Assertions.assertThat(underTest.toEmailDeliveryRequests(List.of(new QualityGateMetricsUpdateNotification(true))))
.extracting(EmailNotificationChannel.EmailDeliveryRequest::recipientEmail, EmailNotificationChannel.EmailDeliveryRequest::notification)
}
@Test
- void toEmailDeliveryRequests_whenHasAdminsButNotSubscribed_shouldNotSendExpectedNotification() {
+ void toEmailDeliveryRequests_whenHasAdminsButHasUnsubscribe_shouldNotSendExpectedNotification() {
when(authorizationDao.selectQualityGateAdministratorLogins(dbSession))
.thenReturn(Set.of(new EmailSubscriberDto().setLogin("login1").setEmail("email@email.com")));
- when(propertiesDao.findEmailSubscribersForNotification(eq(dbSession), eq(QualityGateMetricsUpdateNotificationHandler.KEY), any(), isNull(), eq(Set.of("login1"))))
- .thenReturn(Set.of());
+ when(propertiesDao.findDisabledEmailSubscribersForNotification(eq(dbSession), eq(QualityGateMetricsUpdateNotificationHandler.KEY), any(), isNull(), eq(Set.of("login1"))))
+ .thenReturn(Set.of(new EmailSubscriberDto().setLogin("login1").setEmail("email@email.com")));
Assertions.assertThat(underTest.toEmailDeliveryRequests(List.of(new QualityGateMetricsUpdateNotification(true))))
.isEmpty();
String globalPermission = secure().nextAlphanumeric(4);
String projectPermission = secure().nextAlphanumeric(5);
String projectKey = secure().nextAlphabetic(6);
- when(propertiesDao.findEmailSubscribersForNotification(dbSession, dispatcherKey, "EmailNotificationChannel", projectKey))
+ when(propertiesDao.findEnabledEmailSubscribersForNotification(dbSession, dispatcherKey, "EmailNotificationChannel", projectKey))
.thenReturn(Collections.emptySet());
Set<EmailRecipient> emailRecipients = underTest.findSubscribedEmailRecipients(dispatcherKey, projectKey,
Set<String> logins = IntStream.range(0, 1 + new Random().nextInt(10))
.mapToObj(i -> "login_" + i)
.collect(Collectors.toSet());
- when(propertiesDao.findEmailSubscribersForNotification(dbSession, dispatcherKey, "EmailNotificationChannel", projectKey, logins))
+ when(propertiesDao.findEnabledEmailSubscribersForNotification(dbSession, dispatcherKey, "EmailNotificationChannel", projectKey, logins))
.thenReturn(Collections.emptySet());
Set<EmailRecipient> emailRecipients = underTest.findSubscribedEmailRecipients(dispatcherKey, projectKey, logins,
String globalPermission = secure().nextAlphanumeric(4);
String projectPermission = secure().nextAlphanumeric(5);
String projectKey = secure().nextAlphabetic(6);
- when(propertiesDao.findEmailSubscribersForNotification(dbSession, dispatcherKey, "EmailNotificationChannel", projectKey))
+ when(propertiesDao.findEnabledEmailSubscribersForNotification(dbSession, dispatcherKey, "EmailNotificationChannel", projectKey))
.thenReturn(
newHashSet(EmailSubscriberDto.create("user1", false, "user1@foo"), EmailSubscriberDto.create("user3", false, "user3@foo"),
EmailSubscriberDto.create("user3", true, "user3@foo")));
String projectPermission = secure().nextAlphanumeric(5);
String projectKey = secure().nextAlphabetic(6);
Set<String> logins = ImmutableSet.of("user1", "user2", "user3");
- when(propertiesDao.findEmailSubscribersForNotification(dbSession, dispatcherKey, "EmailNotificationChannel", projectKey, logins))
+ when(propertiesDao.findEnabledEmailSubscribersForNotification(dbSession, dispatcherKey, "EmailNotificationChannel", projectKey, logins))
.thenReturn(
newHashSet(EmailSubscriberDto.create("user1", false, "user1@foo"), EmailSubscriberDto.create("user3", false, "user3@foo"),
EmailSubscriberDto.create("user3", true, "user3@foo")));
.mapToObj(i -> EmailSubscriberDto.create("user" + i, true, "user" + i + "@sonarsource.com"))
.collect(Collectors.toSet());
Set<String> logins = subscribers.stream().map(EmailSubscriberDto::getLogin).collect(Collectors.toSet());
- when(propertiesDao.findEmailSubscribersForNotification(dbSession, dispatcherKey, "EmailNotificationChannel", projectKey))
+ when(propertiesDao.findEnabledEmailSubscribersForNotification(dbSession, dispatcherKey, "EmailNotificationChannel", projectKey))
.thenReturn(subscribers);
when(authorizationDao.keepAuthorizedLoginsOnEntity(dbSession, logins, projectKey, globalPermission))
.thenReturn(logins);
.mapToObj(i -> EmailSubscriberDto.create("user" + i, true, "user" + i + "@sonarsource.com"))
.collect(Collectors.toSet());
Set<String> logins = subscribers.stream().map(EmailSubscriberDto::getLogin).collect(Collectors.toSet());
- when(propertiesDao.findEmailSubscribersForNotification(dbSession, dispatcherKey, "EmailNotificationChannel", projectKey, logins))
+ when(propertiesDao.findEnabledEmailSubscribersForNotification(dbSession, dispatcherKey, "EmailNotificationChannel", projectKey, logins))
.thenReturn(subscribers);
when(authorizationDao.keepAuthorizedLoginsOnEntity(dbSession, logins, projectKey, globalPermission))
.thenReturn(logins);
.mapToObj(i -> EmailSubscriberDto.create("user" + i, false, "user" + i + "@sonarsource.com"))
.collect(Collectors.toSet());
Set<String> logins = subscribers.stream().map(EmailSubscriberDto::getLogin).collect(Collectors.toSet());
- when(propertiesDao.findEmailSubscribersForNotification(dbSession, dispatcherKey, "EmailNotificationChannel", projectKey))
+ when(propertiesDao.findEnabledEmailSubscribersForNotification(dbSession, dispatcherKey, "EmailNotificationChannel", projectKey))
.thenReturn(subscribers);
when(authorizationDao.keepAuthorizedLoginsOnEntity(dbSession, logins, projectKey, projectPermission))
.thenReturn(logins);
.mapToObj(i -> EmailSubscriberDto.create("user" + i, false, "user" + i + "@sonarsource.com"))
.collect(Collectors.toSet());
Set<String> logins = subscribers.stream().map(EmailSubscriberDto::getLogin).collect(Collectors.toSet());
- when(propertiesDao.findEmailSubscribersForNotification(dbSession, dispatcherKey, "EmailNotificationChannel", projectKey, logins))
+ when(propertiesDao.findEnabledEmailSubscribersForNotification(dbSession, dispatcherKey, "EmailNotificationChannel", projectKey, logins))
.thenReturn(subscribers);
when(authorizationDao.keepAuthorizedLoginsOnEntity(dbSession, logins, projectKey, projectPermission))
.thenReturn(logins);
private final WsActionTester ws = new WsActionTester(new AddAction(new NotificationCenter(
new NotificationDispatcherMetadata[] {},
new NotificationChannel[] {emailChannel, twitterChannel, defaultChannel}),
- new NotificationUpdater(dbClient), dispatchers, dbClient, TestComponentFinder.from(db), userSession));
+ new NotificationUpdater(dbClient, dispatchers), dispatchers, dbClient, TestComponentFinder.from(db), userSession));
@Test
void add_to_email_channel_by_default() {
call(NOTIF_MY_NEW_ISSUES, null, null, null);
- db.notifications().assertExists(defaultChannel.getKey(), NOTIF_MY_NEW_ISSUES, userSession.getUuid(), null);
+ db.notifications().assertExists(defaultChannel.getKey(), NOTIF_MY_NEW_ISSUES, userSession.getUuid(), null, true);
}
@Test
call(NOTIF_NEW_QUALITY_GATE_STATUS, twitterChannel.getKey(), null, null);
- db.notifications().assertExists(twitterChannel.getKey(), NOTIF_NEW_QUALITY_GATE_STATUS, userSession.getUuid(), null);
+ db.notifications().assertExists(twitterChannel.getKey(), NOTIF_NEW_QUALITY_GATE_STATUS, userSession.getUuid(), null, true);
}
@Test
call(NOTIF_MY_NEW_ISSUES, null, project.getKey(), null);
- db.notifications().assertExists(defaultChannel.getKey(), NOTIF_MY_NEW_ISSUES, userSession.getUuid(), project);
+ db.notifications().assertExists(defaultChannel.getKey(), NOTIF_MY_NEW_ISSUES, userSession.getUuid(), project, true);
}
@Test
call(NOTIF_MY_NEW_ISSUES, null, project.getKey(), null);
- db.notifications().assertExists(defaultChannel.getKey(), NOTIF_MY_NEW_ISSUES, userSession.getUuid(), project);
+ db.notifications().assertExists(defaultChannel.getKey(), NOTIF_MY_NEW_ISSUES, userSession.getUuid(), project, true);
}
@Test
call(NOTIF_MY_NEW_ISSUES, null, null, null);
- db.notifications().assertExists(defaultChannel.getKey(), NOTIF_MY_NEW_ISSUES, userSession.getUuid(), project);
- db.notifications().assertExists(defaultChannel.getKey(), NOTIF_MY_NEW_ISSUES, userSession.getUuid(), null);
+ db.notifications().assertExists(defaultChannel.getKey(), NOTIF_MY_NEW_ISSUES, userSession.getUuid(), project, true);
+ db.notifications().assertExists(defaultChannel.getKey(), NOTIF_MY_NEW_ISSUES, userSession.getUuid(), null, true);
}
@Test
userSession.addProjectPermission(USER, project);
call(NOTIF_MY_NEW_ISSUES, null, project.getKey(), null);
- db.notifications().assertExists(defaultChannel.getKey(), NOTIF_MY_NEW_ISSUES, userSession.getUuid(), project);
- db.notifications().assertExists(defaultChannel.getKey(), NOTIF_MY_NEW_ISSUES, userSession.getUuid(), null);
+ db.notifications().assertExists(defaultChannel.getKey(), NOTIF_MY_NEW_ISSUES, userSession.getUuid(), project, true);
+ db.notifications().assertExists(defaultChannel.getKey(), NOTIF_MY_NEW_ISSUES, userSession.getUuid(), null, true);
}
@Test
call(NOTIF_MY_NEW_ISSUES, null, project.getKey(), null);
- db.notifications().assertExists(defaultChannel.getKey(), NOTIF_MY_NEW_ISSUES, userSession.getUuid(), project);
- db.notifications().assertExists(defaultChannel.getKey(), NOTIF_MY_NEW_ISSUES, userSession.getUuid(), null);
+ db.notifications().assertExists(defaultChannel.getKey(), NOTIF_MY_NEW_ISSUES, userSession.getUuid(), project, true);
+ db.notifications().assertExists(defaultChannel.getKey(), NOTIF_MY_NEW_ISSUES, userSession.getUuid(), null, true);
}
@Test
call(NOTIF_MY_NEW_ISSUES, null, null, user.getLogin());
- db.notifications().assertExists(defaultChannel.getKey(), NOTIF_MY_NEW_ISSUES, user.getUuid(), null);
+ db.notifications().assertExists(defaultChannel.getKey(), NOTIF_MY_NEW_ISSUES, user.getUuid(), null, true);
}
@Test
*/
package org.sonar.server.notification.ws;
-import org.junit.Rule;
-import org.junit.Test;
+import java.util.Map;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.RegisterExtension;
import org.sonar.api.server.ws.WebService;
import org.sonar.db.DbClient;
import org.sonar.db.DbSession;
import org.sonar.db.DbTester;
import org.sonar.db.component.ProjectData;
+import org.sonar.db.permission.GlobalPermission;
import org.sonar.db.project.ProjectDto;
import org.sonar.db.user.UserDto;
import org.sonar.server.exceptions.ForbiddenException;
import static org.sonar.server.ws.KeyExamples.KEY_PROJECT_EXAMPLE_001;
import static org.sonar.test.JsonAssert.assertJson;
-public class ListActionIT {
+class ListActionIT {
private static final String NOTIF_MY_NEW_ISSUES = "MyNewIssues";
private static final String NOTIF_NEW_ISSUES = "NewIssues";
private static final String NOTIF_NEW_QUALITY_GATE_STATUS = "NewQualityGateStatus";
+ private static final String NOTIF_CONDITIONS_MISMATCH = "QualityGateConditionsMismatch";
- @Rule
+ @RegisterExtension
public final UserSessionRule userSession = UserSessionRule.standalone();
- @Rule
+ @RegisterExtension
public final DbTester db = DbTester.create();
private final DbClient dbClient = db.getDbClient();
private final NotificationChannel emailChannel = new FakeNotificationChannel("EmailChannel");
private final NotificationChannel twitterChannel = new FakeNotificationChannel("TwitterChannel");
- private final NotificationUpdater notificationUpdater = new NotificationUpdater(dbClient);
private final Dispatchers dispatchers = mock(Dispatchers.class);
+ private final NotificationUpdater notificationUpdater = new NotificationUpdater(dbClient, dispatchers);
private final WsActionTester ws = new WsActionTester(new ListAction(new NotificationCenter(
new NotificationDispatcherMetadata[] {},
dbClient, userSession, dispatchers));
@Test
- public void channels() {
+ void channels() {
UserDto user = db.users().insertUser();
userSession.logIn(user);
}
@Test
- public void overall_dispatchers() {
+ void overall_dispatchers() {
UserDto user = db.users().insertUser();
userSession.logIn(user);
- when(dispatchers.getGlobalDispatchers()).thenReturn(asList(NOTIF_MY_NEW_ISSUES, NOTIF_NEW_ISSUES, NOTIF_NEW_QUALITY_GATE_STATUS));
-
+ when(dispatchers.getGlobalDispatchers()).thenReturn(asList(NOTIF_MY_NEW_ISSUES, NOTIF_NEW_ISSUES, NOTIF_NEW_QUALITY_GATE_STATUS, NOTIF_CONDITIONS_MISMATCH));
+ when(dispatchers.getEnabledByDefaultDispatchers()).thenReturn(singletonList(NOTIF_CONDITIONS_MISMATCH));
ListResponse result = call();
- assertThat(result.getGlobalTypesList()).containsExactly(NOTIF_MY_NEW_ISSUES, NOTIF_NEW_ISSUES, NOTIF_NEW_QUALITY_GATE_STATUS);
+ assertThat(result.getGlobalTypesList()).containsExactly(NOTIF_MY_NEW_ISSUES, NOTIF_NEW_ISSUES, NOTIF_NEW_QUALITY_GATE_STATUS, NOTIF_CONDITIONS_MISMATCH);
}
@Test
- public void per_project_dispatchers() {
+ void per_project_dispatchers() {
UserDto user = db.users().insertUser();
userSession.logIn(user);
when(dispatchers.getProjectDispatchers()).thenReturn(asList(NOTIF_MY_NEW_ISSUES, NOTIF_NEW_QUALITY_GATE_STATUS));
}
@Test
- public void filter_unauthorized_projects() {
+ void filter_unauthorized_projects() {
UserDto user = db.users().insertUser();
userSession.logIn(user);
when(dispatchers.getGlobalDispatchers()).thenReturn(singletonList(NOTIF_MY_NEW_ISSUES));
}
@Test
- public void filter_channels() {
+ void filter_channels() {
UserDto user = db.users().insertUser();
userSession.logIn(user);
when(dispatchers.getGlobalDispatchers()).thenReturn(asList(NOTIF_MY_NEW_ISSUES, NOTIF_NEW_ISSUES, NOTIF_NEW_QUALITY_GATE_STATUS));
}
@Test
- public void filter_overall_dispatchers() {
+ void filter_overall_dispatchers() {
UserDto user = db.users().insertUser();
userSession.logIn(user);
when(dispatchers.getGlobalDispatchers()).thenReturn(asList(NOTIF_MY_NEW_ISSUES, NOTIF_NEW_ISSUES, NOTIF_NEW_QUALITY_GATE_STATUS));
}
@Test
- public void filter_per_project_dispatchers() {
+ void filter_enabled_by_default_dispatchers() {
+ UserDto user = db.users().insertUser();
+ userSession.logIn(user);
+ when(dispatchers.getGlobalDispatchers()).thenReturn(asList(NOTIF_MY_NEW_ISSUES, NOTIF_NEW_ISSUES, NOTIF_NEW_QUALITY_GATE_STATUS, NOTIF_CONDITIONS_MISMATCH));
+ when(dispatchers.getEnabledByDefaultDispatchers()).thenReturn(singletonList(NOTIF_CONDITIONS_MISMATCH));
+ notificationUpdater.add(dbSession, emailChannel.getKey(), NOTIF_MY_NEW_ISSUES, user, null);
+ notificationUpdater.add(dbSession, emailChannel.getKey(), "Unknown Notification", user, null);
+ dbSession.commit();
+
+ ListResponse result = call();
+
+ assertThat(result.getNotificationsList()).extracting(Notification::getType).containsOnly(NOTIF_MY_NEW_ISSUES, NOTIF_CONDITIONS_MISMATCH);
+ }
+
+ @Test
+ void filter_whenDispatcherEnabledByDefaultAndRemoved_shouldNotShowNotification() {
+ UserDto user = db.users().insertUser();
+ userSession.logIn(user);
+ when(dispatchers.getGlobalDispatchers()).thenReturn(asList(NOTIF_MY_NEW_ISSUES, NOTIF_CONDITIONS_MISMATCH));
+ when(dispatchers.getEnabledByDefaultDispatchers()).thenReturn(singletonList(NOTIF_CONDITIONS_MISMATCH));
+ notificationUpdater.add(dbSession, emailChannel.getKey(), NOTIF_MY_NEW_ISSUES, user, null);
+ notificationUpdater.remove(dbSession, emailChannel.getKey(), NOTIF_CONDITIONS_MISMATCH, user, null);
+ notificationUpdater.remove(dbSession, twitterChannel.getKey(), NOTIF_CONDITIONS_MISMATCH, user, null);
+ dbSession.commit();
+
+ ListResponse result = call();
+
+ assertThat(result.getNotificationsList()).extracting(Notification::getType).containsOnly(NOTIF_MY_NEW_ISSUES);
+ }
+
+ @Test
+ void filter_whenUserHasPermissionToDispatcher_shouldShowNotifications() {
+ UserDto user = db.users().insertUser();
+ userSession.logIn(user);
+ db.users().insertGlobalPermissionOnUser(user, GlobalPermission.ADMINISTER_QUALITY_GATES);
+ when(dispatchers.getGlobalDispatchers()).thenReturn(asList(NOTIF_MY_NEW_ISSUES, NOTIF_CONDITIONS_MISMATCH));
+ when(dispatchers.getPermissionRestrictedDispatchers()).thenReturn(Map.of(NOTIF_CONDITIONS_MISMATCH, GlobalPermission.ADMINISTER_QUALITY_GATES.getKey()));
+
+ notificationUpdater.add(dbSession, emailChannel.getKey(), NOTIF_MY_NEW_ISSUES, user, null);
+ notificationUpdater.add(dbSession, emailChannel.getKey(), NOTIF_CONDITIONS_MISMATCH, user, null);
+
+ dbSession.commit();
+
+ ListResponse result = call();
+
+ assertThat(result.getGlobalTypesList()).containsOnly(NOTIF_MY_NEW_ISSUES, NOTIF_CONDITIONS_MISMATCH);
+ assertThat(result.getNotificationsList()).extracting(Notification::getType).containsOnly(NOTIF_MY_NEW_ISSUES, NOTIF_CONDITIONS_MISMATCH);
+ }
+
+ @Test
+ void filter_whenAdminAndUserHasNoPermission_shouldNotShowNotifications() {
+ UserDto admin = db.users().insertUser();
+ db.users().insertGlobalPermissionOnUser(admin, GlobalPermission.ADMINISTER_QUALITY_GATES);
+ userSession.logIn(admin).setSystemAdministrator();
+
+ UserDto user = db.users().insertUser();
+
+ when(dispatchers.getGlobalDispatchers()).thenReturn(asList(NOTIF_MY_NEW_ISSUES, NOTIF_CONDITIONS_MISMATCH));
+ when(dispatchers.getPermissionRestrictedDispatchers()).thenReturn(Map.of(NOTIF_CONDITIONS_MISMATCH, GlobalPermission.ADMINISTER_QUALITY_GATES.getKey()));
+
+ notificationUpdater.add(dbSession, emailChannel.getKey(), NOTIF_MY_NEW_ISSUES, user, null);
+ notificationUpdater.add(dbSession, emailChannel.getKey(), NOTIF_CONDITIONS_MISMATCH, user, null);
+
+ dbSession.commit();
+
+ ListResponse result = call(user.getLogin());
+
+ assertThat(result.getGlobalTypesList()).containsOnly(NOTIF_MY_NEW_ISSUES);
+ assertThat(result.getNotificationsList()).extracting(Notification::getType).containsOnly(NOTIF_MY_NEW_ISSUES);
+ }
+
+ @Test
+ void filter_whenUserHasNotPermissions_shouldNotShowNotifications() {
+ UserDto user = db.users().insertUser();
+ userSession.logIn(user);
+
+ when(dispatchers.getGlobalDispatchers()).thenReturn(asList(NOTIF_MY_NEW_ISSUES, NOTIF_CONDITIONS_MISMATCH, NOTIF_NEW_QUALITY_GATE_STATUS));
+
+ when(dispatchers.getPermissionRestrictedDispatchers()).thenReturn(Map.of(NOTIF_CONDITIONS_MISMATCH, GlobalPermission.ADMINISTER_QUALITY_GATES.getKey(),
+ NOTIF_NEW_QUALITY_GATE_STATUS, GlobalPermission.ADMINISTER_QUALITY_GATES.getKey()));
+
+ when(dispatchers.getEnabledByDefaultDispatchers()).thenReturn(singletonList(NOTIF_CONDITIONS_MISMATCH));
+
+ notificationUpdater.add(dbSession, emailChannel.getKey(), NOTIF_MY_NEW_ISSUES, user, null);
+ notificationUpdater.add(dbSession, emailChannel.getKey(), NOTIF_NEW_QUALITY_GATE_STATUS, user, null);
+
+ dbSession.commit();
+
+ ListResponse result = call();
+
+ assertThat(result.getGlobalTypesList()).containsOnly(NOTIF_MY_NEW_ISSUES);
+ assertThat(result.getNotificationsList()).extracting(Notification::getType).containsOnly(NOTIF_MY_NEW_ISSUES);
+ }
+
+ @Test
+ void filter_per_project_dispatchers() {
UserDto user = db.users().insertUser();
userSession.logIn(user);
when(dispatchers.getProjectDispatchers()).thenReturn(singletonList(NOTIF_MY_NEW_ISSUES));
}
@Test
- public void order_with_global_then_by_channel_and_dispatcher() {
+ void order_with_global_then_by_channel_and_dispatcher() {
UserDto user = db.users().insertUser();
userSession.logIn(user);
when(dispatchers.getGlobalDispatchers()).thenReturn(asList(NOTIF_MY_NEW_ISSUES, NOTIF_NEW_ISSUES, NOTIF_NEW_QUALITY_GATE_STATUS));
}
@Test
- public void list_user_notifications_as_system_admin() {
+ void list_user_notifications_as_system_admin() {
UserDto user = db.users().insertUser();
when(dispatchers.getGlobalDispatchers()).thenReturn(asList(NOTIF_MY_NEW_ISSUES, NOTIF_NEW_ISSUES, NOTIF_NEW_QUALITY_GATE_STATUS));
userSession.logIn(user).setSystemAdministrator();
}
@Test
- public void fail_if_login_and_not_system_admin() {
+ void fail_if_login_and_not_system_admin() {
UserDto user = db.users().insertUser();
userSession.logIn(user).setNonSystemAdministrator();
when(dispatchers.getGlobalDispatchers()).thenReturn(singletonList(NOTIF_MY_NEW_ISSUES));
}
@Test
- public void fail_if_login_is_provided_and_unknown() {
+ void fail_if_login_is_provided_and_unknown() {
userSession.logIn().setSystemAdministrator();
assertThatThrownBy(() -> call("LOGIN 404"))
}
@Test
- public void json_example() {
+ void json_example() {
UserDto user = db.users().insertUser();
userSession.logIn(user);
when(dispatchers.getGlobalDispatchers()).thenReturn(asList(NOTIF_MY_NEW_ISSUES, NOTIF_NEW_ISSUES, NOTIF_NEW_QUALITY_GATE_STATUS));
}
@Test
- public void definition() {
+ void definition() {
WebService.Action definition = ws.getDef();
assertThat(definition.key()).isEqualTo("list");
}
@Test
- public void fail_when_not_authenticated() {
+ void fail_when_not_authenticated() {
userSession.anonymous();
assertThatThrownBy(this::call)
*/
package org.sonar.server.notification.ws;
-import org.junit.Rule;
-import org.junit.Test;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.RegisterExtension;
import org.sonar.api.notifications.Notification;
import org.sonar.db.DbClient;
import org.sonar.db.DbSession;
import static org.sonar.server.notification.ws.NotificationsWsParameters.PARAM_PROJECT;
import static org.sonar.server.notification.ws.NotificationsWsParameters.PARAM_TYPE;
-public class RemoveActionIT {
+class RemoveActionIT {
private static final String NOTIF_MY_NEW_ISSUES = "Dispatcher1";
private static final String NOTIF_NEW_ISSUES = "Dispatcher2";
private static final String NOTIF_NEW_QUALITY_GATE_STATUS = "Dispatcher3";
- @Rule
+ @RegisterExtension
public final UserSessionRule userSession = UserSessionRule.standalone();
- @Rule
+ @RegisterExtension
public final DbTester db = DbTester.create();
private final DbClient dbClient = db.getDbClient();
private final DbSession dbSession = db.getSession();
// default channel, based on class simple name
private final NotificationChannel defaultChannel = new FakeNotificationChannel("EmailNotificationChannel");
- private final NotificationUpdater notificationUpdater = new NotificationUpdater(dbClient);
private final Dispatchers dispatchers = mock(Dispatchers.class);
+ private final NotificationUpdater notificationUpdater = new NotificationUpdater(dbClient, dispatchers);
private final RemoveRequest request = new RemoveRequest().setType(NOTIF_MY_NEW_ISSUES);
new NotificationChannel[] {emailChannel, twitterChannel, defaultChannel}), notificationUpdater, dispatchers, dbClient, TestComponentFinder.from(db), userSession));
@Test
- public void remove_to_email_channel_by_default() {
+ void remove_to_email_channel_by_default() {
UserDto user = db.users().insertUser();
userSession.logIn(user);
when(dispatchers.getGlobalDispatchers()).thenReturn(singletonList(NOTIF_MY_NEW_ISSUES));
}
@Test
- public void remove_from_a_specific_channel() {
+ void remove_from_a_specific_channel() {
UserDto user = db.users().insertUser();
userSession.logIn(user);
when(dispatchers.getGlobalDispatchers()).thenReturn(singletonList(NOTIF_NEW_QUALITY_GATE_STATUS));
}
@Test
- public void remove_a_project_notification() {
+ void remove_a_project_notification() {
UserDto user = db.users().insertUser();
userSession.logIn(user);
when(dispatchers.getGlobalDispatchers()).thenReturn(singletonList(NOTIF_MY_NEW_ISSUES));
}
@Test
- public void fail_when_remove_a_global_notification_when_a_project_one_exists() {
+ void fail_when_remove_a_global_notification_when_a_project_one_exists() {
UserDto user = db.users().insertUser();
userSession.logIn(user);
when(dispatchers.getGlobalDispatchers()).thenReturn(singletonList(NOTIF_MY_NEW_ISSUES));
}
@Test
- public void fail_when_remove_a_project_notification_when_a_global_one_exists() {
+ void fail_when_remove_a_project_notification_when_a_global_one_exists() {
UserDto user = db.users().insertUser();
userSession.logIn(user);
when(dispatchers.getGlobalDispatchers()).thenReturn(singletonList(NOTIF_MY_NEW_ISSUES));
}
@Test
- public void http_no_content() {
+ void http_no_content() {
UserDto user = db.users().insertUser();
userSession.logIn(user);
when(dispatchers.getGlobalDispatchers()).thenReturn(singletonList(NOTIF_MY_NEW_ISSUES));
}
@Test
- public void remove_a_notification_from_a_user_as_system_administrator() {
+ void remove_a_notification_from_a_user_as_system_administrator() {
UserDto user = db.users().insertUser();
userSession.logIn(user);
when(dispatchers.getGlobalDispatchers()).thenReturn(singletonList(NOTIF_MY_NEW_ISSUES));
notificationUpdater.add(dbSession, defaultChannel.getKey(), NOTIF_MY_NEW_ISSUES, user, null);
- db.notifications().assertExists(defaultChannel.getKey(), NOTIF_MY_NEW_ISSUES, user.getUuid(), null);
+ db.notifications().assertExists(defaultChannel.getKey(), NOTIF_MY_NEW_ISSUES, user.getUuid(), null, true);
userSession.logIn().setSystemAdministrator();
dbSession.commit();
}
@Test
- public void fail_if_login_is_provided_and_unknown() {
+ void fail_if_login_is_provided_and_unknown() {
UserDto user = db.users().insertUser();
userSession.logIn(user).setSystemAdministrator();
when(dispatchers.getGlobalDispatchers()).thenReturn(singletonList(NOTIF_MY_NEW_ISSUES));
}
@Test
- public void fail_if_login_provided_and_not_system_administrator() {
+ void fail_if_login_provided_and_not_system_administrator() {
UserDto user = db.users().insertUser();
userSession.logIn(user).setNonSystemAdministrator();
when(dispatchers.getGlobalDispatchers()).thenReturn(singletonList(NOTIF_MY_NEW_ISSUES));
}
@Test
- public void fail_when_notification_does_not_exist() {
+ void fail_when_notification_does_not_exist() {
UserDto user = db.users().insertUser();
userSession.logIn(user);
when(dispatchers.getGlobalDispatchers()).thenReturn(singletonList(NOTIF_MY_NEW_ISSUES));
}
@Test
- public void fail_when_unknown_channel() {
+ void fail_when_unknown_channel() {
UserDto user = db.users().insertUser();
userSession.logIn(user);
when(dispatchers.getGlobalDispatchers()).thenReturn(singletonList(NOTIF_MY_NEW_ISSUES));
}
@Test
- public void fail_when_unknown_global_dispatcher() {
+ void fail_when_unknown_global_dispatcher() {
UserDto user = db.users().insertUser();
userSession.logIn(user);
when(dispatchers.getGlobalDispatchers()).thenReturn(asList(NOTIF_MY_NEW_ISSUES, NOTIF_NEW_ISSUES, NOTIF_NEW_QUALITY_GATE_STATUS));
}
@Test
- public void fail_when_unknown_project_dispatcher() {
+ void fail_when_unknown_project_dispatcher() {
UserDto user = db.users().insertUser();
userSession.logIn(user);
when(dispatchers.getGlobalDispatchers()).thenReturn(singletonList(NOTIF_MY_NEW_ISSUES));
}
@Test
- public void fail_when_no_type_parameter() {
+ void fail_when_no_type_parameter() {
UserDto user = db.users().insertUser();
userSession.logIn(user);
when(dispatchers.getGlobalDispatchers()).thenReturn(singletonList(NOTIF_MY_NEW_ISSUES));
}
@Test
- public void fail_when_project_is_unknown() {
+ void fail_when_project_is_unknown() {
UserDto user = db.users().insertUser();
userSession.logIn(user);
when(dispatchers.getGlobalDispatchers()).thenReturn(singletonList(NOTIF_MY_NEW_ISSUES));
}
@Test
- public void fail_when_component_is_not_a_project() {
+ void fail_when_component_is_not_a_project() {
UserDto user = db.users().insertUser();
userSession.logIn(user);
when(dispatchers.getGlobalDispatchers()).thenReturn(singletonList(NOTIF_MY_NEW_ISSUES));
}
@Test
- public void fail_when_not_authenticated() {
+ void fail_when_not_authenticated() {
userSession.anonymous();
when(dispatchers.getGlobalDispatchers()).thenReturn(singletonList(NOTIF_MY_NEW_ISSUES));
.isInstanceOf(UnauthorizedException.class);
}
+ @Test
+ void execute_whenDispatcherEnabledByDefault_shouldAddDisabledNotification() {
+ UserDto user = db.users().insertUser();
+ userSession.logIn(user);
+ when(dispatchers.getGlobalDispatchers()).thenReturn(singletonList(NOTIF_MY_NEW_ISSUES));
+ when(dispatchers.getEnabledByDefaultDispatchers()).thenReturn(singletonList(NOTIF_MY_NEW_ISSUES));
+
+ db.notifications().assertDoesNotExist(defaultChannel.getKey(), NOTIF_MY_NEW_ISSUES, user.getUuid(), null);
+
+ call(request);
+
+ db.notifications().assertExists(defaultChannel.getKey(), NOTIF_MY_NEW_ISSUES, user.getUuid(), null, false);
+ }
+
private TestResponse call(RemoveRequest remove) {
TestRequest request = ws.newRequest();
request.setParam(PARAM_TYPE, remove.getType());
package org.sonar.server.notification.ws;
import java.util.List;
+import java.util.Map;
public interface Dispatchers {
List<String> getGlobalDispatchers();
List<String> getProjectDispatchers();
+
+ List<String> getEnabledByDefaultDispatchers();
+
+ Map<String, String> getPermissionRestrictedDispatchers();
}
package org.sonar.server.notification.ws;
import java.util.List;
+import java.util.Map;
import org.sonar.api.Startable;
+import static org.sonar.server.notification.NotificationDispatcherMetadata.ENABLED_BY_DEFAULT_NOTIFICATION;
import static org.sonar.server.notification.NotificationDispatcherMetadata.GLOBAL_NOTIFICATION;
+import static org.sonar.server.notification.NotificationDispatcherMetadata.PERMISSION_RESTRICTION;
import static org.sonar.server.notification.NotificationDispatcherMetadata.PER_PROJECT_NOTIFICATION;
public class DispatchersImpl implements Dispatchers, Startable {
private List<String> projectDispatchers;
private List<String> globalDispatchers;
+ private List<String> enabledByDefaultDispatchers;
+ private Map<String, String> permissionRestrictedDispatchers;
public DispatchersImpl(NotificationCenter notificationCenter) {
this.notificationCenter = notificationCenter;
return projectDispatchers;
}
+ @Override
+ public List<String> getEnabledByDefaultDispatchers() {
+ return enabledByDefaultDispatchers;
+ }
+
+ @Override
+ public Map<String, String> getPermissionRestrictedDispatchers() {
+ return permissionRestrictedDispatchers;
+ }
+
@Override
public void start() {
this.globalDispatchers = notificationCenter.getDispatcherKeysForProperty(GLOBAL_NOTIFICATION, "true")
.stream()
.sorted()
.toList();
+ this.enabledByDefaultDispatchers = notificationCenter.getDispatcherKeysForProperty(ENABLED_BY_DEFAULT_NOTIFICATION, "true");
+ this.permissionRestrictedDispatchers = notificationCenter.getValueByDispatchers(PERMISSION_RESTRICTION);
}
@Override
import java.util.function.Predicate;
import java.util.function.UnaryOperator;
import java.util.stream.Collectors;
+import java.util.stream.Stream;
+import javax.annotation.Nullable;
import org.sonar.api.server.ws.Request;
import org.sonar.api.server.ws.Response;
import org.sonar.api.server.ws.WebService;
try (DbSession dbSession = dbClient.openSession(false)) {
checkPermissions(request);
UserDto user = getUser(dbSession, request);
-
+ Set<String> globalPermissions = getGlobalPermissions(dbSession, user);
return Optional
.of(ListResponse.newBuilder())
.map(r -> r.addAllChannels(channels))
- .map(r -> r.addAllGlobalTypes(dispatchers.getGlobalDispatchers()))
- .map(r -> r.addAllPerProjectTypes(dispatchers.getProjectDispatchers()))
- .map(addNotifications(dbSession, user))
+ .map(r -> r.addAllGlobalTypes(getAllowedGlobalDispatchers(globalPermissions)))
+ .map(r -> r.addAllPerProjectTypes(getAllowedProjectDispatchers(globalPermissions)))
+ .map(addNotifications(dbSession, user, globalPermissions))
.map(ListResponse.Builder::build)
.orElseThrow();
}
}
+ private Set<String> getGlobalPermissions(DbSession dbSession, UserDto userDto) {
+ return dbClient.authorizationDao().selectGlobalPermissions(dbSession, userDto.getUuid());
+ }
+
+ private List<String> getAllowedGlobalDispatchers(Set<String> globalPermissions) {
+ return dispatchers.getGlobalDispatchers()
+ .stream()
+ .filter(d -> hasUserPermission(globalPermissions, d))
+ .toList();
+ }
+
+ private List<String> getAllowedProjectDispatchers(Set<String> globalPermissions) {
+ return dispatchers.getProjectDispatchers()
+ .stream()
+ .filter(d -> hasUserPermission(globalPermissions, d))
+ .toList();
+ }
+
+ private boolean hasUserPermission(Set<String> globalPermissions, String dispatcher) {
+ if (!dispatchers.getPermissionRestrictedDispatchers().containsKey(dispatcher)) {
+ return true;
+ }
+ String globalPermission = dispatchers.getPermissionRestrictedDispatchers().get(dispatcher);
+ return globalPermissions.contains(globalPermission);
+ }
+
private UserDto getUser(DbSession dbSession, Request request) {
String login = request.param(PARAM_LOGIN) == null ? userSession.getLogin() : request.param(PARAM_LOGIN);
return checkFound(dbClient.userDao().selectByLogin(dbSession, login), "User '%s' not found", login);
}
- private UnaryOperator<ListResponse.Builder> addNotifications(DbSession dbSession, UserDto user) {
+ private UnaryOperator<ListResponse.Builder> addNotifications(DbSession dbSession, UserDto user, Set<String> globalPermissions) {
return response -> {
List<PropertyDto> properties = dbClient.propertiesDao().selectByQuery(PropertyQuery.builder().setUserUuid(user.getUuid()).build(),
dbSession);
Notification.Builder notification = Notification.newBuilder();
- properties.stream()
+ Set<PropertyDto> notificationProps = properties.stream()
.filter(isNotification)
- .filter(channelAndDispatcherAuthorized())
- .filter(isComponentInDb)
- .map(toWsNotification(notification, entitiesByUuid))
+ .filter(channelAndDispatcherAuthorized(globalPermissions))
+ .filter(isComponentInDb).collect(Collectors.toSet());
+
+ Set<Notification> activeNotifications = notificationProps.stream()
+ .filter(prop -> Boolean.parseBoolean(prop.getValue()))
+ .map(p -> toWsNotification(notification, entitiesByUuid, p.getKey(), p.getEntityUuid()))
+ .collect(Collectors.toSet());
+
+ Set<Notification> notificationsEnabledByDefault = getEnabledByDefaultNotifications(notificationProps, notification, entitiesByUuid, globalPermissions);
+
+ Stream.concat(activeNotifications.stream(), notificationsEnabledByDefault.stream())
.sorted(comparing(Notification::getProject, nullsFirst(naturalOrder()))
.thenComparing(Notification::getChannel)
.thenComparing(Notification::getType))
};
}
- private Predicate<PropertyDto> channelAndDispatcherAuthorized() {
+ private Set<Notification> getEnabledByDefaultNotifications(Set<PropertyDto> notificationProps, Builder notificationBuilder, Map<String, EntityDto> entitiesByUuid,
+ Set<String> globalPermissions) {
+ Set<String> disabledNotifications = notificationProps.stream()
+ .filter(prop -> !Boolean.parseBoolean(prop.getValue()))
+ .map(PropertyDto::getKey)
+ .collect(Collectors.toSet());
+
+ return dispatchers.getEnabledByDefaultDispatchers()
+ .stream()
+ .filter(d -> hasUserPermission(globalPermissions, d))
+ .flatMap(dispatcher -> channels.stream()
+ .filter(channel -> !isNotificationDisabled(disabledNotifications, dispatcher, channel))
+ .map(channel -> toWsNotification(notificationBuilder, entitiesByUuid, "notification.%s.%s".formatted(dispatcher, channel), null)))
+ .collect(Collectors.toSet());
+ }
+
+ private static boolean isNotificationDisabled(Set<String> disabledNotification, String dispatcher, String channel) {
+ return disabledNotification.contains("notification.%s.%s".formatted(dispatcher, channel));
+ }
+
+ private Predicate<PropertyDto> channelAndDispatcherAuthorized(Set<String> globalPermissions) {
return prop -> {
List<String> key = PROPERTY_KEY_SPLITTER.splitToList(prop.getKey());
return key.size() == 3
&& channels.contains(key.get(2))
- && isDispatcherAuthorized(prop, key.get(1));
+ && isDispatcherAuthorized(prop, key.get(1), globalPermissions);
};
}
- private boolean isDispatcherAuthorized(PropertyDto prop, String dispatcher) {
- return (prop.getEntityUuid() != null && dispatchers.getProjectDispatchers().contains(dispatcher)) || dispatchers.getGlobalDispatchers().contains(dispatcher);
+ private boolean isDispatcherAuthorized(PropertyDto prop, String dispatcher, Set<String> globalPermissions) {
+ return ((prop.getEntityUuid() != null && dispatchers.getProjectDispatchers().contains(dispatcher))
+ || dispatchers.getGlobalDispatchers().contains(dispatcher))
+ && hasUserPermission(globalPermissions, dispatcher);
}
private Map<String, EntityDto> searchProjects(DbSession dbSession, List<PropertyDto> properties) {
.collect(Collectors.toMap(EntityDto::getUuid, Function.identity()));
}
- private static Function<PropertyDto, Notification> toWsNotification(Notification.Builder notification,
- Map<String, EntityDto> projectsByUuid) {
- return property -> {
- notification.clear();
- List<String> propertyKey = Splitter.on(".").splitToList(property.getKey());
- notification.setType(propertyKey.get(1));
- notification.setChannel(propertyKey.get(2));
- ofNullable(property.getEntityUuid()).ifPresent(componentUuid -> populateProjectFields(notification, componentUuid, projectsByUuid));
-
- return notification.build();
- };
+ private static Notification toWsNotification(Builder notification,
+ Map<String, EntityDto> projectsByUuid, String key, @Nullable String entityUuid) {
+ notification.clear();
+ List<String> propertyKey = Splitter.on(".").splitToList(key);
+ notification.setType(propertyKey.get(1));
+ notification.setChannel(propertyKey.get(2));
+ ofNullable(entityUuid).ifPresent(componentUuid -> populateProjectFields(notification, componentUuid, projectsByUuid));
+ return notification.build();
}
private static void populateProjectFields(Builder notification, String componentUuid, Map<String, EntityDto> projectsByUuid) {
import com.google.common.collect.ImmutableList;
import java.util.Arrays;
import java.util.List;
+import java.util.Map;
import javax.annotation.Nullable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
return keys.build();
}
+ public Map<String, String> getValueByDispatchers(String propertyKey) {
+ Map<String, String> valueByDispatchers = new java.util.HashMap<>();
+ for (NotificationDispatcherMetadata metadata : dispatchersMetadata) {
+ String dispatcherKey = metadata.getDispatcherKey();
+ String value = metadata.getProperty(propertyKey);
+ if (value != null) {
+ valueByDispatchers.put(dispatcherKey, value);
+ }
+ }
+ return valueByDispatchers;
+ }
+
}
public class NotificationUpdater {
private static final String PROP_NOTIFICATION_PREFIX = "notification";
- private static final String PROP_NOTIFICATION_VALUE = "true";
+ private static final String PROP_ENABLED_NOTIFICATION_VALUE = "true";
+ private static final String PROP_DISABLED_NOTIFICATION_VALUE = "false";
private final DbClient dbClient;
+ private final Dispatchers dispatchers;
- public NotificationUpdater(DbClient dbClient) {
+ public NotificationUpdater(DbClient dbClient, Dispatchers dispatchers) {
this.dbClient = dbClient;
+ this.dispatchers = dispatchers;
}
/**
String qualifier = project == null ? null : project.getQualifier();
List<PropertyDto> existingNotification = dbClient.propertiesDao().selectByQuery(
- PropertyQuery.builder()
- .setKey(key)
- .setEntityUuid(projectUuid)
- .setUserUuid(user.getUuid())
- .build(),
- dbSession).stream()
+ PropertyQuery.builder()
+ .setKey(key)
+ .setEntityUuid(projectUuid)
+ .setUserUuid(user.getUuid())
+ .build(),
+ dbSession).stream()
.filter(notificationScope(project))
.toList();
checkArgument(existingNotification.isEmpty()
- || !PROP_NOTIFICATION_VALUE.equals(existingNotification.get(0).getValue()), "Notification already added");
+ || !PROP_ENABLED_NOTIFICATION_VALUE.equals(existingNotification.get(0).getValue()), "Notification already added");
dbClient.propertiesDao().saveProperty(dbSession, new PropertyDto()
- .setKey(key)
- .setUserUuid(user.getUuid())
- .setValue(PROP_NOTIFICATION_VALUE)
- .setEntityUuid(projectUuid),
+ .setKey(key)
+ .setUserUuid(user.getUuid())
+ .setValue(PROP_ENABLED_NOTIFICATION_VALUE)
+ .setEntityUuid(projectUuid),
user.getLogin(), projectKey, projectName, qualifier);
}
String qualifier = project == null ? null : project.getQualifier();
List<PropertyDto> existingNotification = dbClient.propertiesDao().selectByQuery(
- PropertyQuery.builder()
- .setKey(key)
- .setEntityUuid(projectUuid)
- .setUserUuid(user.getUuid())
- .build(),
- dbSession).stream()
+ PropertyQuery.builder()
+ .setKey(key)
+ .setEntityUuid(projectUuid)
+ .setUserUuid(user.getUuid())
+ .build(),
+ dbSession).stream()
.filter(notificationScope(project))
.toList();
- checkArgument(!existingNotification.isEmpty() && PROP_NOTIFICATION_VALUE.equals(existingNotification.get(0).getValue()), "Notification doesn't exist");
- dbClient.propertiesDao().delete(dbSession, new PropertyDto()
- .setKey(key)
- .setUserUuid(user.getUuid())
- .setValue(PROP_NOTIFICATION_VALUE)
- .setEntityUuid(projectUuid), user.getLogin(), projectKey, projectName, qualifier);
+ if (dispatchers.getEnabledByDefaultDispatchers().contains(dispatcher)) {
+ dbClient.propertiesDao().saveProperty(dbSession, new PropertyDto()
+ .setKey(key)
+ .setUserUuid(user.getUuid())
+ .setValue(PROP_DISABLED_NOTIFICATION_VALUE)
+ .setEntityUuid(projectUuid),
+ user.getLogin(), projectKey, projectName, qualifier);
+ } else {
+ checkArgument(!existingNotification.isEmpty() && PROP_ENABLED_NOTIFICATION_VALUE.equals(existingNotification.get(0).getValue()), "Notification doesn't exist");
+ dbClient.propertiesDao().delete(dbSession, new PropertyDto()
+ .setKey(key)
+ .setUserUuid(user.getUuid())
+ .setValue(PROP_ENABLED_NOTIFICATION_VALUE)
+ .setEntityUuid(projectUuid), user.getLogin(), projectKey, projectName, qualifier);
+ }
+
}
private static Predicate<PropertyDto> notificationScope(@Nullable EntityDto project) {
*/
package org.sonar.server.notification.ws;
-import org.junit.Test;
+import java.util.Map;
+import org.junit.jupiter.api.Test;
+import org.sonar.db.permission.GlobalPermission;
import org.sonar.server.issue.notification.FPOrAcceptedNotificationHandler;
import org.sonar.server.issue.notification.MyNewIssuesNotificationHandler;
import org.sonar.server.issue.notification.NewIssuesNotificationHandler;
import org.sonar.server.qualitygate.notification.QGChangeNotificationHandler;
import static org.assertj.core.api.Java6Assertions.assertThat;
+import static org.sonar.server.notification.NotificationDispatcherMetadata.ENABLED_BY_DEFAULT_NOTIFICATION;
import static org.sonar.server.notification.NotificationDispatcherMetadata.GLOBAL_NOTIFICATION;
+import static org.sonar.server.notification.NotificationDispatcherMetadata.PERMISSION_RESTRICTION;
import static org.sonar.server.notification.NotificationDispatcherMetadata.PER_PROJECT_NOTIFICATION;
-public class DispatchersImplTest {
+class DispatchersImplTest {
- private NotificationCenter notificationCenter = new NotificationCenter(
+ private final NotificationCenter notificationCenter = new NotificationCenter(
new NotificationDispatcherMetadata[] {
NotificationDispatcherMetadata.create(MyNewIssuesNotificationHandler.KEY)
.setProperty(GLOBAL_NOTIFICATION, "true")
.setProperty(GLOBAL_NOTIFICATION, "false"),
NotificationDispatcherMetadata.create(QGChangeNotificationHandler.KEY)
.setProperty(GLOBAL_NOTIFICATION, "true")
- .setProperty(PER_PROJECT_NOTIFICATION, "true"),
+ .setProperty(PER_PROJECT_NOTIFICATION, "true")
+ .setProperty(PERMISSION_RESTRICTION, GlobalPermission.ADMINISTER_QUALITY_GATES.getKey()),
NotificationDispatcherMetadata.create(FPOrAcceptedNotificationHandler.KEY)
.setProperty(GLOBAL_NOTIFICATION, "false")
.setProperty(PER_PROJECT_NOTIFICATION, "true")
+ .setProperty(ENABLED_BY_DEFAULT_NOTIFICATION, "true")
},
new NotificationChannel[] {});
- private DispatchersImpl underTest = new DispatchersImpl(notificationCenter);
+ private final DispatchersImpl underTest = new DispatchersImpl(notificationCenter);
@Test
- public void get_sorted_global_dispatchers() {
+ void get_sorted_global_dispatchers() {
underTest.start();
assertThat(underTest.getGlobalDispatchers()).containsExactly(
}
@Test
- public void get_sorted_project_dispatchers() {
+ void get_sorted_project_dispatchers() {
underTest.start();
assertThat(underTest.getProjectDispatchers()).containsExactly(
QGChangeNotificationHandler.KEY, FPOrAcceptedNotificationHandler.KEY, MyNewIssuesNotificationHandler.KEY);
}
+ @Test
+ void get_enabled_by_default_dispatchers() {
+ underTest.start();
+
+ assertThat(underTest.getEnabledByDefaultDispatchers()).containsExactly(
+ FPOrAcceptedNotificationHandler.KEY);
+ }
+
+ @Test
+ void start_shouldProcessPermissionRestrictedDispatchers() {
+ underTest.start();
+
+ assertThat(underTest.getPermissionRestrictedDispatchers())
+ .containsExactlyEntriesOf(Map.of(QGChangeNotificationHandler.KEY, GlobalPermission.ADMINISTER_QUALITY_GATES.getKey()));
+ }
+
}
*/
package org.sonar.server.notification.ws;
+import java.util.Map;
import org.junit.Before;
import org.junit.Test;
import org.sonar.server.notification.NotificationChannel;
underTest = new NotificationCenter(
new NotificationDispatcherMetadata[] {metadata1, metadata2, metadata3},
- new NotificationChannel[] {emailChannel, gtalkChannel}
- );
+ new NotificationChannel[] {emailChannel, gtalkChannel});
}
@Test
assertThat(underTest.getDispatcherKeysForProperty("global", null)).hasSize(1);
}
+ @Test
+ public void getValueByDispatchers_ShouldReturnExpectedMap() {
+ assertThat(underTest.getValueByDispatchers("global"))
+ .containsExactlyInAnyOrderEntriesOf(Map.of("Dispatcher1", "true", "Dispatcher2", "true", "Dispatcher3", "FOO"));
+ }
+
}