@@ -40,6 +40,7 @@ import org.sonar.server.measure.persistence.MeasureDao; | |||
import org.sonar.server.measure.persistence.MetricDao; | |||
import org.sonar.server.qualityprofile.db.ActiveRuleDao; | |||
import org.sonar.server.rule.db.RuleDao; | |||
import org.sonar.server.user.db.GroupDao; | |||
import java.util.Map; | |||
@@ -63,6 +64,7 @@ public class DbClient implements ServerComponent { | |||
private final ActivityDao activityDao; | |||
private final AuthorizationDao authorizationDao; | |||
private final UserDao userDao; | |||
private final GroupDao groupDao; | |||
private final IssueDao issueDao; | |||
private final IssueAuthorizationDao issueAuthorizationDao; | |||
@@ -87,6 +89,7 @@ public class DbClient implements ServerComponent { | |||
activityDao = getDao(map, ActivityDao.class); | |||
authorizationDao = getDao(map, AuthorizationDao.class); | |||
userDao = getDao(map, UserDao.class); | |||
groupDao = getDao(map, GroupDao.class); | |||
issueDao = getDao(map, IssueDao.class); | |||
issueAuthorizationDao = getDao(map, IssueAuthorizationDao.class); | |||
} | |||
@@ -159,6 +162,10 @@ public class DbClient implements ServerComponent { | |||
return userDao; | |||
} | |||
public GroupDao groupDao() { | |||
return groupDao; | |||
} | |||
private <K> K getDao(Map<Class, DaoComponent> map, Class<K> clazz) { | |||
return (K) map.get(clazz); | |||
} |
@@ -63,9 +63,9 @@ public class IssueAuthorizationDao extends BaseDao<IssueAuthorizationMapper, Iss | |||
List<Map<String, String>> rows = session.selectList("org.sonar.core.issue.db.IssueAuthorizationMapper.selectAfterDate", params); | |||
for (Map<String, String> row : rows) { | |||
String project = row.get("PROJECT"); | |||
String user = row.get("USER"); | |||
String group = row.get("PERMISSION_GROUP"); | |||
String project = row.get("project"); | |||
String user = row.get("user"); | |||
String group = row.get("permission_group"); | |||
IssueAuthorizationDto issueAuthorizationDto = authorizationDtoMap.get(project); | |||
if (issueAuthorizationDto == null) { | |||
issueAuthorizationDto = new IssueAuthorizationDto() |
@@ -165,6 +165,7 @@ import org.sonar.server.ui.PageDecorations; | |||
import org.sonar.server.ui.Views; | |||
import org.sonar.server.updatecenter.ws.UpdateCenterWs; | |||
import org.sonar.server.user.*; | |||
import org.sonar.server.user.db.GroupDao; | |||
import org.sonar.server.user.ws.FavoritesWs; | |||
import org.sonar.server.user.ws.UserPropertiesWs; | |||
import org.sonar.server.user.ws.UsersWs; | |||
@@ -227,6 +228,7 @@ class ServerComponents { | |||
DbClient.class, | |||
MeasureFilterDao.class, | |||
ActivityDao.class, | |||
GroupDao.class, | |||
// Elasticsearch | |||
SearchClient.class, |
@@ -25,6 +25,7 @@ import org.sonar.core.persistence.DbSession; | |||
import org.sonar.server.activity.index.ActivityIndex; | |||
import org.sonar.server.db.Dao; | |||
import org.sonar.server.db.DbClient; | |||
import org.sonar.server.issue.index.IssueAuthorizationIndex; | |||
import org.sonar.server.issue.index.IssueIndex; | |||
import org.sonar.server.qualityprofile.index.ActiveRuleIndex; | |||
import org.sonar.server.rule.index.RuleIndex; | |||
@@ -51,8 +52,7 @@ public class IndexSynchronizer { | |||
long start = System.currentTimeMillis(); | |||
synchronize(session, db.ruleDao(), index.get(RuleIndex.class)); | |||
synchronize(session, db.issueDao(), index.get(IssueIndex.class)); | |||
// TODO | |||
//synchronize(session, db.issueAuthorizationDao(), index.get(IssueAuthorizationIndex.class)); | |||
synchronize(session, db.issueAuthorizationDao(), index.get(IssueAuthorizationIndex.class)); | |||
synchronize(session, db.activeRuleDao(), index.get(ActiveRuleIndex.class)); | |||
synchronize(session, db.activityDao(), index.get(ActivityIndex.class)); | |||
session.commit(); |
@@ -0,0 +1,55 @@ | |||
/* | |||
* SonarQube, open source software quality management tool. | |||
* Copyright (C) 2008-2014 SonarSource | |||
* mailto:contact AT sonarsource DOT com | |||
* | |||
* SonarQube 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. | |||
* | |||
* SonarQube 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 this program; if not, write to the Free Software Foundation, | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
package org.sonar.server.user.db; | |||
import com.google.common.annotations.VisibleForTesting; | |||
import org.sonar.api.utils.System2; | |||
import org.sonar.core.persistence.DbSession; | |||
import org.sonar.core.user.GroupDto; | |||
import org.sonar.core.user.GroupMapper; | |||
import org.sonar.server.db.BaseDao; | |||
/** | |||
* @since 3.2 | |||
*/ | |||
public class GroupDao extends BaseDao<GroupMapper, GroupDto, String> { | |||
public GroupDao() { | |||
this(System2.INSTANCE); | |||
} | |||
@VisibleForTesting | |||
public GroupDao(System2 system) { | |||
super(GroupMapper.class, system); | |||
} | |||
@Override | |||
protected GroupDto doGetNullableByKey(DbSession session, String key) { | |||
return mapper(session).selectByKey(key); | |||
} | |||
@Override | |||
protected GroupDto doInsert(DbSession session, GroupDto item) { | |||
mapper(session).insert(item); | |||
return item; | |||
} | |||
} |
@@ -0,0 +1,24 @@ | |||
/* | |||
* SonarQube, open source software quality management tool. | |||
* Copyright (C) 2008-2014 SonarSource | |||
* mailto:contact AT sonarsource DOT com | |||
* | |||
* SonarQube 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. | |||
* | |||
* SonarQube 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 this program; if not, write to the Free Software Foundation, | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
@ParametersAreNonnullByDefault | |||
package org.sonar.server.user.db; | |||
import javax.annotation.ParametersAreNonnullByDefault; |
@@ -0,0 +1,100 @@ | |||
/* | |||
* SonarQube, open source software quality management tool. | |||
* Copyright (C) 2008-2014 SonarSource | |||
* mailto:contact AT sonarsource DOT com | |||
* | |||
* SonarQube 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. | |||
* | |||
* SonarQube 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 this program; if not, write to the Free Software Foundation, | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
package org.sonar.server.issue.index; | |||
import org.junit.After; | |||
import org.junit.Before; | |||
import org.junit.ClassRule; | |||
import org.junit.Test; | |||
import org.sonar.api.web.UserRole; | |||
import org.sonar.core.component.ComponentDto; | |||
import org.sonar.core.permission.PermissionFacade; | |||
import org.sonar.core.persistence.DbSession; | |||
import org.sonar.core.user.GroupDto; | |||
import org.sonar.core.user.UserDto; | |||
import org.sonar.server.db.DbClient; | |||
import org.sonar.server.platform.Platform; | |||
import org.sonar.server.tester.ServerTester; | |||
import java.util.Date; | |||
import static org.fest.assertions.Assertions.assertThat; | |||
public class IssueAuthorizationIndexMediumTest { | |||
@ClassRule | |||
public static ServerTester tester = new ServerTester(); | |||
DbClient db; | |||
DbSession session; | |||
IssueAuthorizationIndex index; | |||
ComponentDto project; | |||
@Before | |||
public void setUp() throws Exception { | |||
tester.clearDbAndIndexes(); | |||
db = tester.get(DbClient.class); | |||
session = db.openSession(false); | |||
index = tester.get(IssueAuthorizationIndex.class); | |||
} | |||
@After | |||
public void after() { | |||
session.close(); | |||
} | |||
@Test | |||
public void synchronize() throws Exception { | |||
project = new ComponentDto() | |||
.setKey("Sample") | |||
.setProjectId(1L); | |||
db.componentDao().insert(session, project); | |||
GroupDto sonarUsers = new GroupDto().setName("devs"); | |||
db.groupDao().insert(session, sonarUsers); | |||
UserDto john = new UserDto().setLogin("john").setName("John").setActive(true); | |||
db.userDao().insert(session, john); | |||
tester.get(PermissionFacade.class).insertGroupPermission(project.getId(), "devs", UserRole.USER, session); | |||
tester.get(PermissionFacade.class).insertUserPermission(project.getId(), john.getId(), UserRole.USER, session); | |||
session.commit(); | |||
session.clearCache(); | |||
tester.clearIndexes(); | |||
assertThat(index.getByKey(project.getKey())).isNull(); | |||
db.issueAuthorizationDao().synchronizeAfter(session, new Date(0)); | |||
IssueAuthorizationDoc issueAuthorizationDoc = index.getByKey(project.getKey()); | |||
assertThat(issueAuthorizationDoc).isNotNull(); | |||
assertThat(issueAuthorizationDoc.project()).isEqualTo("Sample"); | |||
assertThat(issueAuthorizationDoc.permission()).isEqualTo("user"); | |||
assertThat(issueAuthorizationDoc.groups()).containsExactly("devs"); | |||
assertThat(issueAuthorizationDoc.users()).containsExactly("john"); | |||
tester.clearIndexes(); | |||
tester.get(Platform.class).executeStartupTasks(); | |||
assertThat(index.getByKey(project.getKey())).isNotNull(); | |||
} | |||
} |
@@ -0,0 +1,83 @@ | |||
/* | |||
* SonarQube, open source software quality management tool. | |||
* Copyright (C) 2008-2014 SonarSource | |||
* mailto:contact AT sonarsource DOT com | |||
* | |||
* SonarQube 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. | |||
* | |||
* SonarQube 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 this program; if not, write to the Free Software Foundation, | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
package org.sonar.server.user.db; | |||
import org.junit.After; | |||
import org.junit.Before; | |||
import org.junit.Test; | |||
import org.sonar.api.utils.DateUtils; | |||
import org.sonar.api.utils.System2; | |||
import org.sonar.core.persistence.AbstractDaoTestCase; | |||
import org.sonar.core.persistence.DbSession; | |||
import org.sonar.core.user.GroupDto; | |||
import static org.fest.assertions.Assertions.assertThat; | |||
import static org.mockito.Mockito.mock; | |||
import static org.mockito.Mockito.when; | |||
public class GroupDaoTest extends AbstractDaoTestCase { | |||
GroupDao dao; | |||
DbSession session; | |||
System2 system2; | |||
@Before | |||
public void setUp() { | |||
this.session = getMyBatis().openSession(false); | |||
this.system2 = mock(System2.class); | |||
this.dao = new GroupDao(system2); | |||
} | |||
@After | |||
public void tearDown() throws Exception { | |||
session.close(); | |||
} | |||
@Test | |||
public void select_by_key() { | |||
setupData("select_by_key"); | |||
GroupDto group = dao.getByKey(session, "sonar-users"); | |||
assertThat(group).isNotNull(); | |||
assertThat(group.getId()).isEqualTo(1L); | |||
assertThat(group.getName()).isEqualTo("sonar-users"); | |||
assertThat(group.getDescription()).isEqualTo("Sonar Users"); | |||
assertThat(group.getCreatedAt()).isEqualTo(DateUtils.parseDate("2014-09-07")); | |||
assertThat(group.getUpdatedAt()).isEqualTo(DateUtils.parseDate("2014-09-08")); | |||
} | |||
@Test | |||
public void insert() throws Exception { | |||
when(system2.now()).thenReturn(DateUtils.parseDate("2014-09-08").getTime()); | |||
setupData("empty"); | |||
GroupDto dto = new GroupDto() | |||
.setId(1L) | |||
.setName("sonar-users") | |||
.setDescription("Sonar Users"); | |||
dao.insert(session, dto); | |||
session.commit(); | |||
checkTables("insert", "groups"); | |||
} | |||
} |
@@ -0,0 +1,4 @@ | |||
<dataset> | |||
</dataset> |
@@ -0,0 +1,5 @@ | |||
<dataset> | |||
<groups id="1" name="sonar-users" description="Sonar Users" created_at="2014-09-08" updated_at="2014-09-08"/> | |||
</dataset> |
@@ -0,0 +1,5 @@ | |||
<dataset> | |||
<groups id="1" name="sonar-users" description="Sonar Users" created_at="2014-09-07" updated_at="2014-09-08"/> | |||
</dataset> |
@@ -167,7 +167,7 @@ public class MyBatis implements BatchComponent, ServerComponent { | |||
IssueMapper.class, IssueAuthorizationMapper.class, IssueStatsMapper.class, IssueChangeMapper.class, IssueFilterMapper.class, IssueFilterFavouriteMapper.class, | |||
LoadedTemplateMapper.class, MeasureFilterMapper.class, Migration44Mapper.class, PermissionTemplateMapper.class, PropertiesMapper.class, PurgeMapper.class, | |||
ResourceKeyUpdaterMapper.class, ResourceIndexerMapper.class, ResourceSnapshotMapper.class, RoleMapper.class, RuleMapper.class, | |||
SchemaMigrationMapper.class, SemaphoreMapper.class, UserMapper.class, WidgetMapper.class, WidgetPropertyMapper.class, | |||
SchemaMigrationMapper.class, SemaphoreMapper.class, UserMapper.class, GroupMapper.class, WidgetMapper.class, WidgetPropertyMapper.class, | |||
org.sonar.api.database.model.MeasureMapper.class, SnapshotDataMapper.class, SnapshotSourceMapper.class, ActionPlanMapper.class, ActionPlanStatsMapper.class, | |||
NotificationQueueMapper.class, CharacteristicMapper.class, | |||
GroupMembershipMapper.class, QualityProfileMapper.class, ActiveRuleMapper.class, |
@@ -19,18 +19,16 @@ | |||
*/ | |||
package org.sonar.core.user; | |||
import org.sonar.core.persistence.Dto; | |||
import javax.annotation.CheckForNull; | |||
import javax.annotation.Nullable; | |||
import java.util.Date; | |||
/** | |||
* @since 3.2 | |||
*/ | |||
public class GroupDto { | |||
public class GroupDto extends Dto<String> { | |||
private Long id; | |||
private String name; | |||
private String description; | |||
private Date createdAt; | |||
private Date updatedAt; | |||
public Long getId() { | |||
return id; | |||
@@ -50,6 +48,7 @@ public class GroupDto { | |||
return this; | |||
} | |||
@CheckForNull | |||
public String getDescription() { | |||
return description; | |||
} | |||
@@ -59,21 +58,9 @@ public class GroupDto { | |||
return this; | |||
} | |||
public Date getCreatedAt() { | |||
return createdAt; | |||
} | |||
public GroupDto setCreatedAt(Date createdAt) { | |||
this.createdAt = createdAt; | |||
return this; | |||
} | |||
public Date getUpdatedAt() { | |||
return updatedAt; | |||
@Override | |||
public String getKey() { | |||
return name; | |||
} | |||
public GroupDto setUpdatedAt(Date updatedAt) { | |||
this.updatedAt = updatedAt; | |||
return this; | |||
} | |||
} |
@@ -0,0 +1,32 @@ | |||
/* | |||
* SonarQube, open source software quality management tool. | |||
* Copyright (C) 2008-2014 SonarSource | |||
* mailto:contact AT sonarsource DOT com | |||
* | |||
* SonarQube 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. | |||
* | |||
* SonarQube 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 this program; if not, write to the Free Software Foundation, | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
package org.sonar.core.user; | |||
import javax.annotation.CheckForNull; | |||
public interface GroupMapper { | |||
@CheckForNull | |||
GroupDto selectByKey(String name); | |||
void insert(GroupDto groupDto); | |||
} |
@@ -6,10 +6,10 @@ | |||
<select id="selectAfterDate" parameterType="map" resultType="map"> | |||
SELECT | |||
project_authorization.project as project, | |||
project_authorization.login as user, | |||
project_authorization.permission_group as permission_group, | |||
project_authorization.permission_role as permission_role | |||
project_authorization.project as "project", | |||
project_authorization.login as "user", | |||
project_authorization.permission_group as "permission_group", | |||
project_authorization.permission_role as "permission_role" | |||
FROM ( | |||
-- users | |||
SELECT |
@@ -0,0 +1,25 @@ | |||
<?xml version="1.0" encoding="UTF-8" ?> | |||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> | |||
<mapper namespace="org.sonar.core.user.GroupMapper"> | |||
<sql id="groupColumns"> | |||
g.id as id, | |||
g.name as name, | |||
g.description as description, | |||
g.created_at as "createdAt", | |||
g.updated_at as "updatedAt" | |||
</sql> | |||
<select id="selectByKey" parameterType="string" resultType="Group"> | |||
SELECT <include refid="groupColumns"/> | |||
FROM groups g WHERE g.name=#{id} | |||
</select> | |||
<insert id="insert" parameterType="Group" keyColumn="id" useGeneratedKeys="true" keyProperty="id"> | |||
INSERT INTO groups (name, description, created_at, updated_at) | |||
VALUES (#{name}, #{description}, #{createdAt}, #{updatedAt}) | |||
</insert> | |||
</mapper> |