From ea71d3825e08377470138f54d08dc03d17d4df32 Mon Sep 17 00:00:00 2001 From: Juan Rodriguez Date: Wed, 31 Jul 2024 22:07:57 +0200 Subject: [PATCH] fix: generate slug by user + check existing link on update --- app/controllers/link.cr | 15 +++++++++++++-- app/services/slug.cr | 5 +++-- spec/spec_helper.cr | 2 +- 3 files changed, 17 insertions(+), 5 deletions(-) diff --git a/app/controllers/link.cr b/app/controllers/link.cr index 17eb987..6a84c22 100644 --- a/app/controllers/link.cr +++ b/app/controllers/link.cr @@ -27,7 +27,7 @@ module App::Controllers::Link link.id = UUID.v4.to_s link.url = url link.user = user - link.slug = SlugService.shorten_url(url) + link.slug = SlugService.shorten_url(url, user.id.to_s) changeset = Database.insert(link) if !changeset.valid? @@ -118,6 +118,7 @@ module App::Controllers::Link class Update < App::Lib::BaseController include App::Models include App::Lib + include App::Services def call(env) user = env.get("user").as(User) @@ -130,7 +131,17 @@ module App::Controllers::Link raise App::NotFoundException.new(env) if link.nil? raise App::ForbiddenException.new(env) if link.user_id != user.id - link.url = body["url"].to_s + new_url = body["url"].to_s + + existing_query = Database::Query.where(url: new_url, user_id: user.id.to_s).limit(1) + existing_link = Database.all(Link, existing_query).first? + + if existing_link + raise App::UnprocessableEntityException.new(env, { "url" => ["URL already exists"] }) + end + + link.url = new_url + link.slug = SlugService.shorten_url(new_url, user.id.to_s) changeset = Database.update(link) if !changeset.valid? diff --git a/app/services/slug.cr b/app/services/slug.cr index 0352cf7..4a89ecb 100644 --- a/app/services/slug.cr +++ b/app/services/slug.cr @@ -2,8 +2,9 @@ require "digest" require "base64" module App::Services::SlugService - def self.shorten_url(url : String) : String - crc32_hash = Digest::CRC32.digest(url) + def self.shorten_url(url : String, user_id : String) : String + combined = "#{user_id}-#{url}" + crc32_hash = Digest::CRC32.digest(combined) base62_encoded = Base64.urlsafe_encode(crc32_hash).strip.tr("-_=", "") base62_encoded diff --git a/spec/spec_helper.cr b/spec/spec_helper.cr index 9adf39d..961ec4d 100644 --- a/spec/spec_helper.cr +++ b/spec/spec_helper.cr @@ -40,7 +40,7 @@ end def create_test_link(user, url) link = App::Models::Link.new link.id = UUID.v4.to_s - link.slug = App::Services::SlugService.shorten_url(url) + link.slug = App::Services::SlugService.shorten_url(url, user.id.to_s) link.url = url link.user = user