From 876a9a37a31e7a8d3bdfe9909c04e21c60ce90ed Mon Sep 17 00:00:00 2001 From: kraktus Date: Sat, 23 Oct 2021 17:29:33 +0200 Subject: [PATCH] Edit swiss via the API closes https://github.com/ornicar/lila/issues/9862 TODO: update documentation --- app/controllers/Swiss.scala | 32 ++++++++++++++++++++++----- conf/routes | 1 + modules/swiss/src/main/SwissApi.scala | 7 +++--- 3 files changed, 32 insertions(+), 8 deletions(-) diff --git a/app/controllers/Swiss.scala b/app/controllers/Swiss.scala index 4f6da0544a..ef29709598 100644 --- a/app/controllers/Swiss.scala +++ b/app/controllers/Swiss.scala @@ -213,7 +213,25 @@ final class Swiss( .bindFromRequest() .fold( err => BadRequest(html.swiss.form.edit(swiss, err)).fuccess, - data => env.swiss.api.update(swiss, data) inject Redirect(routes.Swiss.show(id)) + data => env.swiss.api.update(swiss.id, data) inject Redirect(routes.Swiss.show(id)) + ) + } + } + + def apiUpdate(id: String) = + ScopedBody(_.Tournament.Write) { implicit req => me => + implicit val lang = reqLang + WithEditableSwiss( + id, + me, + _ => Unauthorized(Json.obj("error" -> "This user cannot edit this swiss")).fuccess + ) { swiss => + env.swiss.forms + .edit(me, swiss) + .bindFromRequest() + .fold( + newJsonFormError, + data => JsonOk { env.swiss.api.update(swiss.id, data) map (_.map(env.swiss.json.api)) } ) } } @@ -295,13 +313,17 @@ final class Swiss( private def WithSwiss(id: String)(f: SwissModel => Fu[Result]): Fu[Result] = env.swiss.api.byId(SwissId(id)) flatMap { _ ?? f } - private def WithEditableSwiss(id: String, me: lila.user.User)( + private def WithEditableSwiss( + id: String, + me: lila.user.User, + fallback: SwissModel => Fu[Result] = swiss => Redirect(routes.Swiss.show(swiss.id.value)).fuccess + )( f: SwissModel => Fu[Result] - )(implicit ctx: Context): Fu[Result] = + ): Fu[Result] = WithSwiss(id) { swiss => if (swiss.createdBy == me.id && !swiss.isFinished) f(swiss) - else if (isGranted(_.ManageTournament)) f(swiss) - else Redirect(routes.Swiss.show(swiss.id.value)).fuccess + else if (isGranted(_.ManageTournament, me)) f(swiss) + else fallback(swiss) } private def canHaveChat(swiss: SwissModel)(implicit ctx: Context): Fu[Boolean] = diff --git a/conf/routes b/conf/routes index 8c83be1214..ec484a1c0b 100644 --- a/conf/routes +++ b/conf/routes @@ -663,6 +663,7 @@ POST /api/tournament/:id/join controllers.Tournament.apiJoin(id: String POST /api/tournament/:id/terminate controllers.Tournament.apiTerminate(id: String) POST /api/tournament/team-battle/:id controllers.Tournament.apiTeamBattleUpdate(id: String) POST /api/swiss/new/:teamId controllers.Swiss.apiCreate(teamId: String) +POST /api/swiss/:id/edit controllers.Swiss.apiUpdate(id: String) POST /api/swiss/:id/join controllers.Swiss.apiJoin(id: String) POST /api/swiss/:id/terminate controllers.Swiss.apiTerminate(id: String) GET /api/swiss/:id/games controllers.Api.swissGames(id: String) diff --git a/modules/swiss/src/main/SwissApi.scala b/modules/swiss/src/main/SwissApi.scala index c5303f2357..fc3620dea6 100644 --- a/modules/swiss/src/main/SwissApi.scala +++ b/modules/swiss/src/main/SwissApi.scala @@ -85,8 +85,8 @@ final class SwissApi( cache.featuredInTeam.invalidate(swiss.teamId) inject swiss } - def update(swiss: Swiss, data: SwissForm.SwissData): Funit = - Sequencing(swiss.id)(byId) { old => + def update(swissId: Swiss.Id, data: SwissForm.SwissData): Fu[Option[Swiss]] = + Sequencing(swissId)(byId) { old => val position = if (old.isCreated || old.settings.position.isDefined) data.realVariant.standard ?? data.realPosition else old.settings.position @@ -121,9 +121,10 @@ final class SwissApi( s.copy(nextRoundAt = none) else s } - colls.swiss.update.one($id(old.id), addFeaturable(swiss)).void >>- { + colls.swiss.update.one($id(old.id), addFeaturable(swiss)).void >> { cache.roundInfo.put(swiss.id, fuccess(swiss.roundInfo.some)) socket.reload(swiss.id) + fuccess(swiss.some) } }