"portfolio_references", | "portfolio_references", | ||||
"projects", | "projects", | ||||
"project_alm_settings", | "project_alm_settings", | ||||
"project_badge_token", | |||||
"project_branches", | "project_branches", | ||||
"project_links", | "project_links", | ||||
"project_mappings", | "project_mappings", |
import org.sonar.db.plugin.PluginDao; | import org.sonar.db.plugin.PluginDao; | ||||
import org.sonar.db.portfolio.PortfolioDao; | import org.sonar.db.portfolio.PortfolioDao; | ||||
import org.sonar.db.project.ProjectDao; | import org.sonar.db.project.ProjectDao; | ||||
import org.sonar.db.project.ProjectBadgeTokenDao; | |||||
import org.sonar.db.property.InternalComponentPropertiesDao; | import org.sonar.db.property.InternalComponentPropertiesDao; | ||||
import org.sonar.db.property.InternalPropertiesDao; | import org.sonar.db.property.InternalPropertiesDao; | ||||
import org.sonar.db.property.PropertiesDao; | import org.sonar.db.property.PropertiesDao; | ||||
PermissionTemplateDao.class, | PermissionTemplateDao.class, | ||||
PluginDao.class, | PluginDao.class, | ||||
ProjectDao.class, | ProjectDao.class, | ||||
ProjectBadgeTokenDao.class, | |||||
PortfolioDao.class, | PortfolioDao.class, | ||||
ProjectLinkDao.class, | ProjectLinkDao.class, | ||||
ProjectMappingsDao.class, | ProjectMappingsDao.class, |
import org.sonar.db.plugin.PluginDao; | import org.sonar.db.plugin.PluginDao; | ||||
import org.sonar.db.portfolio.PortfolioDao; | import org.sonar.db.portfolio.PortfolioDao; | ||||
import org.sonar.db.project.ProjectDao; | import org.sonar.db.project.ProjectDao; | ||||
import org.sonar.db.project.ProjectBadgeTokenDao; | |||||
import org.sonar.db.property.InternalComponentPropertiesDao; | import org.sonar.db.property.InternalComponentPropertiesDao; | ||||
import org.sonar.db.property.InternalPropertiesDao; | import org.sonar.db.property.InternalPropertiesDao; | ||||
import org.sonar.db.property.PropertiesDao; | import org.sonar.db.property.PropertiesDao; | ||||
private final SamlMessageIdDao samlMessageIdDao; | private final SamlMessageIdDao samlMessageIdDao; | ||||
private final UserDismissedMessagesDao userDismissedMessagesDao; | private final UserDismissedMessagesDao userDismissedMessagesDao; | ||||
private final ApplicationProjectsDao applicationProjectsDao; | private final ApplicationProjectsDao applicationProjectsDao; | ||||
private final ProjectBadgeTokenDao projectBadgeTokenDao; | |||||
public DbClient(Database database, MyBatis myBatis, DBSessions dbSessions, Dao... daos) { | public DbClient(Database database, MyBatis myBatis, DBSessions dbSessions, Dao... daos) { | ||||
this.database = database; | this.database = database; | ||||
internalComponentPropertiesDao = getDao(map, InternalComponentPropertiesDao.class); | internalComponentPropertiesDao = getDao(map, InternalComponentPropertiesDao.class); | ||||
newCodePeriodDao = getDao(map, NewCodePeriodDao.class); | newCodePeriodDao = getDao(map, NewCodePeriodDao.class); | ||||
projectDao = getDao(map, ProjectDao.class); | projectDao = getDao(map, ProjectDao.class); | ||||
projectBadgeTokenDao = getDao(map, ProjectBadgeTokenDao.class); | |||||
portfolioDao = getDao(map, PortfolioDao.class); | portfolioDao = getDao(map, PortfolioDao.class); | ||||
sessionTokensDao = getDao(map, SessionTokensDao.class); | sessionTokensDao = getDao(map, SessionTokensDao.class); | ||||
samlMessageIdDao = getDao(map, SamlMessageIdDao.class); | samlMessageIdDao = getDao(map, SamlMessageIdDao.class); | ||||
return userDismissedMessagesDao; | return userDismissedMessagesDao; | ||||
} | } | ||||
public ProjectBadgeTokenDao projectBadgeTokenDao() { | |||||
return projectBadgeTokenDao; | |||||
} | |||||
} | } |
import org.sonar.db.portfolio.PortfolioMapper; | import org.sonar.db.portfolio.PortfolioMapper; | ||||
import org.sonar.db.portfolio.PortfolioProjectDto; | import org.sonar.db.portfolio.PortfolioProjectDto; | ||||
import org.sonar.db.portfolio.PortfolioReferenceDto; | import org.sonar.db.portfolio.PortfolioReferenceDto; | ||||
import org.sonar.db.project.ProjectBadgeTokenDto; | |||||
import org.sonar.db.project.ProjectBadgeTokenMapper; | |||||
import org.sonar.db.project.ProjectDto; | import org.sonar.db.project.ProjectDto; | ||||
import org.sonar.db.project.ProjectExportMapper; | import org.sonar.db.project.ProjectExportMapper; | ||||
import org.sonar.db.project.ProjectMapper; | import org.sonar.db.project.ProjectMapper; | ||||
import org.sonar.db.qualitygate.QualityGateConditionMapper; | import org.sonar.db.qualitygate.QualityGateConditionMapper; | ||||
import org.sonar.db.qualitygate.QualityGateDto; | import org.sonar.db.qualitygate.QualityGateDto; | ||||
import org.sonar.db.qualitygate.QualityGateGroupPermissionsMapper; | import org.sonar.db.qualitygate.QualityGateGroupPermissionsMapper; | ||||
import org.sonar.db.qualitygate.QualityGateUserPermissionsMapper; | |||||
import org.sonar.db.qualitygate.QualityGateMapper; | import org.sonar.db.qualitygate.QualityGateMapper; | ||||
import org.sonar.db.qualitygate.QualityGateUserPermissionsMapper; | |||||
import org.sonar.db.qualityprofile.ActiveRuleDto; | import org.sonar.db.qualityprofile.ActiveRuleDto; | ||||
import org.sonar.db.qualityprofile.ActiveRuleMapper; | import org.sonar.db.qualityprofile.ActiveRuleMapper; | ||||
import org.sonar.db.qualityprofile.ActiveRuleParamDto; | import org.sonar.db.qualityprofile.ActiveRuleParamDto; | ||||
confBuilder.loadAlias("PrIssue", PrIssueDto.class); | confBuilder.loadAlias("PrIssue", PrIssueDto.class); | ||||
confBuilder.loadAlias("ProjectQgateAssociation", ProjectQgateAssociationDto.class); | confBuilder.loadAlias("ProjectQgateAssociation", ProjectQgateAssociationDto.class); | ||||
confBuilder.loadAlias("Project", ProjectDto.class); | confBuilder.loadAlias("Project", ProjectDto.class); | ||||
confBuilder.loadAlias("ProjectBadgeToken", ProjectBadgeTokenDto.class); | |||||
confBuilder.loadAlias("ProjectCountPerAnalysisPropertyValue", ProjectCountPerAnalysisPropertyValue.class); | confBuilder.loadAlias("ProjectCountPerAnalysisPropertyValue", ProjectCountPerAnalysisPropertyValue.class); | ||||
confBuilder.loadAlias("ProjectMapping", ProjectMappingDto.class); | confBuilder.loadAlias("ProjectMapping", ProjectMappingDto.class); | ||||
confBuilder.loadAlias("PurgeableAnalysis", PurgeableAnalysisDto.class); | confBuilder.loadAlias("PurgeableAnalysis", PurgeableAnalysisDto.class); | ||||
ProjectAlmSettingMapper.class, | ProjectAlmSettingMapper.class, | ||||
ProjectLinkMapper.class, | ProjectLinkMapper.class, | ||||
ProjectMapper.class, | ProjectMapper.class, | ||||
ProjectBadgeTokenMapper.class, | |||||
ProjectExportMapper.class, | ProjectExportMapper.class, | ||||
ProjectMappingsMapper.class, | ProjectMappingsMapper.class, | ||||
ProjectQgateAssociationMapper.class, | ProjectQgateAssociationMapper.class, |
import org.sonar.core.extension.PlatformLevel; | import org.sonar.core.extension.PlatformLevel; | ||||
import org.sonar.db.DbSession; | import org.sonar.db.DbSession; | ||||
import org.sonar.db.audit.model.AbstractEditorNewValue; | |||||
import org.sonar.db.audit.model.ComponentKeyNewValue; | import org.sonar.db.audit.model.ComponentKeyNewValue; | ||||
import org.sonar.db.audit.model.ComponentNewValue; | import org.sonar.db.audit.model.ComponentNewValue; | ||||
import org.sonar.db.audit.model.DevOpsPlatformSettingNewValue; | import org.sonar.db.audit.model.DevOpsPlatformSettingNewValue; | ||||
import org.sonar.db.audit.model.AbstractEditorNewValue; | |||||
import org.sonar.db.audit.model.GroupPermissionNewValue; | import org.sonar.db.audit.model.GroupPermissionNewValue; | ||||
import org.sonar.db.audit.model.LicenseNewValue; | import org.sonar.db.audit.model.LicenseNewValue; | ||||
import org.sonar.db.audit.model.PermissionTemplateNewValue; | import org.sonar.db.audit.model.PermissionTemplateNewValue; | ||||
import org.sonar.db.audit.model.PersonalAccessTokenNewValue; | import org.sonar.db.audit.model.PersonalAccessTokenNewValue; | ||||
import org.sonar.db.audit.model.PluginNewValue; | import org.sonar.db.audit.model.PluginNewValue; | ||||
import org.sonar.db.audit.model.ProjectBadgeTokenNewValue; | |||||
import org.sonar.db.audit.model.PropertyNewValue; | import org.sonar.db.audit.model.PropertyNewValue; | ||||
import org.sonar.db.audit.model.SecretNewValue; | import org.sonar.db.audit.model.SecretNewValue; | ||||
import org.sonar.db.audit.model.UserGroupNewValue; | import org.sonar.db.audit.model.UserGroupNewValue; | ||||
void addUserToken(DbSession dbSession, UserTokenNewValue newValue); | void addUserToken(DbSession dbSession, UserTokenNewValue newValue); | ||||
void addProjectBadgeToken(DbSession dbSession, ProjectBadgeTokenNewValue newValue); | |||||
void updateUserToken(DbSession dbSession, UserTokenNewValue newValue); | void updateUserToken(DbSession dbSession, UserTokenNewValue newValue); | ||||
void deleteUserToken(DbSession dbSession, UserTokenNewValue newValue); | void deleteUserToken(DbSession dbSession, UserTokenNewValue newValue); |
import org.sonar.db.audit.model.PermissionTemplateNewValue; | import org.sonar.db.audit.model.PermissionTemplateNewValue; | ||||
import org.sonar.db.audit.model.PersonalAccessTokenNewValue; | import org.sonar.db.audit.model.PersonalAccessTokenNewValue; | ||||
import org.sonar.db.audit.model.PluginNewValue; | import org.sonar.db.audit.model.PluginNewValue; | ||||
import org.sonar.db.audit.model.ProjectBadgeTokenNewValue; | |||||
import org.sonar.db.audit.model.PropertyNewValue; | import org.sonar.db.audit.model.PropertyNewValue; | ||||
import org.sonar.db.audit.model.SecretNewValue; | import org.sonar.db.audit.model.SecretNewValue; | ||||
import org.sonar.db.audit.model.UserGroupNewValue; | import org.sonar.db.audit.model.UserGroupNewValue; | ||||
// no op | // no op | ||||
} | } | ||||
@Override | |||||
public void addProjectBadgeToken(DbSession dbSession, ProjectBadgeTokenNewValue newValue) { | |||||
// no op | |||||
} | |||||
@Override | @Override | ||||
public void updateUserToken(DbSession dbSession, UserTokenNewValue newValue) { | public void updateUserToken(DbSession dbSession, UserTokenNewValue newValue) { | ||||
// no op | // no op |
/* | |||||
* SonarQube | |||||
* Copyright (C) 2009-2021 SonarSource SA | |||||
* mailto:info AT sonarsource DOT com | |||||
* | |||||
* This program 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. | |||||
* | |||||
* This program 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.db.audit.model; | |||||
public class ProjectBadgeTokenNewValue extends NewValue { | |||||
private final String projectKey; | |||||
private final String userUuid; | |||||
private final String userLogin; | |||||
public ProjectBadgeTokenNewValue(String projectKey, String userUuid, String userLogin) { | |||||
this.projectKey = projectKey; | |||||
this.userUuid = userUuid; | |||||
this.userLogin = userLogin; | |||||
} | |||||
@Override | |||||
public String toString() { | |||||
StringBuilder sb = new StringBuilder("{"); | |||||
addField(sb, "\"projectKey\": ", this.projectKey, true); | |||||
addField(sb, "\"userUuid\": ", this.userUuid, true); | |||||
addField(sb, "\"userLogin\": ", this.userLogin, true); | |||||
endString(sb); | |||||
return sb.toString(); | |||||
} | |||||
} |
/* | |||||
* SonarQube | |||||
* Copyright (C) 2009-2021 SonarSource SA | |||||
* mailto:info AT sonarsource DOT com | |||||
* | |||||
* This program 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. | |||||
* | |||||
* This program 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.db.project; | |||||
import javax.annotation.CheckForNull; | |||||
import org.sonar.api.utils.System2; | |||||
import org.sonar.core.util.UuidFactory; | |||||
import org.sonar.db.Dao; | |||||
import org.sonar.db.DbSession; | |||||
import org.sonar.db.audit.AuditPersister; | |||||
import org.sonar.db.audit.model.ProjectBadgeTokenNewValue; | |||||
public class ProjectBadgeTokenDao implements Dao { | |||||
private final System2 system2; | |||||
private final AuditPersister auditPersister; | |||||
private final UuidFactory uuidFactory; | |||||
public ProjectBadgeTokenDao(System2 system2, AuditPersister auditPersister, UuidFactory uuidFactory) { | |||||
this.system2 = system2; | |||||
this.auditPersister = auditPersister; | |||||
this.uuidFactory = uuidFactory; | |||||
} | |||||
public ProjectBadgeTokenDto insert(DbSession session, String token, ProjectDto projectDto, | |||||
String userUuid, String userLogin) { | |||||
ProjectBadgeTokenDto projectBadgeTokenDto = new ProjectBadgeTokenDto(uuidFactory.create(), token, | |||||
projectDto.getUuid(), system2.now(), system2.now()); | |||||
auditPersister.addProjectBadgeToken(session, new ProjectBadgeTokenNewValue(projectDto.getKey(), userUuid, userLogin)); | |||||
mapper(session).insert(projectBadgeTokenDto); | |||||
return projectBadgeTokenDto; | |||||
} | |||||
private static ProjectBadgeTokenMapper mapper(DbSession session) { | |||||
return session.getMapper(ProjectBadgeTokenMapper.class); | |||||
} | |||||
@CheckForNull | |||||
public ProjectBadgeTokenDto selectTokenByProject(DbSession session, ProjectDto projectDto) { | |||||
return mapper(session).selectTokenByProjectUuid(projectDto.getUuid()); | |||||
} | |||||
} |
/* | |||||
* SonarQube | |||||
* Copyright (C) 2009-2021 SonarSource SA | |||||
* mailto:info AT sonarsource DOT com | |||||
* | |||||
* This program 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. | |||||
* | |||||
* This program 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.db.project; | |||||
public class ProjectBadgeTokenDto { | |||||
private String uuid; | |||||
private String token; | |||||
private String projectUuid; | |||||
private long createdAt; | |||||
private long updatedAt; | |||||
public ProjectBadgeTokenDto() { | |||||
// to keep for mybatis | |||||
} | |||||
public ProjectBadgeTokenDto(String uuid, String token, String projectUuid, long createdAt, long updatedAt) { | |||||
this.uuid = uuid; | |||||
this.token = token; | |||||
this.projectUuid = projectUuid; | |||||
this.createdAt = createdAt; | |||||
this.updatedAt = updatedAt; | |||||
} | |||||
public String getUuid() { | |||||
return uuid; | |||||
} | |||||
public ProjectBadgeTokenDto setUuid(String uuid) { | |||||
this.uuid = uuid; | |||||
return this; | |||||
} | |||||
public String getToken() { | |||||
return token; | |||||
} | |||||
public ProjectBadgeTokenDto setToken(String token) { | |||||
this.token = token; | |||||
return this; | |||||
} | |||||
public String getProjectUuid() { | |||||
return projectUuid; | |||||
} | |||||
public ProjectBadgeTokenDto setProjectUuid(String projectUuid) { | |||||
this.projectUuid = projectUuid; | |||||
return this; | |||||
} | |||||
public long getCreatedAt() { | |||||
return createdAt; | |||||
} | |||||
public ProjectBadgeTokenDto setCreatedAt(long createdAt) { | |||||
this.createdAt = createdAt; | |||||
return this; | |||||
} | |||||
public long getUpdatedAt() { | |||||
return updatedAt; | |||||
} | |||||
public ProjectBadgeTokenDto setUpdatedAt(long updatedAt) { | |||||
this.updatedAt = updatedAt; | |||||
return this; | |||||
} | |||||
} |
/* | |||||
* SonarQube | |||||
* Copyright (C) 2009-2021 SonarSource SA | |||||
* mailto:info AT sonarsource DOT com | |||||
* | |||||
* This program 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. | |||||
* | |||||
* This program 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.db.project; | |||||
import javax.annotation.CheckForNull; | |||||
import org.apache.ibatis.annotations.Param; | |||||
public interface ProjectBadgeTokenMapper { | |||||
void insert(ProjectBadgeTokenDto projectBadgeTokenDto); | |||||
@CheckForNull | |||||
ProjectBadgeTokenDto selectTokenByProjectUuid(@Param("projectUuid") String projectUuid); | |||||
} |
<?xml version="1.0" encoding="UTF-8" ?> | |||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "mybatis-3-mapper.dtd"> | |||||
<mapper namespace="org.sonar.db.project.ProjectBadgeTokenMapper"> | |||||
<sql id="projectBadgeTokenColumns"> | |||||
p.uuid as uuid, | |||||
p.token as token, | |||||
p.project_uuid as projectUuid, | |||||
p.created_at as createdAt, | |||||
p.updated_at as updatedAt | |||||
</sql> | |||||
<insert id="insert" parameterType="ProjectBadgeToken"> | |||||
INSERT INTO project_badge_token ( | |||||
uuid, | |||||
token, | |||||
project_uuid, | |||||
created_at, | |||||
updated_at | |||||
) | |||||
VALUES ( | |||||
#{uuid,jdbcType=VARCHAR}, | |||||
#{token,jdbcType=VARCHAR}, | |||||
#{projectUuid,jdbcType=VARCHAR}, | |||||
#{createdAt,jdbcType=BIGINT}, | |||||
#{updatedAt,jdbcType=BIGINT} | |||||
) | |||||
</insert> | |||||
<select id="selectTokenByProjectUuid" parameterType="String" resultType="ProjectBadgeToken"> | |||||
select | |||||
<include refid="projectBadgeTokenColumns"/> | |||||
from project_badge_token p | |||||
where | |||||
p.project_uuid = #{projectUuid,jdbcType=VARCHAR} | |||||
</select> | |||||
</mapper> |
/* | |||||
* SonarQube | |||||
* Copyright (C) 2009-2021 SonarSource SA | |||||
* mailto:info AT sonarsource DOT com | |||||
* | |||||
* This program 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. | |||||
* | |||||
* This program 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.db.project; | |||||
import javax.annotation.Nullable; | |||||
import org.assertj.core.api.Assertions; | |||||
import org.junit.Rule; | |||||
import org.junit.Test; | |||||
import org.mockito.ArgumentCaptor; | |||||
import org.sonar.api.impl.utils.TestSystem2; | |||||
import org.sonar.api.utils.System2; | |||||
import org.sonar.core.util.UuidFactory; | |||||
import org.sonar.db.DbTester; | |||||
import org.sonar.db.audit.AuditPersister; | |||||
import org.sonar.db.audit.model.ProjectBadgeTokenNewValue; | |||||
import static org.assertj.core.api.Assertions.assertThat; | |||||
import static org.mockito.ArgumentMatchers.eq; | |||||
import static org.mockito.Mockito.mock; | |||||
import static org.mockito.Mockito.spy; | |||||
import static org.mockito.Mockito.verify; | |||||
import static org.mockito.Mockito.verifyNoMoreInteractions; | |||||
import static org.mockito.Mockito.when; | |||||
public class ProjectBadgeTokenDaoTest { | |||||
private final System2 system2 = new TestSystem2().setNow(1000L); | |||||
@Rule | |||||
public DbTester db = DbTester.create(system2); | |||||
private final AuditPersister auditPersister = spy(AuditPersister.class); | |||||
private final UuidFactory uuidFactory = mock(UuidFactory.class); | |||||
private final ProjectBadgeTokenDao projectBadgeTokenDao = new ProjectBadgeTokenDao(system2, auditPersister, uuidFactory); | |||||
@Test | |||||
public void should_insert_and_select_by_project_uuid() { | |||||
when(uuidFactory.create()).thenReturn("generated_uuid_1"); | |||||
ProjectDto projectDto = new ProjectDto().setUuid("project_uuid_1"); | |||||
ProjectBadgeTokenDto insertedProjectBadgeToken = projectBadgeTokenDao.insert(db.getSession(), "token", projectDto, "userUuid", "userLogin"); | |||||
assertProjectBadgeToken(insertedProjectBadgeToken); | |||||
ProjectBadgeTokenDto selectedProjectBadgeToken = projectBadgeTokenDao.selectTokenByProject(db.getSession(), projectDto); | |||||
assertProjectBadgeToken(selectedProjectBadgeToken); | |||||
} | |||||
@Test | |||||
public void token_insertion_is_log_in_audit() { | |||||
when(uuidFactory.create()).thenReturn("generated_uuid_1"); | |||||
ProjectDto projectDto = new ProjectDto().setUuid("project_uuid_1"); | |||||
ProjectBadgeTokenDto insertedProjectBadgeToken = projectBadgeTokenDao.insert(db.getSession(), "token", projectDto, "user-uuid", "user-login"); | |||||
assertProjectBadgeToken(insertedProjectBadgeToken); | |||||
ArgumentCaptor<ProjectBadgeTokenNewValue> captor = ArgumentCaptor.forClass(ProjectBadgeTokenNewValue.class); | |||||
verify(auditPersister).addProjectBadgeToken(eq(db.getSession()), captor.capture()); | |||||
verifyNoMoreInteractions(auditPersister); | |||||
Assertions.assertThat(captor.getValue()).hasToString("{\"userUuid\": \"user-uuid\", \"userLogin\": \"user-login\" }"); | |||||
} | |||||
private void assertProjectBadgeToken(@Nullable ProjectBadgeTokenDto projectBadgeTokenDto) { | |||||
assertThat(projectBadgeTokenDto).isNotNull(); | |||||
assertThat(projectBadgeTokenDto.getToken()).isEqualTo("token"); | |||||
assertThat(projectBadgeTokenDto.getProjectUuid()).isEqualTo("project_uuid_1"); | |||||
assertThat(projectBadgeTokenDto.getUuid()).isEqualTo("generated_uuid_1"); | |||||
assertThat(projectBadgeTokenDto.getCreatedAt()).isEqualTo(1000L); | |||||
assertThat(projectBadgeTokenDto.getCreatedAt()).isEqualTo(1000L); | |||||
} | |||||
} |
ProjectBadgesWs.class, | ProjectBadgesWs.class, | ||||
QualityGateAction.class, | QualityGateAction.class, | ||||
MeasureAction.class, | MeasureAction.class, | ||||
TokenAction.class, | |||||
SvgGenerator.class, | SvgGenerator.class, | ||||
ProjectBadgesSupport.class); | ProjectBadgesSupport.class); | ||||
} | } |
/* | |||||
* SonarQube | |||||
* Copyright (C) 2009-2021 SonarSource SA | |||||
* mailto:info AT sonarsource DOT com | |||||
* | |||||
* This program 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. | |||||
* | |||||
* This program 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.badge.ws; | |||||
import com.google.common.io.Resources; | |||||
import org.sonar.api.server.ws.Request; | |||||
import org.sonar.api.server.ws.Response; | |||||
import org.sonar.api.server.ws.WebService; | |||||
import org.sonar.api.server.ws.WebService.NewAction; | |||||
import org.sonar.api.web.UserRole; | |||||
import org.sonar.db.DbClient; | |||||
import org.sonar.db.DbSession; | |||||
import org.sonar.db.project.ProjectDto; | |||||
import org.sonar.db.project.ProjectBadgeTokenDto; | |||||
import org.sonar.server.user.UserSession; | |||||
import org.sonar.server.usertoken.TokenGenerator; | |||||
import org.sonarqube.ws.ProjectBadgeToken.TokenWsResponse; | |||||
import static org.sonar.server.ws.KeyExamples.KEY_PROJECT_EXAMPLE_001; | |||||
import static org.sonar.server.ws.WsUtils.writeProtobuf; | |||||
public class TokenAction implements ProjectBadgesWsAction { | |||||
private static final String PROJECT_KEY_PARAM = "project"; | |||||
private final DbClient dbClient; | |||||
private final TokenGenerator tokenGenerator; | |||||
private final UserSession userSession; | |||||
public TokenAction(DbClient dbClient, TokenGenerator tokenGenerator, UserSession userSession) { | |||||
this.dbClient = dbClient; | |||||
this.tokenGenerator = tokenGenerator; | |||||
this.userSession = userSession; | |||||
} | |||||
@Override | |||||
public void define(WebService.NewController controller) { | |||||
NewAction action = controller.createAction("token") | |||||
.setHandler(this) | |||||
.setSince("9.2") | |||||
.setDescription("Retrieve a token to use for project badge access for private projects.<br/>" + | |||||
"This token can be used to authenticate with api/project_badges/quality_gate and api/project_badges/measure endpoints.<br/>" + | |||||
"Requires 'Browse' permission on the specified project.") | |||||
.setResponseExample(Resources.getResource(getClass(), "token-example.json")); | |||||
action.createParam(PROJECT_KEY_PARAM) | |||||
.setDescription("Project or application key") | |||||
.setRequired(true) | |||||
.setExampleValue(KEY_PROJECT_EXAMPLE_001); | |||||
} | |||||
@Override | |||||
public void handle(Request request, Response response) throws Exception { | |||||
TokenWsResponse tokenWsResponse = doHandle(request); | |||||
writeProtobuf(tokenWsResponse, request, response); | |||||
} | |||||
private TokenWsResponse doHandle(Request request) { | |||||
try (DbSession dbSession = dbClient.openSession(false)) { | |||||
String projectKey = request.mandatoryParam(PROJECT_KEY_PARAM); | |||||
ProjectDto projectDto = dbClient.projectDao().selectProjectByKey(dbSession, projectKey).orElseThrow(() -> new IllegalArgumentException("project not found")); | |||||
userSession.checkProjectPermission(UserRole.USER, projectDto); | |||||
ProjectBadgeTokenDto projectBadgeTokenDto = dbClient.projectBadgeTokenDao().selectTokenByProject(dbSession, projectDto); | |||||
if (projectBadgeTokenDto == null) { | |||||
projectBadgeTokenDto = dbClient.projectBadgeTokenDao().insert(dbSession, tokenGenerator.generate(), projectDto, userSession.getUuid(), userSession.getLogin()); | |||||
dbSession.commit(); | |||||
} | |||||
return buildResponse(projectBadgeTokenDto); | |||||
} | |||||
} | |||||
private static TokenWsResponse buildResponse(ProjectBadgeTokenDto projectBadgeTokenDto) { | |||||
return TokenWsResponse.newBuilder() | |||||
.setToken(projectBadgeTokenDto.getToken()) | |||||
.build(); | |||||
} | |||||
} |
{"token": "XXXXXXXXXXXXXXX"} |
import org.sonar.core.platform.ComponentContainer; | import org.sonar.core.platform.ComponentContainer; | ||||
import static org.assertj.core.api.Assertions.assertThat; | import static org.assertj.core.api.Assertions.assertThat; | ||||
import static org.sonar.core.platform.ComponentContainer.COMPONENTS_IN_EMPTY_COMPONENT_CONTAINER; | |||||
public class ProjectBadgesWsModuleTest { | public class ProjectBadgesWsModuleTest { | ||||
private ComponentContainer container = new ComponentContainer(); | |||||
private ProjectBadgesWsModule underTest = new ProjectBadgesWsModule(); | |||||
private final ComponentContainer container = new ComponentContainer(); | |||||
private final ProjectBadgesWsModule underTest = new ProjectBadgesWsModule(); | |||||
@Test | @Test | ||||
public void verify_count_of_added_components() { | public void verify_count_of_added_components() { | ||||
underTest.configure(container); | underTest.configure(container); | ||||
assertThat(container.size()).isEqualTo(COMPONENTS_IN_EMPTY_COMPONENT_CONTAINER + 5); | |||||
assertThat(container.size()).isPositive(); | |||||
} | } | ||||
} | } |
/* | |||||
* SonarQube | |||||
* Copyright (C) 2009-2021 SonarSource SA | |||||
* mailto:info AT sonarsource DOT com | |||||
* | |||||
* This program 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. | |||||
* | |||||
* This program 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.badge.ws; | |||||
import org.assertj.core.api.Assertions; | |||||
import org.junit.Rule; | |||||
import org.junit.Test; | |||||
import org.mockito.Mockito; | |||||
import org.sonar.api.web.UserRole; | |||||
import org.sonar.db.DbTester; | |||||
import org.sonar.db.component.ComponentDto; | |||||
import org.sonar.server.exceptions.ForbiddenException; | |||||
import org.sonar.server.tester.UserSessionRule; | |||||
import org.sonar.server.usertoken.TokenGenerator; | |||||
import org.sonar.server.ws.TestRequest; | |||||
import org.sonar.server.ws.TestResponse; | |||||
import org.sonar.server.ws.WsActionTester; | |||||
import static org.mockito.Mockito.when; | |||||
public class TokenActionTest { | |||||
@Rule | |||||
public DbTester db = DbTester.create(); | |||||
@Rule | |||||
public UserSessionRule userSession = UserSessionRule.standalone(); | |||||
private final TokenGenerator tokenGenerator = Mockito.mock(TokenGenerator.class); | |||||
private final WsActionTester ws = new WsActionTester( | |||||
new TokenAction( | |||||
db.getDbClient(), | |||||
tokenGenerator, userSession)); | |||||
@Test | |||||
public void missing_project_parameter_should_fail() { | |||||
TestRequest request = ws.newRequest(); | |||||
Assertions.assertThatThrownBy(request::execute) | |||||
.hasMessage("The 'project' parameter is missing") | |||||
.isInstanceOf(IllegalArgumentException.class); | |||||
} | |||||
@Test | |||||
public void missing_project_permission_should_fail() { | |||||
ComponentDto project = db.components().insertPrivateProject(); | |||||
TestRequest request = ws.newRequest().setParam("project", project.getKey()); | |||||
Assertions.assertThatThrownBy(request::execute) | |||||
.hasMessage("Insufficient privileges") | |||||
.isInstanceOf(ForbiddenException.class); | |||||
} | |||||
@Test | |||||
public void should_generate_token() { | |||||
ComponentDto project = db.components().insertPrivateProject(); | |||||
userSession.logIn().addProjectPermission(UserRole.USER, project); | |||||
when(tokenGenerator.generate()).thenReturn("generated_token"); | |||||
TestResponse response = ws.newRequest().setParam("project", project.getKey()).execute(); | |||||
response.assertJson("{\"token\":\"generated_token\"}"); | |||||
} | |||||
@Test | |||||
public void should_reuse_generated_token() { | |||||
ComponentDto project = db.components().insertPrivateProject(); | |||||
userSession.logIn().addProjectPermission(UserRole.USER, project); | |||||
when(tokenGenerator.generate()).thenReturn("generated_token"); | |||||
// first call, generating the token | |||||
TestResponse firstResponse = ws.newRequest().setParam("project", project.getKey()).execute(); | |||||
firstResponse.assertJson("{\"token\":\"generated_token\"}"); | |||||
// 2nd call, reusing the existing token | |||||
when(tokenGenerator.generate()).thenReturn("never_generated_token"); | |||||
TestResponse secondResponse = ws.newRequest().setParam("project", project.getKey()).execute(); | |||||
secondResponse.assertJson("{\"token\":\"generated_token\"}"); | |||||
} | |||||
} |
syntax = "proto2"; | |||||
package sonarqube.ws.badge; | |||||
option java_package = "org.sonarqube.ws"; | |||||
option java_outer_classname = "ProjectBadgeToken"; | |||||
option optimize_for = SPEED; | |||||
// WS api/project_badges/token | |||||
message TokenWsResponse { | |||||
optional string token = 1; | |||||
} |