Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: Snyk security issues (minor), updated ktLint #2055

Merged
merged 1 commit into from
Dec 30, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
6 changes: 5 additions & 1 deletion .editorconfig
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
[*.{kt, kts}]
disabled_rules = no-wildcard-imports
ktlint_standard_no-wildcard-imports = disabled
ktlint_standard_filename = disabled
indent_size = 2
insert_final_newline = true
# possible values: number (e.g. 120) (package name, imports & comments are ignored), "off"
# it's automatically set to 100 on `ktlint --android ...` (per Android Kotlin Style Guide)
max_line_length = 120

[backend/data/src/main/kotlin/io/tolgee/service/dataImport/processors/messageFormat/data/PluralData.kt]
max_line_length = 500
2 changes: 1 addition & 1 deletion .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -435,4 +435,4 @@ jobs:
key: ${{ runner.os }}-gradle-wrapper-${{ hashFiles('gradle/wrapper/gradle-wrapper.properties') }}

- name: Run ktlint
run: ./gradlew ktlint
run: ./gradlew ktlintCheck
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ import io.tolgee.constants.Message
import io.tolgee.exceptions.BadRequestException
import io.tolgee.hateoas.organization.OrganizationModel
import io.tolgee.hateoas.organization.OrganizationModelAssembler
import io.tolgee.hateoas.user_account.UserAccountModel
import io.tolgee.hateoas.user_account.UserAccountModelAssembler
import io.tolgee.hateoas.userAccount.UserAccountModel
import io.tolgee.hateoas.userAccount.UserAccountModelAssembler
import io.tolgee.model.UserAccount
import io.tolgee.model.views.OrganizationView
import io.tolgee.security.authentication.AuthenticationFacade
Expand All @@ -33,8 +33,8 @@ import io.swagger.v3.oas.annotations.tags.Tag as OpenApiTag
@CrossOrigin(origins = ["*"])
@RequestMapping(
value = [
"/v2/administration"
]
"/v2/administration",
],
)
@OpenApiTag(name = "Admin", description = "Server administration")
class AdministrationController(
Expand All @@ -45,15 +45,16 @@ class AdministrationController(
private val userAccountService: UserAccountService,
private val pagedResourcesAssembler: PagedResourcesAssembler<UserAccount>,
private val userAccountModelAssembler: UserAccountModelAssembler,
private val jwtService: JwtService
private val jwtService: JwtService,
) : IController {

@GetMapping(value = ["/organizations"])
@Operation(summary = "Get all server organizations")
@RequiresSuperAuthentication
fun getOrganizations(
@ParameterObject @SortDefault(sort = ["name"]) pageable: Pageable,
search: String? = null
@ParameterObject
@SortDefault(sort = ["name"])
pageable: Pageable,
search: String? = null,
): PagedModel<OrganizationModel> {
val organizations = organizationService.findAllPaged(pageable, search, authenticationFacade.authenticatedUser.id)
return pagedOrganizationResourcesAssembler.toModel(organizations, organizationModelAssembler)
Expand All @@ -63,8 +64,10 @@ class AdministrationController(
@Operation(summary = "Get all server users")
@RequiresSuperAuthentication
fun getUsers(
@ParameterObject @SortDefault(sort = ["name"]) pageable: Pageable,
search: String? = null
@ParameterObject
@SortDefault(sort = ["name"])
pageable: Pageable,
search: String? = null,
): PagedModel<UserAccountModel> {
val users = userAccountService.findAllWithDisabledPaged(pageable, search)
return pagedResourcesAssembler.toModel(users, userAccountModelAssembler)
Expand All @@ -73,7 +76,9 @@ class AdministrationController(
@DeleteMapping(value = ["/users/{userId}"])
@Operation(summary = "Deletes an user")
@RequiresSuperAuthentication
fun deleteUser(@PathVariable userId: Long) {
fun deleteUser(
@PathVariable userId: Long,
) {
if (userId == authenticationFacade.authenticatedUser.id) {
throw BadRequestException(Message.CANNOT_DELETE_YOUR_OWN_ACCOUNT)
}
Expand All @@ -83,7 +88,9 @@ class AdministrationController(
@PutMapping(value = ["/users/{userId}/disable"])
@Operation(summary = "Deletes an user")
@RequiresSuperAuthentication
fun disableUser(@PathVariable userId: Long) {
fun disableUser(
@PathVariable userId: Long,
) {
if (userId == authenticationFacade.authenticatedUser.id) {
throw BadRequestException(Message.CANNOT_DISABLE_YOUR_OWN_ACCOUNT)
}
Expand All @@ -93,7 +100,9 @@ class AdministrationController(
@PutMapping(value = ["/users/{userId}/enable"])
@Operation(summary = "Deletes an user")
@RequiresSuperAuthentication
fun enableUser(@PathVariable userId: Long) {
fun enableUser(
@PathVariable userId: Long,
) {
userAccountService.enable(userId)
}

Expand All @@ -102,7 +111,7 @@ class AdministrationController(
@RequiresSuperAuthentication
fun setRole(
@PathVariable userId: Long,
@PathVariable role: UserAccount.Role
@PathVariable role: UserAccount.Role,
) {
val user = userAccountService.get(userId)
user.role = role
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ import org.springframework.web.bind.annotation.RestController
@RequestMapping(
value = [
"/v2/projects/{projectId}/all-keys",
]
],
)
@Tag(name = "All localization keys", description = "All localization keys in the project")
class AllKeysController(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,12 @@ import org.springframework.web.bind.annotation.RestController
@RequestMapping(
value = [
"/v2/announcement",
]
],
)
@Tag(name = "New features announcements")
class AnnouncementController(
private val announcementService: AnnouncementService,
private val authenticationFacade: AuthenticationFacade
private val authenticationFacade: AuthenticationFacade,
) : IController {
@GetMapping("")
@Operation(description = "Get latest announcement")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,11 +65,13 @@ class ApiKeyController(
private val pagedResourcesAssembler: PagedResourcesAssembler<ApiKey>,
private val permissionService: PermissionService,
) {

@PostMapping(path = ["/api-keys"])
@Operation(summary = "Creates new API key with provided scopes")
@RequiresSuperAuthentication
fun create(@RequestBody @Valid dto: CreateApiKeyDto): RevealedApiKeyModel {
fun create(
@RequestBody @Valid
dto: CreateApiKeyDto,
): RevealedApiKeyModel {
val project = projectService.get(dto.projectId)
if (authenticationFacade.authenticatedUser.role != UserAccount.Role.ADMIN) {
securityService.checkApiKeyScopes(dto.scopes, project)
Expand All @@ -79,22 +81,27 @@ class ApiKeyController(
scopes = dto.scopes,
project = project,
expiresAt = dto.expiresAt,
description = dto.description
description = dto.description,
).let {
revealedApiKeyModelAssembler.toModel(it)
}
}

@Operation(summary = "Returns user's api keys")
@GetMapping(path = ["/api-keys"])
fun allByUser(pageable: Pageable, @RequestParam filterProjectId: Long?): PagedModel<ApiKeyModel> {
fun allByUser(
pageable: Pageable,
@RequestParam filterProjectId: Long?,
): PagedModel<ApiKeyModel> {
return apiKeyService.getAllByUser(authenticationFacade.authenticatedUser.id, filterProjectId, pageable)
.let { pagedResourcesAssembler.toModel(it, apiKeyModelAssembler) }
}

@Operation(summary = "Returns specific API key info")
@GetMapping(path = ["/api-keys/{keyId:[0-9]+}"])
fun get(@PathVariable keyId: Long): ApiKeyModel {
fun get(
@PathVariable keyId: Long,
): ApiKeyModel {
val apiKey = apiKeyService.findOptional(keyId).orElseThrow { NotFoundException() }
if (apiKey.userAccount.id != authenticationFacade.authenticatedUser.id) {
securityService.checkProjectPermission(apiKey.project.id, Scope.ADMIN)
Expand All @@ -112,17 +119,18 @@ class ApiKeyController(

val apiKey = authenticationFacade.projectApiKeyEntity

val permissionData = permissionService.getProjectPermissionData(
apiKey.project.id,
authenticationFacade.authenticatedUser.id
)
val permissionData =
permissionService.getProjectPermissionData(
apiKey.project.id,
authenticationFacade.authenticatedUser.id,
)

val translateLanguageIds =
permissionData.computedPermissions.translateLanguageIds.toNormalizedPermittedLanguageSet()

return ApiKeyWithLanguagesModel(
apiKeyModelAssembler.toModel(apiKey),
permittedLanguageIds = translateLanguageIds
permittedLanguageIds = translateLanguageIds,
)
}

Expand All @@ -131,39 +139,43 @@ class ApiKeyController(
@AllowApiAccess()
fun getCurrentPermissions(
@RequestParam
@Parameter(description = "Required when using with PAT") projectId: Long?
@Parameter(description = "Required when using with PAT")
projectId: Long?,
): ApiKeyPermissionsModel {
val apiKeyAuthentication = authenticationFacade.isProjectApiKeyAuth
val personalAccessTokenAuth = authenticationFacade.isPersonalAccessTokenAuth

val projectIdNotNull = when {
apiKeyAuthentication ->
authenticationFacade.projectApiKey.projectId
val projectIdNotNull =
when {
apiKeyAuthentication ->
authenticationFacade.projectApiKey.projectId

personalAccessTokenAuth ->
projectId ?: throw BadRequestException(Message.NO_PROJECT_ID_PROVIDED)
personalAccessTokenAuth ->
projectId ?: throw BadRequestException(Message.NO_PROJECT_ID_PROVIDED)

else -> throw BadRequestException(Message.INVALID_AUTHENTICATION_METHOD)
}
else -> throw BadRequestException(Message.INVALID_AUTHENTICATION_METHOD)
}

val permissionData = permissionService.getProjectPermissionData(
projectIdNotNull,
authenticationFacade.authenticatedUser.id
)
val permissionData =
permissionService.getProjectPermissionData(
projectIdNotNull,
authenticationFacade.authenticatedUser.id,
)

val computed = permissionData.computedPermissions
val scopes = when {
apiKeyAuthentication -> authenticationFacade.projectApiKey.scopes.toTypedArray()
else -> computed.scopes
}
val scopes =
when {
apiKeyAuthentication -> authenticationFacade.projectApiKey.scopes.toTypedArray()
else -> computed.scopes
}

return ApiKeyPermissionsModel(
projectIdNotNull,
type = if (apiKeyAuthentication) null else computed.type,
translateLanguageIds = computed.translateLanguageIds.toNormalizedPermittedLanguageSet(),
viewLanguageIds = computed.viewLanguageIds.toNormalizedPermittedLanguageSet(),
stateChangeLanguageIds = computed.stateChangeLanguageIds.toNormalizedPermittedLanguageSet(),
scopes = scopes
scopes = scopes,
)
}

Expand All @@ -185,7 +197,11 @@ class ApiKeyController(
@PutMapping(path = ["/api-keys/{apiKeyId:[0-9]+}"])
@Operation(summary = "Edits existing API key")
@RequiresSuperAuthentication
fun update(@RequestBody @Valid dto: V2EditApiKeyDto, @PathVariable apiKeyId: Long): ApiKeyModel {
fun update(
@RequestBody @Valid
dto: V2EditApiKeyDto,
@PathVariable apiKeyId: Long,
): ApiKeyModel {
val apiKey = apiKeyService.get(apiKeyId)
checkOwner(apiKey)
securityService.checkApiKeyScopes(dto.scopes, apiKey.project)
Expand All @@ -195,12 +211,13 @@ class ApiKeyController(

@PutMapping(value = ["/api-keys/{apiKeyId:[0-9]+}/regenerate"])
@Operation(
summary = "Regenerates API key. It generates new API key value and updates its time of expiration."
summary = "Regenerates API key. It generates new API key value and updates its time of expiration.",
)
@RequiresSuperAuthentication
fun regenerate(
@RequestBody @Valid dto: RegenerateApiKeyDto,
@PathVariable apiKeyId: Long
@RequestBody @Valid
dto: RegenerateApiKeyDto,
@PathVariable apiKeyId: Long,
): RevealedApiKeyModel {
checkOwner(apiKeyId)
return revealedApiKeyModelAssembler.toModel(apiKeyService.regenerate(apiKeyId, dto.expiresAt))
Expand All @@ -209,7 +226,9 @@ class ApiKeyController(
@DeleteMapping(path = ["/api-keys/{apiKeyId:[0-9]+}"])
@Operation(summary = "Deletes API key")
@RequiresSuperAuthentication
fun delete(@PathVariable apiKeyId: Long) {
fun delete(
@PathVariable apiKeyId: Long,
) {
val apiKey = apiKeyService.findOptional(apiKeyId).orElseThrow { NotFoundException(Message.API_KEY_NOT_FOUND) }
checkOwner(apiKey)
apiKeyService.deleteApiKey(apiKey)
Expand Down Expand Up @@ -239,8 +258,9 @@ class ApiKeyController(
content = [
Content(
mediaType = "application/json",
schema = Schema(
example = """
schema =
Schema(
example = """
{
"TRANSLATE":[
"translations.view",
Expand All @@ -267,12 +287,12 @@ class ApiKeyController(
"translations.view",
"screenshots.view"
]
}"""
)
)
]
)
]
}""",
),
),
],
),
],
)
@Deprecated(message = "Don't use this endpoint, it's useless.")
val scopes: Map<String, List<String>> by lazy {
Expand Down
Loading
Loading