Skip to content

Commit 6e5eee7

Browse files
authored
Merge pull request #187 from Poeschl/add-user-registration-setting
✨ Add setting for disabling user registration
2 parents 5a1859f + 1cccefe commit 6e5eee7

File tree

10 files changed

+45
-19
lines changed

10 files changed

+45
-19
lines changed

backend/src/main/kotlin/xyz/poeschl/roborush/controller/ConfigRestController.kt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,8 @@ class ConfigRestController(private val configService: ConfigService, private val
125125
fun getClientSettings(): ClientSettings {
126126
return ClientSettings(
127127
configService.getGlobalNotificationText(),
128-
configService.getBooleanSetting(SettingKey.ENABLE_WEB_ROBOT_CONTROL).value
128+
configService.getBooleanSetting(SettingKey.ENABLE_WEB_ROBOT_CONTROL).value,
129+
configService.getBooleanSetting(SettingKey.ENABLE_USER_REGISTRATION).value
129130
)
130131
}
131132
}

backend/src/main/kotlin/xyz/poeschl/roborush/models/settings/Setting.kt

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,8 @@ enum class SettingKey(@JsonIgnore val isFrontendSetting: Boolean = false) {
3535
ENABLE_FULL_MAP_SCAN,
3636
ENABLE_DUMMY_ROBOTS,
3737
ENABLE_WEB_ROBOT_CONTROL(isFrontendSetting = true),
38-
DISTANCE_ROBOT_SIGHT_ON_MOVE
38+
DISTANCE_ROBOT_SIGHT_ON_MOVE,
39+
ENABLE_USER_REGISTRATION(isFrontendSetting = true)
3940
}
4041

4142
enum class SettingType {
@@ -44,4 +45,4 @@ enum class SettingType {
4445
BOOLEAN
4546
}
4647

47-
data class ClientSettings(val globalNotificationText: String, val enableWebRobotControl: Boolean)
48+
data class ClientSettings(val globalNotificationText: String, val enableWebRobotControl: Boolean, val enableUserRegistration: Boolean)

backend/src/main/kotlin/xyz/poeschl/roborush/security/restcontroller/AuthRestController.kt

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -9,16 +9,22 @@ import org.springframework.security.authentication.AuthenticationManager
99
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken
1010
import org.springframework.security.core.Authentication
1111
import org.springframework.security.core.context.SecurityContextHolder
12-
import org.springframework.web.bind.annotation.*
12+
import org.springframework.web.bind.annotation.PostMapping
13+
import org.springframework.web.bind.annotation.RequestBody
14+
import org.springframework.web.bind.annotation.RequestMapping
15+
import org.springframework.web.bind.annotation.RestController
16+
import xyz.poeschl.roborush.models.settings.SettingKey
1317
import xyz.poeschl.roborush.security.service.UserDetailsService
1418
import xyz.poeschl.roborush.security.utils.JwtTokenProvider
19+
import xyz.poeschl.roborush.service.ConfigService
1520

1621
@RestController
1722
@RequestMapping("/auth")
1823
class AuthRestController(
1924
private val authenticationManager: AuthenticationManager,
2025
private val jwtTokenProvider: JwtTokenProvider,
21-
private val userDetailsService: UserDetailsService
26+
private val userDetailsService: UserDetailsService,
27+
private val configService: ConfigService
2228
) {
2329

2430
companion object {
@@ -40,12 +46,19 @@ class AuthRestController(
4046

4147
@PostMapping("/register", produces = [MediaType.APPLICATION_JSON_VALUE], consumes = [MediaType.APPLICATION_JSON_VALUE])
4248
fun registerUser(@RequestBody registerRequest: RegisterRequest): ResponseEntity<Void> {
43-
try {
44-
userDetailsService.registerNewUser(registerRequest.username, registerRequest.password)
45-
} catch (ex: DataIntegrityViolationException) {
46-
LOGGER.warn("Username '${registerRequest.username}' is already taken. Registration not possible")
47-
return ResponseEntity.status(HttpStatus.CONFLICT).build()
49+
if (registerRequest.username.length > 3 &&
50+
registerRequest.password.length > 8 &&
51+
configService.getBooleanSetting(SettingKey.ENABLE_USER_REGISTRATION).value
52+
) {
53+
try {
54+
userDetailsService.registerNewUser(registerRequest.username, registerRequest.password)
55+
} catch (ex: DataIntegrityViolationException) {
56+
LOGGER.warn("Username '${registerRequest.username}' is already taken. Registration not possible")
57+
return ResponseEntity.status(HttpStatus.CONFLICT).build()
58+
}
59+
return ResponseEntity.ok().build()
60+
} else {
61+
return ResponseEntity.badRequest().build()
4862
}
49-
return ResponseEntity.ok().build()
5063
}
5164
}

backend/src/main/kotlin/xyz/poeschl/roborush/service/ConfigService.kt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,8 @@ class ConfigService(
6262
websocketController.sendClientSettingsUpdate(
6363
ClientSettings(
6464
globalNotificationText,
65-
getBooleanSetting(SettingKey.ENABLE_FULL_MAP_SCAN).value
65+
getBooleanSetting(SettingKey.ENABLE_FULL_MAP_SCAN).value,
66+
getBooleanSetting(SettingKey.ENABLE_USER_REGISTRATION).value
6667
)
6768
)
6869
}

backend/src/main/resources/db/migration/V1_002__create_config_schemas.sql

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,3 +17,4 @@ INSERT INTO config (key, type, value) values ('ENABLE_FULL_MAP_SCAN', 'BOOLEAN',
1717
INSERT INTO config (key, type, value) values ('ENABLE_DUMMY_ROBOTS', 'BOOLEAN', 'true');
1818
INSERT INTO config (key, type, value) values ('ENABLE_WEB_ROBOT_CONTROL', 'BOOLEAN', 'true');
1919
INSERT INTO config (key, type, value) values ('DISTANCE_ROBOT_SIGHT_ON_MOVE', 'INT', '2');
20+
INSERT INTO config (key, type, value) values ('ENABLE_USER_REGISTRATION', 'BOOLEAN', 'true');

backend/src/test/kotlin/xyz/poeschl/roborush/DBMigrationIntegrityTest.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ class DBMigrationIntegrityTest {
2929
.withHashAlgorithm(HashAlgorithm.MD5)
3030
.withHashPair("V1_000__create_user_schemas.sql", "5982877bb3946da9beea4e57f4d1f57e")
3131
.withHashPair("V1_001__create_robot_schemas.sql", "6b37f4a87fa7ff214b3f61b997cc83c4")
32-
.withHashPair("V1_002__create_config_schemas.sql", "561fed397577fecf52e169147a4719f6")
32+
.withHashPair("V1_002__create_config_schemas.sql", "935942d229304ef2116299aac7697f4c")
3333
.withHashPair("V1_003__create_map_schemas.sql", "69f4ddc8bd39e42d586afca833e4e6f8")
3434
.withHashPair("V1_004__add_map_icon_map.sql", "018fc6ef7adba9b861d33394bbcc57c2")
3535
.withHashPair("V1_005__add_map_easy.sql", "c0a99225ea3ac682bd576590d630d94b")

backend/src/test/kotlin/xyz/poeschl/roborush/service/ConfigServiceTest.kt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,9 +52,11 @@ class ConfigServiceTest {
5252
val controlDto = SaveSettingDto(controlSettingEntity.key, "true")
5353

5454
val enableFullScanSettingEntity = a(`$SettingEntity`().withKey(SettingKey.ENABLE_FULL_MAP_SCAN).withType(SettingType.BOOLEAN).withValue("true"))
55+
val enableUserRegisterSettingEntity = a(`$SettingEntity`().withKey(SettingKey.ENABLE_USER_REGISTRATION).withType(SettingType.BOOLEAN).withValue("true"))
5556

5657
every { configRepository.findByKey(enableFullScanSettingEntity.key) } returns enableFullScanSettingEntity
5758
every { configRepository.findByKey(controlSettingEntity.key) } returns controlSettingEntity
59+
every { configRepository.findByKey(enableUserRegisterSettingEntity.key) } returns enableUserRegisterSettingEntity
5860

5961
every { settingEntityMapper.toEntity(controlSettingEntity, controlDto) } returns controlConvertedEntity
6062
every { configRepository.save(controlConvertedEntity) } returns controlConvertedEntity
@@ -164,6 +166,7 @@ class ConfigServiceTest {
164166

165167
every { configRepository.findByKey(SettingKey.ENABLE_FULL_MAP_SCAN) } returns settingEntity
166168
every { configRepository.findByKey(SettingKey.ENABLE_WEB_ROBOT_CONTROL) } returns settingEntity
169+
every { configRepository.findByKey(SettingKey.ENABLE_USER_REGISTRATION) } returns settingEntity
167170
every { settingEntityMapper.fromEntity(settingEntity) } answers { callOriginal() }
168171

169172
// THEN

frontend/src/components/NavbarUserComponent.vue

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<template>
22
<div class="navbar-item is-button" v-if="!userStore.loggedIn">
3-
<button class="button" @click="openRegister">
3+
<button class="button" @click="openRegister" :disabled="!registerEnabled">
44
<span class="has-text-weight-semibold">Create a account</span>
55
</button>
66
</div>
@@ -18,13 +18,13 @@
1818
</a>
1919

2020
<LoginForm v-if="loginIsShowing" :loading="loginLoading" @close="loginIsShowing = false" @login="loginUser" />
21-
<RegisterForm v-if="registerIsShowing" :loading="registerLoading" @close="registerIsShowing = false" @register="registerUser" />
21+
<RegisterForm v-if="registerIsShowing && registerEnabled" :loading="registerLoading" @close="registerIsShowing = false" @register="registerUser" />
2222
<UserModal v-if="userDetailsShown" @close="() => (userDetailsShown = false)" />
2323
<Toast v-if="toast.shown" :type="toast.type" :message="toast.message" @close="() => (toast.shown = false)" />
2424
</template>
2525

2626
<script setup lang="ts">
27-
import { ref } from "vue";
27+
import { computed, ref } from "vue";
2828
import LoginForm from "@/components/LoginForm.vue";
2929
import type { LoginRequest, RegisterRequest } from "@/models/User";
3030
import RegisterForm from "@/components/RegisterForm.vue";
@@ -33,13 +33,16 @@ import Toast from "@/components/Toast.vue";
3333
import { ToastType } from "@/models/ToastType";
3434
import UserModal from "@/components/UserModal.vue";
3535
import log from "loglevel";
36+
import { useConfigStore } from "@/stores/ConfigStore";
3637
3738
const userStore = useUserStore();
39+
const configStore = useConfigStore();
3840
3941
const loginIsShowing = ref<boolean>(false);
4042
const loginLoading = ref<boolean>(false);
4143
const registerIsShowing = ref<boolean>(false);
4244
const registerLoading = ref<boolean>(false);
45+
const registerEnabled = computed<boolean>(() => configStore.clientSettings.enableUserRegistration);
4346
const toast = ref<{ shown: boolean; type: ToastType; message: string }>({ shown: false, type: ToastType.INFO, message: "" });
4447
const userDetailsShown = ref<boolean>(false);
4548
@@ -68,8 +71,10 @@ const loginUser = (data: LoginRequest) => {
6871
};
6972
7073
const openRegister = () => {
71-
registerLoading.value = false;
72-
registerIsShowing.value = true;
74+
if (registerEnabled.value) {
75+
registerLoading.value = false;
76+
registerIsShowing.value = true;
77+
}
7378
};
7479
7580
const registerUser = (data: RegisterRequest) => {

frontend/src/models/Config.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,4 +22,5 @@ export interface MapGenerationResult {
2222
export interface ClientSettings {
2323
globalNotificationText: string;
2424
enableWebRobotControl: boolean;
25+
enableUserRegistration: boolean;
2526
}

frontend/src/stores/ConfigStore.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ export const useConfigStore = defineStore("configStore", () => {
1111

1212
const currentConfig = ref<Map<string, Setting>>(new Map());
1313
const availableMaps = ref<{ maps: PlaygroundMap[] }>({ maps: [] });
14-
const clientSettings = ref<ClientSettings>({ globalNotificationText: "", enableWebRobotControl: true });
14+
const clientSettings = ref<ClientSettings>({ globalNotificationText: "", enableWebRobotControl: true, enableUserRegistration: false });
1515

1616
const initWebsocket = (webSocketInstance: { initWebsocket: Function; registerForTopicCallback: Function }) => {
1717
websocketService.value = webSocketInstance;

0 commit comments

Comments
 (0)