package com.andr3h3nriqu3s.applications import java.sql.ResultSet import java.util.UUID import org.springframework.http.MediaType import org.springframework.http.HttpStatus import org.springframework.jdbc.core.JdbcTemplate import org.springframework.jdbc.core.RowMapper import org.springframework.stereotype.Service import org.springframework.web.bind.annotation.ControllerAdvice import org.springframework.web.bind.annotation.DeleteMapping import org.springframework.web.bind.annotation.GetMapping import org.springframework.web.bind.annotation.PathVariable import org.springframework.web.bind.annotation.PutMapping import org.springframework.web.bind.annotation.RequestBody import org.springframework.web.bind.annotation.RequestHeader import org.springframework.web.bind.annotation.RequestMapping import org.springframework.web.bind.annotation.RestController import org.springframework.web.server.ResponseStatusException data class CreateFlair( var color: String, var name: String, var expr: String, var description: String? ) @RestController @ControllerAdvice @RequestMapping("/api/flair") class FlairController( val sessionService: SessionService, val flairService: FlairService, val applicationService: ApplicationService ) { @PutMapping(path = ["/"], produces = [MediaType.APPLICATION_JSON_VALUE]) public fun create( @RequestBody flair: CreateFlair, @RequestHeader("token") token: String ): Flair { val user = sessionService.verifyTokenThrow(token) return flairService.createFlair(user, flair) } @PutMapping(path = ["/update"], produces = [MediaType.APPLICATION_JSON_VALUE]) public fun create(@RequestBody flair: Flair, @RequestHeader("token") token: String): Flair { val user = sessionService.verifyTokenThrow(token) var old_flair = flairService.getById(user, flair.id) if (old_flair == null) { throw NotFound() } if (old_flair.user_id != user.id) { throw NotAuth() } flair.user_id = old_flair.user_id return flairService.updateFlair(flair) } @GetMapping(path = ["/"], produces = [MediaType.APPLICATION_JSON_VALUE]) public fun list(@RequestHeader("token") token: String): List { val user = sessionService.verifyTokenThrow(token) return flairService.listUser(user) } @GetMapping(path = ["/simple/{id}"], produces = [MediaType.APPLICATION_JSON_VALUE]) public fun listSimple(@PathVariable id: String): List { var application = applicationService.findApplicationByIdNoUser(id) if (application == null) { throw ResponseStatusException(HttpStatus.NOT_FOUND, "Application Not Found", null) } return flairService.listUserId(application.user_id).map { it.toFlairSimple() } } @DeleteMapping(path = ["/{id}"], produces = [MediaType.APPLICATION_JSON_VALUE]) public fun delete(@PathVariable id: String, @RequestHeader("token") token: String): Flair { val user = sessionService.verifyTokenThrow(token) return flairService.deleteById(user, id) } } data class SimpleFlair( val name: String, val description: String, val color: String, ) data class Flair( var id: String, var user_id: String, var color: String, var name: String, var expr: String, var description: String, ) { companion object : RowMapper { override public fun mapRow(rs: ResultSet, rowNum: Int): Flair { return Flair( rs.getString("id"), rs.getString("user_id"), rs.getString("color"), rs.getString("name"), rs.getString("expr"), rs.getString("description"), ) } } fun toFlairSimple(): SimpleFlair { return SimpleFlair(this.name, this.description, this.color) } } data class FlairLink(var id: String, var application_id: String, var flair_id: String) @Service public class FlairService(val db: JdbcTemplate) { public fun linkFlair(application: Application, flair: Flair): FlairLink { val links = db.query( "select * from flair_link where application_id=? and flair_id=?", arrayOf(application.id, flair.id) ) { request, _ -> FlairLink( request.getString("id"), request.getString("application_id"), request.getString("flair_id") ) } if (links.size > 0) { return links[0] } val link = FlairLink(UUID.randomUUID().toString(), application.id, flair.id) db.update( "insert into flair_link (id, application_id, flair_id) values (?, ?, ?)", link.id, link.application_id, link.flair_id ) return link } public fun unlinkFlair(applicationId: String, flairId: String) { db.update( "delete from flair_link where flair_id=? and application_id=?", flairId, applicationId, ) } public fun listFromLinkApplicationId(id: String): List = db.query( "select f.id, f.user_id, f.color, f.name, f.expr, f.description from flair_link as fl inner join flair as f on f.id = fl.flair_id where application_id=? order by name asc;", arrayOf(id), Flair ) .toList() public fun listUser(user: UserDb): List = db.query( "select * from flair where user_id=? order by name asc;", arrayOf(user.id), Flair ) .toList() public fun listUserId(id: String): List = db.query( "select * from flair where user_id=? and description != '' order by name asc;", arrayOf(id), Flair ) .toList() public fun getById(user: UserDb, id: String): Flair? { val items = db.query( "select * from flair where user_id=? and id=?;", arrayOf(user.id, id), Flair ) .toList() if (items.size == 0) { return null } return items[0] } public fun deleteById(user: UserDb, id: String): Flair { val flair = this.getById(user, id) if (flair == null) { throw NotFound() } db.update("delete from flair where id=?", id) return flair } public fun updateFlair(flair: Flair): Flair { db.update( "update flair set user_id=?, color=?, name=?, expr=?, description=? where id=?;", flair.user_id, flair.color, flair.name, flair.expr, flair.description, flair.id, ) return flair } public fun createFlair(user: UserDb, flair: CreateFlair): Flair { val id = UUID.randomUUID().toString() var description = "" if (flair.description != null) { description = flair.description!! } var new_flair = Flair(id, user.id, flair.color, flair.name, flair.expr, description) db.update( "insert into flair (id, user_id, color, name, expr, description) values (?, ?, ?, ?, ?, ?)", new_flair.id, new_flair.user_id, new_flair.color, new_flair.name, new_flair.expr, new_flair.description ) return new_flair } }