Skip to content

Commit

Permalink
Merge branch 'master' into localization_for_cn
Browse files Browse the repository at this point in the history
  • Loading branch information
JustinB1eber authored Sep 6, 2023
2 parents f9a7bdd + 13d4ade commit 8737bcb
Show file tree
Hide file tree
Showing 6 changed files with 62 additions and 6 deletions.
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
package com.saveourtool.save.backend.security

import com.saveourtool.save.authservice.utils.username
import com.saveourtool.save.backend.service.LnkUserOrganizationService
import com.saveourtool.save.backend.repository.LnkUserOrganizationRepository
import com.saveourtool.save.entities.OrganizationStatus
import com.saveourtool.save.info.UserPermissions
import com.saveourtool.save.info.UserPermissionsInOrganization
import org.springframework.security.core.Authentication
Expand All @@ -12,7 +13,7 @@ import org.springframework.stereotype.Component
*/
@Component
class UserPermissionEvaluator(
private var lnkUserOrganizationService: LnkUserOrganizationService,
private var lnkUserOrganizationRepository: LnkUserOrganizationRepository,
) {
/**
* @param authentication
Expand All @@ -21,7 +22,21 @@ class UserPermissionEvaluator(
fun getUserPermissions(
authentication: Authentication,
): UserPermissions {
val lnkOrganizations = lnkUserOrganizationService.getOrganizationsByUserNameAndCreatedStatus(authentication.username())
val lnkOrganizations = lnkUserOrganizationRepository.findByUserNameAndOrganizationStatus(authentication.username(), OrganizationStatus.CREATED)

return UserPermissions(
lnkOrganizations.associate { it.organization.name to UserPermissionsInOrganization(it.organization.canCreateContests, it.organization.canBulkUpload) },
)
}

/**
* @param userName
* @return UserPermissions
*/
fun getUserPermissionsByName(
userName: String,
): UserPermissions {
val lnkOrganizations = lnkUserOrganizationRepository.findByUserNameAndOrganizationStatus(userName, OrganizationStatus.CREATED)

return UserPermissions(
lnkOrganizations.associate { it.organization.name to UserPermissionsInOrganization(it.organization.canCreateContests, it.organization.canBulkUpload) },
Expand All @@ -37,7 +52,8 @@ class UserPermissionEvaluator(
authentication: Authentication,
organizationName: String,
): UserPermissions {
val lnkOrganization = lnkUserOrganizationService.getOrganizationsByUserNameAndCreatedStatusAndOrganizationName(authentication.username(), organizationName)
val lnkOrganization = lnkUserOrganizationRepository.findByUserNameAndOrganizationStatusAndOrganizationName(authentication.username(), OrganizationStatus.CREATED,
organizationName)

val isPermittedCreateContest = lnkOrganization?.organization?.canCreateContests ?: false
val isPermittedToBulkUpload = lnkOrganization?.organization?.canBulkUpload ?: false
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
package com.saveourtool.save.backend.service

import com.saveourtool.save.backend.security.UserPermissionEvaluator
import com.saveourtool.save.backend.service.vulnerability.VulnerabilityService
import com.saveourtool.save.entities.Organization
import com.saveourtool.save.entities.User
import com.saveourtool.save.entities.vulnerabilities.Vulnerability
import com.saveourtool.save.entities.vulnerability.VulnerabilityDto
import org.springframework.security.core.Authentication
import org.springframework.stereotype.Service

/**
Expand All @@ -15,6 +17,7 @@ class BackendForCosvService(
private val vulnerabilityService: VulnerabilityService,
private val organizationService: OrganizationService,
private val userDetailsService: UserDetailsService,
private val userPermissionEvaluator: UserPermissionEvaluator,
) : IBackendService {
override fun findVulnerabilityByName(name: String): Vulnerability? = vulnerabilityService.findByName(name)

Expand All @@ -23,4 +26,8 @@ class BackendForCosvService(
override fun getOrganizationByName(name: String): Organization = organizationService.getByName(name)

override fun getUserByName(name: String): User = userDetailsService.getByName(name)

override fun getUserPermissionsByOrganizationName(authentication: Authentication, organizationName: String) = userPermissionEvaluator.getUserPermissionsByOrganizationName(
authentication, organizationName
)
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package com.saveourtool.save.backend.service

import com.saveourtool.save.authservice.utils.userId
import com.saveourtool.save.authservice.utils.username
import com.saveourtool.save.backend.repository.LnkUserOrganizationRepository
import com.saveourtool.save.backend.repository.LnkUserProjectRepository
import com.saveourtool.save.backend.repository.OriginalLoginRepository
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,13 @@ import kotlinx.serialization.Serializable
@Serializable
data class UserPermissions(
val inOrganizations: Map<String, UserPermissionsInOrganization> = emptyMap(),
)
) {
companion object {
/**
* Value that represents an empty [UserPermissions]
*/
val empty = UserPermissions(
inOrganizations = emptyMap(),
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ import com.saveourtool.save.entities.Organization
import com.saveourtool.save.entities.User
import com.saveourtool.save.entities.vulnerabilities.Vulnerability
import com.saveourtool.save.entities.vulnerability.VulnerabilityDto
import com.saveourtool.save.info.UserPermissions
import org.springframework.security.core.Authentication

/**
* Interface for service to get required info for COSV from backend
Expand Down Expand Up @@ -39,4 +41,11 @@ interface IBackendService {
* @return found [User] by name
*/
fun getUserByName(name: String): User

/**
* @param authentication
* @param organizationName name of organization
* @return found [UserPermissions] by organizationName
*/
fun getUserPermissionsByOrganizationName(authentication: Authentication, organizationName: String): UserPermissions
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,10 @@ import com.saveourtool.save.entities.vulnerability.*
import com.saveourtool.save.utils.*

import com.saveourtool.osv4k.*
import org.springframework.http.HttpStatus
import org.springframework.security.core.Authentication
import org.springframework.stereotype.Service
import org.springframework.web.server.ResponseStatusException
import reactor.core.publisher.Flux
import reactor.core.publisher.Mono
import reactor.kotlin.core.publisher.toMono
Expand Down Expand Up @@ -47,6 +49,7 @@ class CosvService(
* @param authentication who uploads [inputStream]
* @param organizationName to which is uploaded
* @return save's vulnerability identifiers
* @throws ResponseStatusException
*/
@OptIn(ExperimentalSerializationApi::class)
fun decodeAndSave(
Expand All @@ -56,6 +59,12 @@ class CosvService(
): Flux<String> {
val user = backendService.getUserByName(authentication.name)
val organization = backendService.getOrganizationByName(organizationName)
val userPermissions = backendService.getUserPermissionsByOrganizationName(authentication, organizationName)

if (userPermissions.inOrganizations[organizationName]?.canDoBulkUpload != true) {
return Flux.error(ResponseStatusException(HttpStatus.FORBIDDEN, "You do not have permission to upload COSV files on behalf of this organization: $organizationName"))
}

return inputStreams.flatMap { inputStream ->
decode(json.decodeFromStream<JsonElement>(inputStream), user, organization)
}.save(user)
Expand All @@ -68,6 +77,7 @@ class CosvService(
* @param authentication who uploads [content]
* @param organizationName to which is uploaded
* @return save's vulnerability identifiers
* @throws ResponseStatusException
*/
fun decodeAndSave(
content: String,
Expand All @@ -76,6 +86,12 @@ class CosvService(
): Flux<String> {
val user = backendService.getUserByName(authentication.name)
val organization = backendService.getOrganizationByName(organizationName)
val userPermissions = backendService.getUserPermissionsByOrganizationName(authentication, organizationName)

if (userPermissions.inOrganizations[organizationName]?.canDoBulkUpload != true) {
return Flux.error(ResponseStatusException(HttpStatus.FORBIDDEN, "You do not have permission to upload COSV file on behalf of this organization: $organizationName"))
}

return decode(json.parseToJsonElement(content), user, organization).save(user)
}

Expand Down

0 comments on commit 8737bcb

Please sign in to comment.