Skip to content

Commit

Permalink
Authorization with other source providers (#2304)
Browse files Browse the repository at this point in the history
### What's done:
- Fix for registration of new users
- Polishing formating of auth providers
- Dev test configuration for Gitee OAUTH
  • Loading branch information
orchestr7 authored Jul 10, 2023
1 parent 3112719 commit 942c35a
Show file tree
Hide file tree
Showing 17 changed files with 142 additions and 95 deletions.
13 changes: 13 additions & 0 deletions api-gateway/src/main/resources/application-dev.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@ spring:
client:
provider:
# example: https://github.com/wearearima/spring-boot-dex/blob/master/src/main/resources/application.properties
gitee:
authorization-uri: https://gitee.com/oauth/authorize
token-uri: https://gitee.com/oauth/token
user-info-uri: https://gitee.com/api/v5/user
dex:
authorization-uri: http://localhost:5556/dex/auth
token-uri: http://localhost:5556/dex/token
Expand All @@ -31,6 +35,15 @@ spring:
# for more details.
user-name-attribute: login
registration:
gitee:
client-id: 6b7fc07ecdf7a12d9aa8e2aaf034743baa6f77e036dc22fe6455e02fcf51a851
client-secret: 8908a8a4239c688af45a4db89ec27d4a7e7f5076dc3125b07b506de6414926a3
client-name: Gitee
provider: gitee
redirect-uri: '${gateway.frontend.url}/{action}/oauth2/code/{registrationId}'
authorization-grant-type: authorization_code
scope:
- user_info
dex:
client-id: save-gateway-dev
client-secret: 123test123
Expand Down
15 changes: 4 additions & 11 deletions save-frontend/src/main/kotlin/com/saveourtool/save/frontend/App.kt
Original file line number Diff line number Diff line change
Expand Up @@ -112,17 +112,10 @@ class App : ComponentWithScope<PropsWithChildren, AppState>() {
requestModalHandler {
userInfo = state.userInfo

withRouter<Props> { location, _ ->
if (state.userInfo?.isActive == false && !location.pathname.startsWith("/${FrontendRoutes.REGISTRATION.path}")) {
Navigate {
to = "/${FrontendRoutes.REGISTRATION.path}"
replace = false
}
} else if (state.userInfo?.isActive == true && location.pathname.startsWith("/${FrontendRoutes.REGISTRATION.path}")) {
Navigate {
to = "/${FrontendRoutes.PROJECTS.path}"
replace = false
}
if (state.userInfo?.isActive == false) {
Navigate {
to = "/${FrontendRoutes.REGISTRATION.path}"
replace = false
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
package com.saveourtool.save.frontend.components.basic

import com.saveourtool.save.entities.OrganizationDto
import com.saveourtool.save.frontend.utils.AVATAR_PROFILE_PLACEHOLDER
import com.saveourtool.save.info.UserInfo
import js.core.jso
import react.CSSProperties
Expand All @@ -18,11 +19,6 @@ import web.cssom.ClassName
*/
const val ORGANIZATION_AVATAR_PLACEHOLDER = "img/company.svg"

/**
* Placeholder for user avatar
*/
const val USER_AVATAR_PLACEHOLDER = "img/undraw_profile.svg"

/**
* Render organization avatar or placeholder
*
Expand Down Expand Up @@ -51,7 +47,7 @@ fun ChildrenBuilder.renderAvatar(
classes: String = "",
link: String? = null,
styleBuilder: CSSProperties.() -> Unit = {},
) = renderAvatar(userInfo.avatar ?: USER_AVATAR_PLACEHOLDER, classes, link, styleBuilder)
) = renderAvatar(userInfo.avatar ?: AVATAR_PROFILE_PLACEHOLDER, classes, link, styleBuilder)

private fun ChildrenBuilder.renderAvatar(
avatarLink: String,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -185,7 +185,7 @@ private fun ChildrenBuilder.renderLeftColumn(
rating: Long,
color: String = "#f1f1f1",
) {
val (avatar, setAvatar) = useState(userAvatar?.let { "/api/$v1/avatar$it" } ?: "img/undraw_profile.svg")
val (avatar, setAvatar) = useState(userAvatar?.let { "/api/$v1/avatar$it" } ?: AVATAR_PROFILE_PLACEHOLDER)

div {
className = ClassName("input-group-prepend col-2")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,12 @@ import com.saveourtool.save.frontend.externals.modal.Styles
import react.CSSProperties
import kotlin.js.json

private val defaultOverlayProperties: CSSProperties = json("zIndex" to "1000").unsafeCast<CSSProperties>()
/**
* Maximum zIndex in the project, should be only used in modal windows
*/
internal const val MAX_Z_INDEX = 1000

private val defaultOverlayProperties: CSSProperties = json("zIndex" to MAX_Z_INDEX.toString()).unsafeCast<CSSProperties>()

val defaultModalStyle = Styles(
// make modal window occupy center of the screen
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import com.saveourtool.save.info.UserInfo
import com.saveourtool.save.v1
import com.saveourtool.save.validation.FrontendRoutes

import js.core.jso
import react.*
import react.dom.aria.*
import react.dom.html.ReactHTML.a
Expand All @@ -22,6 +23,7 @@ import react.dom.html.ReactHTML.span
import react.dom.html.ReactHTML.ul
import react.router.useNavigate
import web.cssom.ClassName
import web.cssom.rem

import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
Expand All @@ -30,6 +32,13 @@ import kotlinx.coroutines.isActive

val topBarUserField = topBarUserField()

@Suppress("MAGIC_NUMBER")
val logoSize: CSSProperties =
jso {
height = 2.5.rem
width = 2.5.rem
}

/**
* [Props] of the top bar user field component
*/
Expand Down Expand Up @@ -91,20 +100,23 @@ private fun topBarUserField() = FC<TopBarUserFieldProps> { props ->
+(props.userInfo?.name.orEmpty())
}
val globalRole = props.userInfo?.globalRole ?: Role.VIEWER
if (globalRole.isHigherOrEqualThan(Role.ADMIN)) {
small {
className = ClassName("text-gray-400 text-justify")
+globalRole.formattedName
small {
className = ClassName("text-gray-400 text-justify")
props.userInfo?.let {
if (globalRole.isHigherOrEqualThan(Role.ADMIN)) {
+"Super user"
} else {
+"User settings"
}
}
}
}
props.userInfo?.avatar?.let {
props.userInfo?.let { userInfo ->
img {
className =
ClassName("ml-2 align-self-center avatar avatar-user width-full border color-bg-default rounded-circle fas mr-2")
src = avatar
height = 45.0
width = 45.0
src = userInfo.avatar?.let { avatar } ?: AVATAR_PROFILE_PLACEHOLDER
style = logoSize
onError = {
setAvatar { AVATAR_PLACEHOLDER }
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -208,7 +208,7 @@ class OrganizationView : AbstractView<OrganizationProps, OrganizationViewState>(
isEditDisabled = true
selfRole = highestRole
usersInOrganization = users
avatar = organizationLoaded.avatar?.let { "/api/$v1/avatar$it" } ?: "img/undraw_profile.svg"
avatar = organizationLoaded.avatar?.let { "/api/$v1/avatar$it" } ?: AVATAR_PROFILE_PLACEHOLDER
}
urlAnalysis(OrganizationMenuBar, highestRole, organizationLoaded.canCreateContests)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,13 @@ package com.saveourtool.save.frontend.components.views

import com.saveourtool.save.frontend.components.inputform.InputTypes
import com.saveourtool.save.frontend.components.inputform.inputTextFormRequired
import com.saveourtool.save.frontend.components.modal.MAX_Z_INDEX
import com.saveourtool.save.frontend.http.postImageUpload
import com.saveourtool.save.frontend.utils.*
import com.saveourtool.save.frontend.utils.classLoadingHandler
import com.saveourtool.save.info.UserInfo
import com.saveourtool.save.utils.AvatarType
import com.saveourtool.save.v1
import com.saveourtool.save.validation.FrontendRoutes
import com.saveourtool.save.validation.isValidName

import js.core.asList
Expand All @@ -30,7 +30,9 @@ import react.dom.html.ReactHTML.input
import react.dom.html.ReactHTML.label
import react.dom.html.ReactHTML.main
import react.dom.html.ReactHTML.span
import react.router.Navigate
import web.cssom.ClassName
import web.cssom.ZIndex
import web.cssom.rem
import web.html.ButtonType
import web.html.HTMLInputElement
Expand Down Expand Up @@ -122,7 +124,7 @@ class RegistrationView : AbstractView<RegistrationProps, RegistrationViewState>(
responseHandler = ::classComponentResponseHandlerWithValidation,
)
if (response.ok) {
window.location.href = "#/${FrontendRoutes.PROJECTS.path}"
window.location.href = "#"
window.location.reload()
} else if (response.isConflict()) {
val responseText = response.unpackMessage()
Expand All @@ -137,6 +139,15 @@ class RegistrationView : AbstractView<RegistrationProps, RegistrationViewState>(
"EMPTY_BLOCK_STRUCTURE_ERROR",
)
override fun ChildrenBuilder.render() {
particles()

if (props.userInfo?.isActive != false) {
Navigate {
to = "/"
replace = false
}
}

main {
className = ClassName("main-content mt-0 ps")
div {
Expand All @@ -150,6 +161,9 @@ class RegistrationView : AbstractView<RegistrationProps, RegistrationViewState>(
className = ClassName("col-sm-4")
div {
className = ClassName("container card o-hidden border-0 shadow-lg my-2 card-body p-0")
style = jso {
zIndex = (MAX_Z_INDEX - 1).unsafeCast<ZIndex>()
}
div {
className = ClassName("p-5 text-center")
renderTitle()
Expand Down Expand Up @@ -194,7 +208,7 @@ class RegistrationView : AbstractView<RegistrationProps, RegistrationViewState>(
src = props.userInfo?.avatar?.let {
"/api/$v1/avatar$it"
}
?: "img/undraw_profile.svg"
?: AVATAR_PROFILE_PLACEHOLDER
style = jso {
height = 16.rem
width = 16.rem
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ private fun ChildrenBuilder.creationCard(url: String, img: String) {
(img {
src = img
style = jso {
width = 20.rem
width = 17.rem
border = "0.2rem solid hsl(186 100% 69%)".unsafeCast<Border>()
}
})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,8 @@

package com.saveourtool.save.frontend.components.views.index

import com.saveourtool.save.frontend.externals.fontawesome.faCopyright
import com.saveourtool.save.frontend.externals.fontawesome.faGithub
import com.saveourtool.save.frontend.externals.fontawesome.faSignInAlt
import com.saveourtool.save.frontend.externals.fontawesome.fontAwesomeIcon
import com.saveourtool.save.frontend.components.views.welcome.mappingFromTypeToFontLogo
import com.saveourtool.save.frontend.externals.fontawesome.*
import com.saveourtool.save.frontend.utils.*
import com.saveourtool.save.frontend.utils.noopResponseHandler
import com.saveourtool.save.info.OauthProviderInfo
Expand Down Expand Up @@ -48,24 +46,27 @@ val indexAuth: FC<IndexViewProps> = FC { props ->
div {
className = ClassName("row mt-2")
div {
className = ClassName("col-3 text-center")
className = ClassName("col-4 text-center")
}
div {
className = ClassName("col-6 text-center")
className = ClassName("col-4 text-center")
@Suppress("MAGIC_NUMBER")
oauthProviders.map {
oauthLogin(
4.rem, it, "animate__backInUp",
when (it.registrationId) {
"github" -> faGithub
"codehub" -> faCopyright
else -> faSignInAlt
}
)
div {
className = ClassName("row")
oauthProviders.map { userInfo ->
val oauthProvider = userInfo.registrationId
oauthLogin(
4.rem,
userInfo,
"animate__backInUp",
oauthProvider.replaceFirstChar { ch -> if (ch.isLowerCase()) ch.titlecase() else ch.toString() },
mappingFromTypeToFontLogo(oauthProvider)
)
}
}
}
div {
className = ClassName("col-3 text-center")
className = ClassName("col-4 text-center")
}
}
}
Expand Down Expand Up @@ -96,19 +97,31 @@ val separator = VFC {
* @param provider oauth provider (Huawei, Gitee, Github, etc.)
* @param icon icon logo
* @param animate
* @param label
*/
fun ChildrenBuilder.oauthLogin(
size: FontSize,
provider: OauthProviderInfo,
animate: String,
label: String = "",
icon: dynamic
) {
a {
href = provider.authorizationLink
className = ClassName("btn btn-link px-5 text-white text-lg text-center animate__animated $animate")
style = jso {
fontSize = size
div {
className = ClassName("animated-provider col animate__animated $animate")
a {
href = provider.authorizationLink
className = ClassName("text-center")
div {
className = ClassName("col text-center text-white")
style = jso {
fontSize = size
}
fontAwesomeIcon(icon = icon)
}
div {
className = ClassName("col text-center text-white")
+label
}
}
fontAwesomeIcon(icon = icon)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ val userRatingTable: FC<Props> = FC { _ ->
ClassName("avatar avatar-user width-full border color-bg-default rounded-circle")
src = cellContext.row.original.avatar?.let {
"/api/$v1/avatar$it"
} ?: "img/undraw_profile.svg"
} ?: AVATAR_PROFILE_PLACEHOLDER
style = jso {
height = 2.rem
width = 2.rem
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ fun ChildrenBuilder.renderLeftUserMenu(
"/api/$v1/avatar$path"
}
?: run {
"img/undraw_profile.svg"
AVATAR_PROFILE_PLACEHOLDER
}
alt = ""
}
Expand Down Expand Up @@ -272,7 +272,7 @@ fun ChildrenBuilder.renderLeftUserMenu(
"/api/$v1/avatar$path"
}
?: run {
"img/undraw_profile.svg"
AVATAR_PROFILE_PLACEHOLDER
}
alt = ""
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ abstract class UserSettingsView : AbstractView<UserSettingsProps, UserSettingsVi
userInfo = user
userInfo?.let { updateFieldsMap(it) }
selfOrganizationWithUserList = organizationDtos.sortedWith(comparator)
avatar = user?.avatar?.let { "/api/$v1/avatar$it" } ?: "img/undraw_profile.svg"
avatar = user?.avatar?.let { "/api/$v1/avatar$it" } ?: AVATAR_PROFILE_PLACEHOLDER
}
}
}
Expand Down
Loading

0 comments on commit 942c35a

Please sign in to comment.