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

Design improvements - 1 #73

Merged
merged 47 commits into from
Oct 13, 2021
Merged
Show file tree
Hide file tree
Changes from 33 commits
Commits
Show all changes
47 commits
Select commit Hold shift + click to select a range
7150594
Menubar styling
snicki13 Oct 4, 2021
c0a4796
Refactor: User -> UserCredentials; UserDisplay -> User.
snicki13 Oct 6, 2021
f3a688c
Avatar Upload #19
snicki13 Oct 6, 2021
2859fc9
Fixed typo
snicki13 Oct 6, 2021
ec8501d
Better error overlay.
snicki13 Oct 6, 2021
b05a0d9
Logout styled
snicki13 Oct 7, 2021
5f7da20
Simplified full page components for error messages, etc.
snicki13 Oct 7, 2021
08dc8f6
ktlint formatter
snicki13 Oct 7, 2021
2fe8fcf
Ticket-list reworked 30%
snicki13 Oct 7, 2021
d8e2dae
add-ticket icon
snicki13 Oct 7, 2021
c0a8c70
Tickets reworked
snicki13 Oct 8, 2021
ec16db0
UserIconService
snicki13 Oct 8, 2021
2d171ea
Credentials to user
snicki13 Oct 8, 2021
52d1254
Fixed userAvatar in Tickets.
snicki13 Oct 8, 2021
021ed2c
Sidemenues
snicki13 Oct 8, 2021
2488815
Cleanup + BugFix: dead conferences
snicki13 Oct 9, 2021
d563f0b
Fix invitation accuracy.
snicki13 Oct 9, 2021
5ed8492
Better overlay error
snicki13 Oct 10, 2021
77e190f
Login error handling.
snicki13 Oct 10, 2021
3c400b6
Fixed undefined behavior in AuthManager
snicki13 Oct 10, 2021
3b16de3
Choose conference to join.
snicki13 Oct 10, 2021
736dece
Conference visibility preparations.
snicki13 Oct 10, 2021
e4a5fe5
ktlint
snicki13 Oct 10, 2021
348f7c5
Update attendees from BBB server
snicki13 Oct 10, 2021
f1b68cd
missing menu component...
snicki13 Oct 10, 2021
7280e9c
Merge backend code from ui-overhaul
snicki13 Oct 10, 2021
ec71015
clean sender
snicki13 Oct 10, 2021
b688640
Merge branch 'ui-overhaul' into fix/conference-handling
snicki13 Oct 10, 2021
d036334
Small tweaks.
snicki13 Oct 6, 2021
887a317
rename
snicki13 Oct 10, 2021
22b2cd7
Dynamic side panel components.
snicki13 Oct 10, 2021
a80e71c
fix assets
snicki13 Oct 11, 2021
4be6b53
fixed assets and changed routes in backend / frontend. #58?
snicki13 Oct 11, 2021
2e2f166
Update web-gui/src/app/page-components/classroom/classroom.component.ts
snicki13 Oct 12, 2021
fcf9dd0
Updating attendees from BBB backend needs longer delay, since BBB reg…
snicki13 Oct 12, 2021
18908b5
layout change.
snicki13 Oct 12, 2021
bbc709d
Update web-gui/src/index.html
snicki13 Oct 12, 2021
e94353a
Merge remote-tracking branch 'origin/ui-overhaul' into ui-overhaul
snicki13 Oct 12, 2021
79db967
minor fix on example.env
snicki13 Oct 12, 2021
f40e0de
Fixes on docker build process.
snicki13 Oct 12, 2021
fb07341
Fixed some sound problems and centralized asset management.
snicki13 Oct 12, 2021
b84e970
Angular update.
snicki13 Oct 12, 2021
270bb2f
Strict ESLint :')
snicki13 Oct 13, 2021
bc51726
[examples][docker-compose] fix CLASSROOM_HOST
mxsph Oct 13, 2021
d0d06e8
"Fix"
snicki13 Oct 13, 2021
532eeba
Merge remote-tracking branch 'origin/ui-overhaul' into ui-overhaul
snicki13 Oct 13, 2021
d154297
[Dockerfile] Keeping the folder structure while copying frontend files
mxsph Oct 13, 2021
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile

plugins {
id("org.springframework.boot") version "2.4.5"
id("org.springframework.boot") version "2.5.5"
id("io.spring.dependency-management") version "1.0.11.RELEASE"
idea
kotlin("jvm") version "1.4.32"
Expand All @@ -20,7 +20,6 @@ repositories {
}

dependencies {
implementation("com.google.guava:guava:30.1.1-jre")
implementation("org.springframework.boot:spring-boot-starter-webflux")
implementation("org.springframework.security:spring-security-rsocket")
implementation("org.springframework.security:spring-security-messaging")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,13 @@ package de.thm.mni.ii.classroom
import org.springframework.boot.autoconfigure.SpringBootApplication
import org.springframework.boot.context.properties.ConfigurationPropertiesScan
import org.springframework.boot.runApplication
import reactor.core.publisher.Hooks

@SpringBootApplication
@ConfigurationPropertiesScan("de.thm.mni.ii.classroom.properties")
class DigitalClassroomApplication

fun main(args: Array<String>) {
Hooks.onErrorDropped {}
runApplication<DigitalClassroomApplication>(*args)
}
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
package de.thm.mni.ii.classroom.controller

import de.thm.mni.ii.classroom.model.classroom.User
import de.thm.mni.ii.classroom.model.classroom.UserCredentials
import de.thm.mni.ii.classroom.security.exception.UnauthorizedException
import de.thm.mni.ii.classroom.security.jwt.ClassroomAuthentication
import de.thm.mni.ii.classroom.security.jwt.ClassroomJwtService
import de.thm.mni.ii.classroom.security.jwt.ClassroomTokenRepository
import de.thm.mni.ii.classroom.services.ClassroomInstanceService
import de.thm.mni.ii.classroom.util.component1
import de.thm.mni.ii.classroom.util.component2
import org.apache.commons.lang3.RandomStringUtils
Expand All @@ -20,17 +22,17 @@ import org.springframework.web.bind.annotation.ResponseStatus
import org.springframework.web.bind.annotation.RestController
import org.springframework.web.server.ServerWebExchange
import reactor.core.publisher.Mono
import reactor.kotlin.core.publisher.switchIfEmpty

@RestController
@RequestMapping("/classroom-api")
@CrossOrigin
class ClassroomApiController(
val classroomTokenRepository: ClassroomTokenRepository,
val jwtService: ClassroomJwtService
private val classroomTokenRepository: ClassroomTokenRepository,
private val jwtService: ClassroomJwtService,
private val classroomInstanceService: ClassroomInstanceService
) {

private val logger = LoggerFactory.getLogger(this::class.java)
private val logger = LoggerFactory.getLogger(ClassroomApiController::class.java)

/**
* Does not return any value. This route is called with sessionToken, which is exchanged to a JWT
Expand All @@ -40,8 +42,11 @@ class ClassroomApiController(
@GetMapping("/join")
@ResponseStatus(HttpStatus.NO_CONTENT)
fun joinClassroom(auth: ClassroomAuthentication, originalExchange: ServerWebExchange): Mono<ServerHttpResponse> {
return Mono.just(generateRefreshToken(auth.principal))
.map { refreshToken ->
return classroomInstanceService.getClassroomInstance(auth.getClassroomId())
.doOnNext { classroom ->
classroom.savePreAuthUserData(auth.principal as User)
}.map {
val refreshToken = generateRefreshToken(auth.principal)
// Set refresh_token header
val refreshTokenSet = setHeader("refresh_token", refreshToken, originalExchange)
// Set Authorization header
Expand All @@ -60,17 +65,11 @@ class ClassroomApiController(
): Mono<ServerHttpResponse> {
return classroomTokenRepository
.findRefreshToken(refreshToken)
.switchIfEmpty {
val ex = UnauthorizedException("Invalid refresh token provided by user ${auth.user?.fullName}")
logger.error("", ex)
Mono.error(ex)
}.filter { user ->
user == auth.user
}.switchIfEmpty {
val ex = UnauthorizedException("Owner of refresh token does not match requester!")
logger.error("", ex)
Mono.error(ex)
}.map { user ->
.switchIfEmpty(Mono.error(UnauthorizedException("Invalid refresh token provided by user ${auth.userCredentials?.fullName}")))
.filter { user ->
user == auth.userCredentials
}.switchIfEmpty(Mono.error(UnauthorizedException("Owner of refresh token does not match requester!")))
.map { user ->
val newRefreshToken = generateRefreshToken(user)
Pair(user, setHeader("refresh_token", newRefreshToken, originalExchange))
}.flatMap { (user, exchange) ->
Expand All @@ -82,9 +81,9 @@ class ClassroomApiController(
}
}

private fun generateRefreshToken(user: User): String {
private fun generateRefreshToken(userCredentials: UserCredentials): String {
val newRefreshToken = RandomStringUtils.randomAscii(30)
classroomTokenRepository.insertRefreshToken(newRefreshToken, user)
classroomTokenRepository.insertRefreshToken(newRefreshToken, userCredentials)
return newRefreshToken
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ package de.thm.mni.ii.classroom.controller
import de.thm.mni.ii.classroom.event.InvitationEvent
import de.thm.mni.ii.classroom.model.classroom.ConferenceInfo
import de.thm.mni.ii.classroom.model.classroom.JoinLink
import de.thm.mni.ii.classroom.model.classroom.User
import de.thm.mni.ii.classroom.model.classroom.UserCredentials
import de.thm.mni.ii.classroom.services.ConferenceService
import org.springframework.messaging.handler.annotation.MessageMapping
import org.springframework.messaging.handler.annotation.Payload
Expand All @@ -15,32 +15,32 @@ import reactor.core.publisher.Mono
class ConferenceController(private val conferenceService: ConferenceService) {

@MessageMapping("socket/conference/create")
fun createConference(@AuthenticationPrincipal user: User, @Payload conferenceInfo: ConferenceInfo): Mono<ConferenceInfo> {
return conferenceService.createConference(user, conferenceInfo)
fun createConference(@AuthenticationPrincipal userCredentials: UserCredentials, @Payload conferenceInfo: ConferenceInfo): Mono<ConferenceInfo> {
return conferenceService.createConference(userCredentials, conferenceInfo)
}

@MessageMapping("socket/conference/join")
fun joinConference(@AuthenticationPrincipal user: User, @Payload conferenceInfo: ConferenceInfo): Mono<JoinLink> {
return conferenceService.joinConference(user, conferenceInfo)
fun joinConference(@AuthenticationPrincipal userCredentials: UserCredentials, @Payload conferenceInfo: ConferenceInfo): Mono<JoinLink> {
return conferenceService.joinConference(userCredentials, conferenceInfo)
}

@MessageMapping("socket/conference/join-user")
fun joinConferenceOfUser(@AuthenticationPrincipal joiningUser: User, @Payload conferencingUser: User): Mono<JoinLink> {
return conferenceService.joinConferenceOfUser(joiningUser, conferencingUser)
fun joinConferenceOfUser(@AuthenticationPrincipal joiningUserCredentials: UserCredentials, @Payload conferencingUserCredentials: UserCredentials): Mono<JoinLink> {
return conferenceService.joinConferenceOfUser(joiningUserCredentials, conferencingUserCredentials)
}

@MessageMapping("socket/conference/leave")
fun leaveConference(@AuthenticationPrincipal user: User, @Payload conferenceInfo: ConferenceInfo): Mono<Void> {
return conferenceService.leaveConference(user, conferenceInfo)
fun leaveConference(@AuthenticationPrincipal userCredentials: UserCredentials, @Payload conferenceInfo: ConferenceInfo): Mono<Void> {
return conferenceService.leaveConference(userCredentials, conferenceInfo)
}

@MessageMapping("socket/conference/end")
fun endConference(@AuthenticationPrincipal user: User, @Payload conferenceInfo: ConferenceInfo): Mono<Void> {
fun endConference(@AuthenticationPrincipal userCredentials: UserCredentials, @Payload conferenceInfo: ConferenceInfo): Mono<Void> {
TODO("NOT YET IMPLEMENTED")
}

@MessageMapping("socket/conference/invite")
fun inviteToConference(@AuthenticationPrincipal user: User, @Payload invitationEvent: InvitationEvent): Mono<Void> {
return conferenceService.forwardInvitation(user, invitationEvent)
fun inviteToConference(@AuthenticationPrincipal userCredentials: UserCredentials, @Payload invitationEvent: InvitationEvent): Mono<Void> {
return conferenceService.forwardInvitation(userCredentials, invitationEvent)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import de.thm.mni.ii.classroom.model.classroom.ClassroomInfo
import de.thm.mni.ii.classroom.model.classroom.ConferenceInfo
import de.thm.mni.ii.classroom.model.classroom.Ticket
import de.thm.mni.ii.classroom.model.classroom.User
import de.thm.mni.ii.classroom.model.classroom.UserDisplay
import de.thm.mni.ii.classroom.model.classroom.UserCredentials
import de.thm.mni.ii.classroom.services.ClassroomEventReceiverService
import de.thm.mni.ii.classroom.services.ClassroomUserService
import org.springframework.messaging.handler.annotation.MessageMapping
Expand All @@ -23,32 +23,32 @@ class UserWebSocketController(
private val classroomEventReceiverService: ClassroomEventReceiverService
) {
@ConnectMapping
fun connect(@AuthenticationPrincipal user: User, requester: RSocketRequester): Mono<Void> {
return userService.userConnected(user, requester)
fun connect(@AuthenticationPrincipal userCredentials: UserCredentials, requester: RSocketRequester): Mono<Void> {
return userService.userConnected(userCredentials, requester)
}

@MessageMapping("socket/classroom-event")
fun receiveEvent(@AuthenticationPrincipal user: User, @Payload event: ClassroomEvent) {
classroomEventReceiverService.classroomEventReceived(user, event)
fun receiveEvent(@AuthenticationPrincipal userCredentials: UserCredentials, @Payload event: ClassroomEvent) {
classroomEventReceiverService.classroomEventReceived(userCredentials, event)
}

@MessageMapping("socket/init-classroom")
fun initClassroom(@AuthenticationPrincipal user: User): Mono<ClassroomInfo> {
return userService.getClassroomInfo(user)
fun initClassroom(@AuthenticationPrincipal userCredentials: UserCredentials): Mono<ClassroomInfo> {
return userService.getClassroomInfo(userCredentials)
}

@MessageMapping("socket/init-tickets")
fun initTickets(@AuthenticationPrincipal user: User): Flux<Ticket> {
return userService.getTickets(user)
fun initTickets(@AuthenticationPrincipal userCredentials: UserCredentials): Flux<Ticket> {
return userService.getTickets(userCredentials)
}

@MessageMapping("socket/init-users")
fun initUsers(@AuthenticationPrincipal user: User): Flux<UserDisplay> {
return userService.getUserDisplays(user)
fun initUsers(@AuthenticationPrincipal userCredentials: UserCredentials): Flux<User> {
return userService.getUserDisplays(userCredentials)
}

@MessageMapping("socket/init-conferences")
fun initConferences(@AuthenticationPrincipal user: User): Flux<ConferenceInfo> {
return userService.getConferences(user)
fun initConferences(@AuthenticationPrincipal userCredentials: UserCredentials): Flux<ConferenceInfo> {
return userService.getConferences(userCredentials)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ data class ConferenceEvent(
enum class ConferenceAction {
CREATE,
CLOSE,
PUBLISH,
HIDE,
VISIBILITY,
USER_CHANGE
}
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
package de.thm.mni.ii.classroom.event

import de.thm.mni.ii.classroom.model.classroom.ConferenceInfo
import de.thm.mni.ii.classroom.model.classroom.User
import de.thm.mni.ii.classroom.model.classroom.UserCredentials

data class InvitationEvent(
val inviter: User,
val invitee: User,
val inviter: UserCredentials,
val invitee: UserCredentials,
val conferenceInfo: ConferenceInfo
) : ClassroomEvent(InvitationEvent::class.simpleName!!)
4 changes: 2 additions & 2 deletions src/main/kotlin/de/thm/mni/ii/classroom/event/UserEvent.kt
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
package de.thm.mni.ii.classroom.event

import de.thm.mni.ii.classroom.model.classroom.UserDisplay
import de.thm.mni.ii.classroom.model.classroom.User

data class UserEvent(
val user: UserDisplay,
val user: User,
val userAction: UserAction
) : ClassroomEvent(UserEvent::class.simpleName!!)

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package de.thm.mni.ii.classroom.exception.classroom

import de.thm.mni.ii.classroom.event.InvitationEvent
import de.thm.mni.ii.classroom.model.classroom.User
import de.thm.mni.ii.classroom.model.classroom.UserCredentials

class InvitationException(user: User, invitationEvent: InvitationEvent) :
ClassroomException("Sender ${user.userId} does not match inviter ${invitationEvent.inviter.userId}!")
class InvitationException(userCredentials: UserCredentials, invitationEvent: InvitationEvent) :
ClassroomException("Sender ${userCredentials.userId} does not match inviter ${invitationEvent.inviter.userId}!")
24 changes: 12 additions & 12 deletions src/main/kotlin/de/thm/mni/ii/classroom/model/api/Attendees.kt
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
package de.thm.mni.ii.classroom.model.api

import de.thm.mni.ii.classroom.model.classroom.User
import de.thm.mni.ii.classroom.model.classroom.UserCredentials
import javax.xml.bind.annotation.XmlElement
import javax.xml.bind.annotation.XmlRootElement
import javax.xml.bind.annotation.XmlType

@XmlRootElement(name = "attendees")
class Attendees(users: Set<User>? = null) {
class Attendees(userCredentials: Set<UserCredentials>? = null) {

@Suppress("unused")
@XmlElement(name = "attendee")
private val attendees = users?.map(::Attendee)
val attendees = userCredentials?.mapTo(HashSet(), ::Attendee)
}

@XmlType(
Expand All @@ -28,13 +28,13 @@ class Attendees(users: Set<User>? = null) {
)

@Suppress("unused")
class Attendee(user: User? = null) {
@XmlElement private val userID: String? = user?.userId
@XmlElement private val fullName: String? = user?.fullName
@XmlElement private val role: String? = user?.userRole?.name
@XmlElement private val isPresenter = false
@XmlElement private val isListeningOnly = true
@XmlElement private val hasJoinedVoice = false
@XmlElement private val hasVideo = false
@XmlElement private val clientType = "CLASSROOM"
class Attendee(userCredentials: UserCredentials? = null) {
@XmlElement val userID: String? = userCredentials?.userId
@XmlElement val fullName: String? = userCredentials?.fullName
@XmlElement val role: String? = userCredentials?.userRole?.name
@XmlElement val isPresenter = false
@XmlElement val isListeningOnly = true
@XmlElement val hasJoinedVoice = false
@XmlElement val hasVideo = false
@XmlElement val clientType = "CLASSROOM"
}
Loading