Skip to content
Open
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
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added .DS_Store
Binary file not shown.
1 change: 1 addition & 0 deletions build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -86,4 +86,5 @@ dependencies {
runtimeOnly("org.postgresql:postgresql:42.3.6")
implementation("com.google.code.gson:gson:2.9.1")
implementation("aws.sdk.kotlin:s3:0.17.5-beta")
implementation("org.simplejavamail:simple-java-mail:7.5.0")
}
Binary file added src/.DS_Store
Binary file not shown.
Binary file added src/main/.DS_Store
Binary file not shown.
12 changes: 11 additions & 1 deletion src/main/kotlin/com/example/Application.kt
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import com.example.plugins.configureHikariDataSource
import com.example.plugins.configureRouting
import com.example.plugins.configureSecurity
import com.example.plugins.performDBMigration
import com.example.routes.mailSender.SmtpMailClient
import com.fasterxml.jackson.databind.ObjectMapper
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule
import io.ktor.http.ContentType
Expand All @@ -24,6 +25,10 @@ const val ENV_GITHUB_CLIENT_ID = "GITHUB_CLIENT_ID"
const val ENV_GITHUB_CLIENT_SECRET = "GITHUB_CLIENT_SECRET"
const val ENV_CLIENT_URL = "CLIENT_URL"
const val ENV_DATA_BUCKET_NAME = "DATA_BUCKET_NAME"
const val ENV_EMAIL = "EMAIL"
const val ENV_EMAIL_PASSWORD = "EMAIL_PASSWORD"
const val ENV_EMAIL_HOST = "EMAIL_HOST"
const val ENV_EMAIL_PORT = "EMAIL_PORT"

fun configureGithubClient(
clientId: String = System.getenv(ENV_GITHUB_CLIENT_ID),
Expand All @@ -43,6 +48,10 @@ fun main() {
val context = DSL.using(datasource, SQLDialect.POSTGRES)
val clientUrl = System.getenv(ENV_CLIENT_URL)
val dataBucketName = System.getenv(ENV_DATA_BUCKET_NAME)
val smtpEmail = System.getenv(ENV_EMAIL)
val smtpPassword = System.getenv(ENV_EMAIL_PASSWORD)
val smtpHost = System.getenv(ENV_EMAIL_HOST)
val smtpPort = System.getenv(ENV_EMAIL_PORT).toInt()
performDBMigration(datasource)

configureSecurity(context)
Expand All @@ -51,7 +60,8 @@ fun main() {
context,
configureGithubClient(),
clientUrl,
dataBucketName
dataBucketName,
SmtpMailClient(smtpHost,smtpPort,smtpEmail,smtpPassword)
)

install(ContentNegotiation) {
Expand Down
7 changes: 5 additions & 2 deletions src/main/kotlin/com/example/plugins/Routing.kt
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ import com.example.routes.badges.badge
import com.example.routes.dataBucket.dataBucket
import com.example.routes.githubEvents.githubEvents
import com.example.routes.leaderboard.leaderboard
import com.example.routes.mailSender.MailClient
import com.example.routes.mailSender.SmtpMailClient
import com.example.routes.pullRequests.pullRequests
import com.example.routes.session.session
import com.example.routes.sprints.sprints
Expand Down Expand Up @@ -69,15 +71,16 @@ fun Application.configureRouting(
context: DSLContext? = null,
githubClient: GithubClient? = null,
clientUrl: String? = null,
dataBucketName: String? = null
dataBucketName: String? = null,
mailClient: SmtpMailClient? = null
) {
routing {
oidc(context!!, githubClient!!, clientUrl!!)
session()
user(context)
githubEvents(context)
tasks(context)
sprints(context)
sprints(context, mailClient!!)
leaderboard(context)
badge(context)
dataBucket(dataBucketName!!)
Expand Down
21 changes: 21 additions & 0 deletions src/main/kotlin/com/example/routes/mailSender/EmailDto.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package com.example.routes.mailSender

import java.time.OffsetDateTime


open class PartialEmailDto(
open val subject: String,
open val emailAddresses: String,
open val htmlBody: String
)

class EmailDto(
subject: String,
emailAddresses: String,
htmlBody: String,
val createdAt: OffsetDateTime,
): PartialEmailDto(
subject,
emailAddresses,
htmlBody
)
7 changes: 7 additions & 0 deletions src/main/kotlin/com/example/routes/mailSender/MailClient.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package com.example.routes.mailSender

import java.util.concurrent.CompletableFuture

interface MailClient {
fun sendEmail (emailDto: EmailDto): CompletableFuture<Void>
}
27 changes: 27 additions & 0 deletions src/main/kotlin/com/example/routes/mailSender/SmtpMailClient.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package com.example.routes.mailSender

import org.simplejavamail.api.mailer.Mailer
import org.simplejavamail.email.EmailBuilder
import org.simplejavamail.mailer.MailerBuilder
import java.util.concurrent.CompletableFuture


class SmtpMailClient(
private val host: String,
private val port: Int,
private val username: String,
private val password: String,
) : MailClient {

private val mailer: Mailer = MailerBuilder.withSMTPServer(host, port, username, password).buildMailer()

override fun sendEmail(emailDto: EmailDto): CompletableFuture<Void> {
val email = EmailBuilder.startingBlank()
.from(username)
.to(emailDto.emailAddresses)
.withSubject(emailDto.subject)
.withHTMLText(emailDto.htmlBody)
.buildEmail()
return mailer.sendMail(email)
}
}
42 changes: 38 additions & 4 deletions src/main/kotlin/com/example/routes/sprints/sprintRouter.kt
Original file line number Diff line number Diff line change
@@ -1,11 +1,16 @@
package com.example.routes.sprints

import aws.smithy.kotlin.runtime.http.response.dumpResponse
import com.example.plugins.UserPrinciple
import com.example.routes.mailSender.EmailDto
import com.example.routes.mailSender.SmtpMailClient
import com.example.routes.tasks.DevTaskDetails
import com.example.routes.tasks.QuizAnswerPayload
import com.example.routes.tasks.toDto
import com.wehuddle.db.enums.IssueState
import com.wehuddle.db.enums.TaskType
import com.wehuddle.db.enums.UserRole
import com.wehuddle.db.tables.Issue
import com.wehuddle.db.tables.Sprint
import com.wehuddle.db.tables.SprintIssue
import com.wehuddle.db.tables.*
import io.ktor.http.HttpStatusCode
import io.ktor.server.application.call
import io.ktor.server.auth.authenticate
Expand All @@ -19,8 +24,11 @@ import org.jooq.DSLContext

private val SPRINT = Sprint.SPRINT
private val ISSUE = Issue.ISSUE
private val PROFILE = Profile.PROFILE
private val ISSUE_ASSIGNMENT = IssueAssignment.ISSUE_ASSIGNMENT
private val SPRINT_ISSUE = SprintIssue.SPRINT_ISSUE

fun Route.sprints(context: DSLContext) {
fun Route.sprints(context: DSLContext, mailClient: SmtpMailClient) {
authenticate {
route("/sprints") {
post {
Expand Down Expand Up @@ -54,6 +62,32 @@ fun Route.sprints(context: DSLContext) {
}

route("/{sprintId}") {
route("/send-reminder") {
post {
val userPrinciple = call.principal<UserPrinciple>()!!
if (userPrinciple.profile.role != UserRole.HUDDLE_AGENT) {
call.respond(HttpStatusCode.Forbidden)
return@post
}

val sprint = call.receive<SprintDto>()
val emailAddresses = context
.select(PROFILE.EMAIL)
.from(PROFILE)
.join(ISSUE_ASSIGNMENT)
.on(PROFILE.ID.eq(ISSUE_ASSIGNMENT.PROFILE_ID))
.join(SPRINT_ISSUE)
.on(SPRINT_ISSUE.SPRINT_ID.eq(sprint.id))
.fetch(PROFILE.EMAIL)
.toList()
println(emailAddresses)
emailAddresses.forEach(){ email ->
val emailToSend = EmailDto(sprint.title, email, sprint.description, OffsetDateTime.now())
mailClient.sendEmail(emailToSend)
}
}
}

get {
val sprintId = UUID.fromString(call.parameters["sprintId"]!!)
val existingSprint = context.fetchOne(
Expand Down
Binary file added src/main/resources/.DS_Store
Binary file not shown.
Binary file added src/main/resources/migrations/.DS_Store
Binary file not shown.