From c704a2178733c88f5fb85df23916e1eff0b4a282 Mon Sep 17 00:00:00 2001 From: Joseph Ferano Date: Wed, 20 Jul 2022 17:35:38 +0700 Subject: [PATCH 01/14] Creating Currency API endpoint --- Bot/paket.references | 4 +- CurrencyAPI/Currency.fs | 118 +++++++++++++++++++++++++++++++++ CurrencyAPI/CurrencyAPI.fsproj | 19 ++++++ CurrencyAPI/paket.references | 5 ++ CurrencyAPI/web.config | 9 +++ DegenzGame.sln | 6 ++ paket.dependencies | 5 +- paket.lock | 48 +++++--------- 8 files changed, 181 insertions(+), 33 deletions(-) create mode 100644 CurrencyAPI/Currency.fs create mode 100644 CurrencyAPI/CurrencyAPI.fsproj create mode 100644 CurrencyAPI/paket.references create mode 100644 CurrencyAPI/web.config diff --git a/Bot/paket.references b/Bot/paket.references index 018add7..4b4a306 100644 --- a/Bot/paket.references +++ b/Bot/paket.references @@ -2,9 +2,11 @@ FSharp.Core DSharpPlus DSharpPlus.Interactivity DSharpPlus.SlashCommands +FSharp.Core dotenv.net Npgsql.FSharp mixpanel-csharp Solnet.Rpc FsToolkit.ErrorHandling -FSharp.Data \ No newline at end of file +FSharp.Data +Newtonsoft.Json \ No newline at end of file diff --git a/CurrencyAPI/Currency.fs b/CurrencyAPI/Currency.fs new file mode 100644 index 0000000..779ebf9 --- /dev/null +++ b/CurrencyAPI/Currency.fs @@ -0,0 +1,118 @@ +module CurrencyAPI.App + +open System +open System.IO +open Microsoft.AspNetCore.Builder +open Microsoft.AspNetCore.Hosting +open Microsoft.AspNetCore.Http +open Microsoft.Extensions.Hosting +open Microsoft.Extensions.Logging +open Microsoft.Extensions.DependencyInjection +open Giraffe +open dotenv.net +open Npgsql.FSharp + +let prodEnv = DotEnv.Read(DotEnvOptions(envFilePaths = [ "../.prod.env"], overwriteExistingVars = false)) + +let ( _ , connStr ) = prodEnv.TryGetValue("DATABASE_URL") +let ( _ , apiKey ) = prodEnv.TryGetValue("API_KEY") + +let validateApiKey (ctx : HttpContext) = + match ctx.TryGetRequestHeader "X-API-Key" with + | Some key -> apiKey.Equals key + | None -> false + +let accessDenied = setStatusCode 401 >=> text "Access Denied" +let requiresApiKey = authorizeRequest validateApiKey accessDenied + +let getCurrentBalance (discordId : string) = + task { + let! amounts = + connStr + |> Sql.connect + |> Sql.parameters [ "did" , Sql.string discordId ] + |> Sql.query """SELECT gbt FROM "user" WHERE discord_id = @did""" + |> Sql.executeAsync (fun r -> r.int "gbt") + match amounts with + | [] -> return Error "User not found" + | a::_ -> return Ok a + } + +let get (discordId : string) : HttpHandler = + fun (next : HttpFunc) (ctx : HttpContext) -> + task { + try + match! getCurrentBalance discordId with + | Ok amount -> return! json {| Amount = amount |} next ctx + | Error e -> return! RequestErrors.notFound (json {| Error = e |}) next ctx + with ex -> + return! ServerErrors.internalError (json {| Error = ex.Message |}) next ctx + } + +let modify sign (discordId : string) : HttpHandler = + fun (next : HttpFunc) (ctx : HttpContext) -> + task { + let! body = ctx.BindJsonAsync<{|Amount:int|}>() + match! getCurrentBalance discordId with + | Ok current -> + let amount = body.Amount * sign + if current + amount < 0 then + return! RequestErrors.badRequest (json {| Error = "Insufficient funds" |}) next ctx + else + try + let! _ = + connStr + |> Sql.connect + |> Sql.parameters [ "did" , Sql.string discordId ; "amount" , Sql.int amount ] + |> Sql.query """UPDATE "user" SET gbt = GREATEST(gbt + @amount, 0) WHERE discord_id = @did""" + |> Sql.executeNonQueryAsync + return! json {| NewBalance = current + amount |} next ctx + with ex -> return! RequestErrors.notFound (json {| Error = ex.Message |}) next ctx + | Error e -> return! RequestErrors.notFound (json {| Error = e |}) next ctx + } + +let webApp = + choose [ + GET >=> requiresApiKey >=> routef "/user/%s/balance" get + PATCH >=> requiresApiKey >=> routef "/user/%s/balance/withdraw" (modify -1) + PATCH >=> requiresApiKey >=> routef "/user/%s/balance/deposit" (modify +1) + RequestErrors.NOT_FOUND "Not Found" ] + +let errorHandler (ex : Exception) (logger : ILogger) = + logger.LogError(ex, "An unhandled exception has occurred while executing the request.") + clearResponse >=> setStatusCode 500 >=> text ex.Message + +let configureApp (app : IApplicationBuilder) = + let env = app.ApplicationServices.GetService() + if env.IsDevelopment() then + app.UseDeveloperExceptionPage() + else + app.UseGiraffeErrorHandler(errorHandler) + |> ignore + app.UseGiraffe(webApp) + +let configureServices (services : IServiceCollection) = + services.AddGiraffe() |> ignore + +let configureLogging (builder : ILoggingBuilder) = + builder.AddConsole() + .AddDebug() |> ignore + +[] +let main args = + let contentRoot = Directory.GetCurrentDirectory() + let webRoot = Path.Combine(contentRoot, "WebRoot") + Host.CreateDefaultBuilder(args) + .ConfigureWebHostDefaults( + fun webHostBuilder -> + webHostBuilder + .UseContentRoot(contentRoot) + .UseWebRoot(webRoot) + .ConfigureKestrel(fun opt -> opt.AddServerHeader <- false) + .Configure(Action configureApp) + .ConfigureServices(configureServices) + .ConfigureLogging(configureLogging) + |> ignore) + .Build() + .Run() + 0 \ No newline at end of file diff --git a/CurrencyAPI/CurrencyAPI.fsproj b/CurrencyAPI/CurrencyAPI.fsproj new file mode 100644 index 0000000..bbd3e99 --- /dev/null +++ b/CurrencyAPI/CurrencyAPI.fsproj @@ -0,0 +1,19 @@ + + + + net6.0 + CurrencyAPI.App + false + true + + + + + + + + PreserveNewest + + + + \ No newline at end of file diff --git a/CurrencyAPI/paket.references b/CurrencyAPI/paket.references new file mode 100644 index 0000000..054c675 --- /dev/null +++ b/CurrencyAPI/paket.references @@ -0,0 +1,5 @@ +FSharp.Data +FSharp.Core +dotenv.net +Npgsql.FSharp +Giraffe diff --git a/CurrencyAPI/web.config b/CurrencyAPI/web.config new file mode 100644 index 0000000..f81ac42 --- /dev/null +++ b/CurrencyAPI/web.config @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/DegenzGame.sln b/DegenzGame.sln index 4f1c150..115934b 100644 --- a/DegenzGame.sln +++ b/DegenzGame.sln @@ -5,6 +5,8 @@ VisualStudioVersion = 16.0.30114.105 MinimumVisualStudioVersion = 10.0.40219.1 Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "Bot", "Bot\Bot.fsproj", "{FF9E58A6-1A1D-4DEC-B52D-265F215BF315}" EndProject +Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "CurrencyAPI", "CurrencyAPI\CurrencyAPI.fsproj", "{AFA1A9F3-625E-44CA-83DA-A50756D119B5}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -22,5 +24,9 @@ Global {44151B85-0D17-4270-AD72-490A6D8D6290}.Debug|Any CPU.Build.0 = Debug|Any CPU {44151B85-0D17-4270-AD72-490A6D8D6290}.Release|Any CPU.ActiveCfg = Release|Any CPU {44151B85-0D17-4270-AD72-490A6D8D6290}.Release|Any CPU.Build.0 = Release|Any CPU + {AFA1A9F3-625E-44CA-83DA-A50756D119B5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {AFA1A9F3-625E-44CA-83DA-A50756D119B5}.Debug|Any CPU.Build.0 = Debug|Any CPU + {AFA1A9F3-625E-44CA-83DA-A50756D119B5}.Release|Any CPU.ActiveCfg = Release|Any CPU + {AFA1A9F3-625E-44CA-83DA-A50756D119B5}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection EndGlobal diff --git a/paket.dependencies b/paket.dependencies index 8c05677..22a0f65 100644 --- a/paket.dependencies +++ b/paket.dependencies @@ -11,11 +11,12 @@ nuget DSharpPlus.SlashCommands >= 4.3.0-nightly-01135 nuget FSharp.Data nuget FsToolkit.ErrorHandling -nuget MongoDB.Driver nuget dotenv.net 3.1.1 nuget Npgsql.FSharp nuget mixpanel-csharp 5.0.0 nuget Solnet.Extensions nuget Solnet.KeyStore nuget Solnet.Programs -nuget Solnet.Rpc \ No newline at end of file +nuget Solnet.Rpc + +nuget Giraffe diff --git a/paket.lock b/paket.lock index 15b27e4..7ca9e0d 100644 --- a/paket.lock +++ b/paket.lock @@ -4,9 +4,6 @@ NUGET remote: https://api.nuget.org/v3/index.json Chaos.NaCl.Standard (1.0) - restriction: || (== net6.0) (&& (== netstandard2.0) (>= net6.0)) (&& (== netstandard2.1) (>= net6.0)) ConcurrentHashSet (1.3) - DnsClient (1.6) - Microsoft.Win32.Registry (>= 5.0) - System.Buffers (>= 4.5.1) - restriction: || (&& (== net6.0) (>= net471)) (&& (== net6.0) (< netstandard2.0)) (&& (== net6.0) (< netstandard2.1)) (== netstandard2.0) (&& (== netstandard2.1) (>= net471)) (&& (== netstandard2.1) (< netstandard2.0)) dotenv.net (3.1.1) System.Memory (>= 4.5.4) - restriction: || (&& (== net6.0) (< netstandard2.0)) (&& (== net6.0) (< netstandard2.1)) (== netstandard2.0) (&& (== netstandard2.1) (< netstandard2.0)) DSharpPlus (4.3.0-nightly-01135) @@ -35,6 +32,15 @@ NUGET FSharp.Core (>= 4.7.2) FsToolkit.ErrorHandling (2.13) FSharp.Core (>= 4.7.2) + Giraffe (6.0) + FSharp.Core (>= 6.0.1) - restriction: || (== net6.0) (&& (== netstandard2.0) (>= net6.0)) (&& (== netstandard2.1) (>= net6.0)) + Giraffe.ViewEngine (>= 1.3) - restriction: || (== net6.0) (&& (== netstandard2.0) (>= net6.0)) (&& (== netstandard2.1) (>= net6.0)) + Microsoft.IO.RecyclableMemoryStream (>= 2.2) - restriction: || (== net6.0) (&& (== netstandard2.0) (>= net6.0)) (&& (== netstandard2.1) (>= net6.0)) + Newtonsoft.Json (>= 13.0.1) - restriction: || (== net6.0) (&& (== netstandard2.0) (>= net6.0)) (&& (== netstandard2.1) (>= net6.0)) + System.Text.Json (>= 6.0.2) - restriction: || (== net6.0) (&& (== netstandard2.0) (>= net6.0)) (&& (== netstandard2.1) (>= net6.0)) + Utf8Json (>= 1.3.7) - restriction: || (== net6.0) (&& (== netstandard2.0) (>= net6.0)) (&& (== netstandard2.1) (>= net6.0)) + Giraffe.ViewEngine (1.4) - restriction: || (== net6.0) (&& (== netstandard2.0) (>= net6.0)) (&& (== netstandard2.1) (>= net6.0)) + FSharp.Core (>= 5.0) Microsoft.Bcl.AsyncInterfaces (6.0) - restriction: || (&& (== net6.0) (< netstandard2.1)) (== netstandard2.0) System.Threading.Tasks.Extensions (>= 4.5.4) - restriction: || (&& (== net6.0) (>= net461)) (&& (== net6.0) (< netstandard2.1)) (== netstandard2.0) (&& (== netstandard2.1) (>= net461)) Microsoft.Bcl.HashCode (1.1.1) - restriction: || (&& (== net6.0) (< netstandard2.1)) (== netstandard2.0) @@ -89,31 +95,14 @@ NUGET Microsoft.Extensions.Primitives (>= 6.0) Microsoft.Extensions.Primitives (6.0) - restriction: || (== net6.0) (&& (== netstandard2.0) (>= net6.0)) (&& (== netstandard2.1) (>= net6.0)) System.Runtime.CompilerServices.Unsafe (>= 6.0) + Microsoft.IO.RecyclableMemoryStream (2.2) - restriction: || (== net6.0) (&& (== netstandard2.0) (>= net6.0)) (&& (== netstandard2.1) (>= net6.0)) Microsoft.NETCore.Platforms (6.0.2) Microsoft.NETCore.Targets (5.0) Microsoft.Win32.Primitives (4.3) Microsoft.NETCore.Platforms (>= 1.1) Microsoft.NETCore.Targets (>= 1.1) System.Runtime (>= 4.3) - Microsoft.Win32.Registry (5.0) - System.Buffers (>= 4.5.1) - restriction: || (&& (== net6.0) (>= monoandroid) (< netstandard1.3)) (&& (== net6.0) (>= monotouch)) (&& (== net6.0) (< netcoreapp2.0)) (&& (== net6.0) (>= xamarinios)) (&& (== net6.0) (>= xamarinmac)) (&& (== net6.0) (>= xamarintvos)) (&& (== net6.0) (>= xamarinwatchos)) (== netstandard2.0) (== netstandard2.1) - System.Memory (>= 4.5.4) - restriction: || (&& (== net6.0) (< netcoreapp2.0)) (&& (== net6.0) (< netcoreapp2.1)) (&& (== net6.0) (>= uap10.1)) (== netstandard2.0) (== netstandard2.1) - System.Security.AccessControl (>= 5.0) - System.Security.Principal.Windows (>= 5.0) mixpanel-csharp (5.0) - MongoDB.Bson (2.15) - System.Runtime.CompilerServices.Unsafe (>= 5.0) - MongoDB.Driver (2.15) - MongoDB.Bson (>= 2.15) - MongoDB.Driver.Core (>= 2.15) - MongoDB.Libmongocrypt (>= 1.3) - MongoDB.Driver.Core (2.15) - DnsClient (>= 1.6) - MongoDB.Bson (>= 2.15) - MongoDB.Libmongocrypt (>= 1.3) - SharpCompress (>= 0.30.1) - System.Buffers (>= 4.5.1) - MongoDB.Libmongocrypt (1.3) Newtonsoft.Json (13.0.1) Npgsql (6.0.3) Microsoft.Bcl.AsyncInterfaces (>= 6.0) - restriction: || (&& (== net6.0) (< netstandard2.1)) (== netstandard2.0) @@ -177,9 +166,6 @@ NUGET runtime.ubuntu.16.04-x64.runtime.native.System.Security.Cryptography.OpenSsl (4.3.3) runtime.ubuntu.16.10-x64.runtime.native.System.Security.Cryptography.OpenSsl (4.3.3) runtime.ubuntu.18.04-x64.runtime.native.System.Security.Cryptography.OpenSsl (4.3.3) - SharpCompress (0.30.1) - System.Memory (>= 4.5.4) - restriction: || (&& (== net6.0) (>= net461)) (&& (== net6.0) (< netstandard2.1)) (== netstandard2.0) (&& (== netstandard2.1) (>= net461)) - System.Text.Encoding.CodePages (>= 5.0) - restriction: || (&& (== net6.0) (>= net461)) (&& (== net6.0) (< netcoreapp3.1)) (&& (== net6.0) (< netstandard2.1)) (== netstandard2.0) (== netstandard2.1) Solnet.Extensions (6.0.11) Solnet.Programs (>= 6.0.11) - restriction: || (== net6.0) (&& (== netstandard2.0) (>= net6.0)) (&& (== netstandard2.1) (>= net6.0)) Solnet.Rpc (>= 6.0.11) - restriction: || (== net6.0) (&& (== netstandard2.0) (>= net6.0)) (&& (== netstandard2.1) (>= net6.0)) @@ -197,7 +183,7 @@ NUGET Solnet.Wallet (6.0.11) - restriction: || (== net6.0) (&& (== netstandard2.0) (>= net6.0)) (&& (== netstandard2.1) (>= net6.0)) Chaos.NaCl.Standard (>= 1.0) - restriction: || (== net6.0) (&& (== netstandard2.0) (>= net6.0)) (&& (== netstandard2.1) (>= net6.0)) Portable.BouncyCastle (>= 1.9) - restriction: || (== net6.0) (&& (== netstandard2.0) (>= net6.0)) (&& (== netstandard2.1) (>= net6.0)) - System.Buffers (4.5.1) + System.Buffers (4.5.1) - restriction: || (&& (== net6.0) (>= monotouch)) (&& (== net6.0) (>= net461)) (&& (== net6.0) (< netcoreapp2.0) (< netstandard2.1)) (&& (== net6.0) (< netstandard1.1)) (&& (== net6.0) (< netstandard2.0)) (&& (== net6.0) (< netstandard2.1) (>= xamarinios)) (&& (== net6.0) (< netstandard2.1) (>= xamarinmac)) (&& (== net6.0) (< netstandard2.1) (>= xamarintvos)) (&& (== net6.0) (< netstandard2.1) (>= xamarinwatchos)) (== netstandard2.0) (== netstandard2.1) System.Collections (4.3) Microsoft.NETCore.Platforms (>= 1.1) Microsoft.NETCore.Targets (>= 1.1) @@ -397,6 +383,8 @@ NUGET System.IO (>= 4.3) System.Reflection.Primitives (>= 4.3) System.Runtime (>= 4.3) + System.Reflection.Emit (4.7) - restriction: || (== net6.0) (&& (== netstandard2.0) (>= net6.0)) (&& (== netstandard2.1) (>= net6.0)) + System.Reflection.Emit.Lightweight (4.7) - restriction: || (== net6.0) (&& (== netstandard2.0) (>= net6.0)) (&& (== netstandard2.1) (>= net6.0)) System.Reflection.Extensions (4.3) Microsoft.NETCore.Platforms (>= 1.1) Microsoft.NETCore.Targets (>= 1.1) @@ -444,8 +432,6 @@ NUGET System.Resources.ResourceManager (>= 4.3) System.Runtime (>= 4.3) System.Runtime.Extensions (>= 4.3) - System.Security.AccessControl (6.0) - System.Security.Principal.Windows (>= 5.0) - restriction: || (&& (== net6.0) (>= net461)) (== netstandard2.0) (== netstandard2.1) System.Security.Claims (4.3) System.Collections (>= 4.3) System.Globalization (>= 4.3) @@ -541,9 +527,6 @@ NUGET Microsoft.NETCore.Platforms (>= 1.1) Microsoft.NETCore.Targets (>= 1.1) System.Runtime (>= 4.3) - System.Text.Encoding.CodePages (6.0) - restriction: || (&& (== net6.0) (>= net461)) (&& (== net6.0) (< netcoreapp3.1)) (&& (== net6.0) (< netstandard2.1)) (== netstandard2.0) (== netstandard2.1) - System.Memory (>= 4.5.4) - restriction: || (&& (== net6.0) (>= net461)) (&& (== net6.0) (< netcoreapp3.1)) (== netstandard2.0) (== netstandard2.1) - System.Runtime.CompilerServices.Unsafe (>= 6.0) System.Text.Encoding.Extensions (4.3) Microsoft.NETCore.Platforms (>= 1.1) Microsoft.NETCore.Targets (>= 1.1) @@ -573,3 +556,8 @@ NUGET Microsoft.NETCore.Targets (>= 1.1) System.Runtime (>= 4.3) System.ValueTuple (4.5) + Utf8Json (1.3.7) - restriction: || (== net6.0) (&& (== netstandard2.0) (>= net6.0)) (&& (== netstandard2.1) (>= net6.0)) + System.Reflection.Emit (>= 4.3) + System.Reflection.Emit.Lightweight (>= 4.3) + System.Threading.Tasks.Extensions (>= 4.4) + System.ValueTuple (>= 4.4) From f6f37654a1b7837c86356b30a380df8cd2b436c3 Mon Sep 17 00:00:00 2001 From: Joseph Ferano Date: Wed, 20 Jul 2022 18:01:25 +0700 Subject: [PATCH 02/14] Add port and change docker file --- CurrencyAPI/Currency.fs | 10 ++++------ Dockerfile | 6 +++--- 2 files changed, 7 insertions(+), 9 deletions(-) diff --git a/CurrencyAPI/Currency.fs b/CurrencyAPI/Currency.fs index 779ebf9..53a5764 100644 --- a/CurrencyAPI/Currency.fs +++ b/CurrencyAPI/Currency.fs @@ -100,19 +100,17 @@ let configureLogging (builder : ILoggingBuilder) = [] let main args = - let contentRoot = Directory.GetCurrentDirectory() - let webRoot = Path.Combine(contentRoot, "WebRoot") Host.CreateDefaultBuilder(args) .ConfigureWebHostDefaults( fun webHostBuilder -> webHostBuilder - .UseContentRoot(contentRoot) - .UseWebRoot(webRoot) - .ConfigureKestrel(fun opt -> opt.AddServerHeader <- false) + .ConfigureKestrel(fun opt -> + opt.AddServerHeader <- false + opt.ListenLocalhost(3333, (fun o -> o.UseHttps() |> ignore))) .Configure(Action configureApp) .ConfigureServices(configureServices) .ConfigureLogging(configureLogging) |> ignore) .Build() .Run() - 0 \ No newline at end of file + 0 diff --git a/Dockerfile b/Dockerfile index eb41ac9..83eb974 100644 --- a/Dockerfile +++ b/Dockerfile @@ -12,12 +12,12 @@ RUN dotnet restore "Bot/Bot.fsproj" WORKDIR "/src/Bot" -RUN dotnet build "Bot.fsproj" -c Release -o /app/build +RUN dotnet build "CurrencyAPI.fsproj" -c Release -o /app/build FROM build AS publish -RUN dotnet publish "Bot.fsproj" -c Release -o /app/publish +RUN dotnet publish "CurrencyAPI.fsproj" -c Release -o /app/publish FROM base AS final WORKDIR /app COPY --from=publish /app/publish . -ENTRYPOINT "./Bot" +ENTRYPOINT "./CurrencyAPI.App" From 96a11721ac04372eac64ef926172559f145831f6 Mon Sep 17 00:00:00 2001 From: Joseph Ferano Date: Wed, 20 Jul 2022 18:12:02 +0700 Subject: [PATCH 03/14] Forgot line dockerfile --- Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index 83eb974..e46a237 100644 --- a/Dockerfile +++ b/Dockerfile @@ -8,7 +8,7 @@ COPY . . RUN dotnet tool restore -RUN dotnet restore "Bot/Bot.fsproj" +RUN dotnet restore "CurrencyAPI/CurrencyAPI.fsproj" WORKDIR "/src/Bot" From 76a335109072bad0dd370c424856fb8db610823a Mon Sep 17 00:00:00 2001 From: Joseph Ferano Date: Wed, 20 Jul 2022 18:18:41 +0700 Subject: [PATCH 04/14] This? --- Bot/paket.references | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Bot/paket.references b/Bot/paket.references index 4b4a306..c7dcb68 100644 --- a/Bot/paket.references +++ b/Bot/paket.references @@ -2,11 +2,10 @@ FSharp.Core DSharpPlus DSharpPlus.Interactivity DSharpPlus.SlashCommands -FSharp.Core dotenv.net Npgsql.FSharp mixpanel-csharp Solnet.Rpc FsToolkit.ErrorHandling FSharp.Data -Newtonsoft.Json \ No newline at end of file +Newtonsoft.Json From 2ac29d526ce7c9accf17cf60d03a2ef061c29564 Mon Sep 17 00:00:00 2001 From: Joseph Ferano Date: Wed, 20 Jul 2022 18:25:50 +0700 Subject: [PATCH 05/14] Oh vey --- Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index e46a237..eb9698c 100644 --- a/Dockerfile +++ b/Dockerfile @@ -10,7 +10,7 @@ RUN dotnet tool restore RUN dotnet restore "CurrencyAPI/CurrencyAPI.fsproj" -WORKDIR "/src/Bot" +WORKDIR "/src/CurrencyAPI/" RUN dotnet build "CurrencyAPI.fsproj" -c Release -o /app/build From e00f3a865ec252adaab025fbd924a9318e05dd1d Mon Sep 17 00:00:00 2001 From: Joseph Ferano Date: Wed, 20 Jul 2022 18:30:52 +0700 Subject: [PATCH 06/14] AspNetCoreModuleV2 --- CurrencyAPI/web.config | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CurrencyAPI/web.config b/CurrencyAPI/web.config index f81ac42..aa1be50 100644 --- a/CurrencyAPI/web.config +++ b/CurrencyAPI/web.config @@ -2,8 +2,8 @@ - + - \ No newline at end of file + From fab68a5d399b8635543eb79be54e002b6caebc31 Mon Sep 17 00:00:00 2001 From: Joseph Ferano Date: Wed, 20 Jul 2022 18:41:02 +0700 Subject: [PATCH 07/14] See if this fixes it --- Dockerfile | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Dockerfile b/Dockerfile index eb9698c..c7aba67 100644 --- a/Dockerfile +++ b/Dockerfile @@ -15,9 +15,9 @@ WORKDIR "/src/CurrencyAPI/" RUN dotnet build "CurrencyAPI.fsproj" -c Release -o /app/build FROM build AS publish -RUN dotnet publish "CurrencyAPI.fsproj" -c Release -o /app/publish +RUN dotnet publish "CurrencyAPI.fsproj" -c Release -o /app/publish --no-restore -FROM base AS final +FROM mcr.microsoft.com/dotnet/aspnet:6.0 WORKDIR /app COPY --from=publish /app/publish . -ENTRYPOINT "./CurrencyAPI.App" +ENTRYPOINT [ "dotnet", "./CurrencyAPI.App.dll" ] From 489a39c06a967a3c2f63abc5e765f349a1a5d9d6 Mon Sep 17 00:00:00 2001 From: Joseph Ferano Date: Thu, 21 Jul 2022 14:32:07 +0700 Subject: [PATCH 08/14] Try the expose --- Dockerfile | 1 + 1 file changed, 1 insertion(+) diff --git a/Dockerfile b/Dockerfile index c7aba67..091c15f 100644 --- a/Dockerfile +++ b/Dockerfile @@ -20,4 +20,5 @@ RUN dotnet publish "CurrencyAPI.fsproj" -c Release -o /app/publish --no-restore FROM mcr.microsoft.com/dotnet/aspnet:6.0 WORKDIR /app COPY --from=publish /app/publish . +EXPOSE 3333 ENTRYPOINT [ "dotnet", "./CurrencyAPI.App.dll" ] From fc04e5f2b53f35f3987324bd6ef56b90bdb79390 Mon Sep 17 00:00:00 2001 From: Joseph Ferano Date: Thu, 21 Jul 2022 14:38:24 +0700 Subject: [PATCH 09/14] Try this --- Dockerfile | 1 + 1 file changed, 1 insertion(+) diff --git a/Dockerfile b/Dockerfile index 091c15f..19d7ef8 100644 --- a/Dockerfile +++ b/Dockerfile @@ -21,4 +21,5 @@ FROM mcr.microsoft.com/dotnet/aspnet:6.0 WORKDIR /app COPY --from=publish /app/publish . EXPOSE 3333 +RUN dotnet dev-certs https ENTRYPOINT [ "dotnet", "./CurrencyAPI.App.dll" ] From b86adff83da22554429a56ab1117791f9261c978 Mon Sep 17 00:00:00 2001 From: Joseph Ferano Date: Thu, 21 Jul 2022 14:46:54 +0700 Subject: [PATCH 10/14] Remove https --- CurrencyAPI/Currency.fs | 3 +-- Dockerfile | 3 ++- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/CurrencyAPI/Currency.fs b/CurrencyAPI/Currency.fs index 53a5764..672ed73 100644 --- a/CurrencyAPI/Currency.fs +++ b/CurrencyAPI/Currency.fs @@ -105,8 +105,7 @@ let main args = fun webHostBuilder -> webHostBuilder .ConfigureKestrel(fun opt -> - opt.AddServerHeader <- false - opt.ListenLocalhost(3333, (fun o -> o.UseHttps() |> ignore))) + opt.AddServerHeader <- false) .Configure(Action configureApp) .ConfigureServices(configureServices) .ConfigureLogging(configureLogging) diff --git a/Dockerfile b/Dockerfile index 19d7ef8..d971799 100644 --- a/Dockerfile +++ b/Dockerfile @@ -21,5 +21,6 @@ FROM mcr.microsoft.com/dotnet/aspnet:6.0 WORKDIR /app COPY --from=publish /app/publish . EXPOSE 3333 -RUN dotnet dev-certs https +EXPOSE 80 +EXPOSE 443 ENTRYPOINT [ "dotnet", "./CurrencyAPI.App.dll" ] From f921d7b1237d2af068bcf27e5d969c145a7c221d Mon Sep 17 00:00:00 2001 From: Joseph Ferano Date: Thu, 21 Jul 2022 15:12:24 +0700 Subject: [PATCH 11/14] Get the environment variable properly --- CurrencyAPI/Currency.fs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/CurrencyAPI/Currency.fs b/CurrencyAPI/Currency.fs index 672ed73..8f773ff 100644 --- a/CurrencyAPI/Currency.fs +++ b/CurrencyAPI/Currency.fs @@ -12,10 +12,10 @@ open Giraffe open dotenv.net open Npgsql.FSharp -let prodEnv = DotEnv.Read(DotEnvOptions(envFilePaths = [ "../.prod.env"], overwriteExistingVars = false)) +DotEnv.Load(DotEnvOptions(envFilePaths = [ "../.prod.env" ], overwriteExistingVars = false)) -let ( _ , connStr ) = prodEnv.TryGetValue("DATABASE_URL") -let ( _ , apiKey ) = prodEnv.TryGetValue("API_KEY") +let connStr = Environment.GetEnvironmentVariable("DATABASE_URL") +let apiKey = Environment.GetEnvironmentVariable("API_KEY") let validateApiKey (ctx : HttpContext) = match ctx.TryGetRequestHeader "X-API-Key" with From 9e4a37baabd96092333f82363faefe81672f2e24 Mon Sep 17 00:00:00 2001 From: Joseph Ferano Date: Thu, 21 Jul 2022 15:20:10 +0700 Subject: [PATCH 12/14] Do the thing with the postgres url --- CurrencyAPI/Currency.fs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CurrencyAPI/Currency.fs b/CurrencyAPI/Currency.fs index 8f773ff..b08ed56 100644 --- a/CurrencyAPI/Currency.fs +++ b/CurrencyAPI/Currency.fs @@ -15,6 +15,8 @@ open Npgsql.FSharp DotEnv.Load(DotEnvOptions(envFilePaths = [ "../.prod.env" ], overwriteExistingVars = false)) let connStr = Environment.GetEnvironmentVariable("DATABASE_URL") + .Replace("postgresql://", "postgres://") + .Replace("?sslmode=require", "") let apiKey = Environment.GetEnvironmentVariable("API_KEY") let validateApiKey (ctx : HttpContext) = From 3d1a863ab5d3759c771e8461fa129d73b13c766e Mon Sep 17 00:00:00 2001 From: Joseph Ferano Date: Thu, 4 Aug 2022 13:50:32 +0700 Subject: [PATCH 13/14] Whitespace it seems --- Bot/Games/HackerBattle.fs | 12 ++++++------ CurrencyAPI/Currency.fs | 10 +++++----- Dockerfile | 1 - 3 files changed, 11 insertions(+), 12 deletions(-) diff --git a/Bot/Games/HackerBattle.fs b/Bot/Games/HackerBattle.fs index 26996d5..f295060 100644 --- a/Bot/Games/HackerBattle.fs +++ b/Bot/Games/HackerBattle.fs @@ -76,7 +76,7 @@ let strengthBonus attacker defender = |> (*) 0.01 |> (*) 200.0 // Bonus |> int - + let runHackerBattle defender (hack : HackItem) = defender |> Player.removeExpiredActions @@ -108,7 +108,7 @@ let updateCombatants successfulHack (attacker : PlayerData) (defender : PlayerDa DbService.addPlayerEvent defender.DiscordId (event true) ] |> Async.Parallel |> Async.Ignore - + let hackerResult successfulHack (ctx : IDiscordContext) attacker defender (hack : HackItem) = async { let prizeAmount , bonus = @@ -120,9 +120,9 @@ let hackerResult successfulHack (ctx : IDiscordContext) attacker defender (hack if hack.Power < int attacker.Bank then gbt hack.Power , 0 else attacker.Bank , 0 - + do! updateCombatants successfulHack attacker defender hack prizeAmount - + let! defenderMember = ctx.GetGuild().GetMemberAsync(defender.DiscordId) |> Async.AwaitTask let embed = Embeds.responseSuccessfulHack2 successfulHack attacker defender (ctx.GetDiscordMember()) defenderMember prizeAmount bonus hack do! ctx.GetChannel().SendMessageAsync(embed) @@ -368,7 +368,7 @@ type HackerGame() = [] member this.ScanCommand (ctx : InteractionContext) = enforceChannels (DiscordInteractionContext ctx) scan scan - + // [] member this.TestAutoComplete (ctx : InteractionContext) = async { @@ -377,4 +377,4 @@ type HackerGame() = do! ctx.Interaction.CreateResponseAsync(InteractionResponseType.ChannelMessageWithSource, builder) |> Async.AwaitTask } |> Async.StartAsTask - :> Task \ No newline at end of file + :> Task diff --git a/CurrencyAPI/Currency.fs b/CurrencyAPI/Currency.fs index b08ed56..763f3c3 100644 --- a/CurrencyAPI/Currency.fs +++ b/CurrencyAPI/Currency.fs @@ -23,7 +23,7 @@ let validateApiKey (ctx : HttpContext) = match ctx.TryGetRequestHeader "X-API-Key" with | Some key -> apiKey.Equals key | None -> false - + let accessDenied = setStatusCode 401 >=> text "Access Denied" let requiresApiKey = authorizeRequest validateApiKey accessDenied @@ -40,7 +40,7 @@ let getCurrentBalance (discordId : string) = | a::_ -> return Ok a } -let get (discordId : string) : HttpHandler = +let get (discordId : string) : HttpHandler = fun (next : HttpFunc) (ctx : HttpContext) -> task { try @@ -50,8 +50,8 @@ let get (discordId : string) : HttpHandler = with ex -> return! ServerErrors.internalError (json {| Error = ex.Message |}) next ctx } - -let modify sign (discordId : string) : HttpHandler = + +let modify sign (discordId : string) : HttpHandler = fun (next : HttpFunc) (ctx : HttpContext) -> task { let! body = ctx.BindJsonAsync<{|Amount:int|}>() @@ -72,7 +72,7 @@ let modify sign (discordId : string) : HttpHandler = with ex -> return! RequestErrors.notFound (json {| Error = ex.Message |}) next ctx | Error e -> return! RequestErrors.notFound (json {| Error = e |}) next ctx } - + let webApp = choose [ GET >=> requiresApiKey >=> routef "/user/%s/balance" get diff --git a/Dockerfile b/Dockerfile index d971799..5951f44 100644 --- a/Dockerfile +++ b/Dockerfile @@ -20,7 +20,6 @@ RUN dotnet publish "CurrencyAPI.fsproj" -c Release -o /app/publish --no-restore FROM mcr.microsoft.com/dotnet/aspnet:6.0 WORKDIR /app COPY --from=publish /app/publish . -EXPOSE 3333 EXPOSE 80 EXPOSE 443 ENTRYPOINT [ "dotnet", "./CurrencyAPI.App.dll" ] From 61285d6bc4dd4b7b90fbbb530c704be8e43853d7 Mon Sep 17 00:00:00 2001 From: Joseph Ferano Date: Mon, 27 Feb 2023 18:14:42 +0700 Subject: [PATCH 14/14] Fixing some DB stuff I guess --- Bot/DbService.fs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Bot/DbService.fs b/Bot/DbService.fs index db787fe..7867523 100644 --- a/Bot/DbService.fs +++ b/Bot/DbService.fs @@ -154,14 +154,14 @@ let getRafflesWithPurchases storeId = |> Sql.connect |> Sql.parameters [ "sid" , Sql.string storeId ] |> Sql.query """ -WITH raffles AS + WITH raffles AS (SELECT store_id,stock,available,limit_stock,i.id AS raffle_id,name,description,icon_url,image_url,category,require_role,require_invites,sale_end,rank, buy_price,sell_price,rate_limit,expiration,drop_chance,can_trade,can_consume,attack_power,defense_power,class_name,max_stack,mods FROM store_item JOIN item i on store_item.item_id = i.id WHERE store_id = @sid AND store_item.unlisted = false) -SELECT * FROM raffles -FULL JOIN (SELECT item_id, count(*) AS total FROM inventory_item + SELECT * FROM raffles + FULL JOIN (SELECT item_id, count(*) AS total FROM inventory_item WHERE item_id = ANY (SELECT raffle_id FROM raffles) GROUP BY item_id) total_raffles ON total_raffles.item_id = raffle_id; """