Merge branch 'user_registration' into 'master'

User registration front + back end

See merge request murphg62/2023-ca400-murphg62-byrnm257!12
This commit is contained in:
gaz8860 Gary 2023-05-02 19:13:31 +00:00
commit 6e89fca3fd
8 changed files with 177 additions and 68 deletions

View File

@ -1,6 +1,7 @@
@page "/account/register" @page "/account/register"
@using PanoptesFrontend.Data.Account; @using PanoptesFrontend.Data.Account;
@using PanoptesFrontend.Services; @using PanoptesFrontend.Services;
@using System.Text.Json;
@inject IAccountService AccountService @inject IAccountService AccountService
@ -33,6 +34,8 @@
private async void OnValidSubmit() private async void OnValidSubmit()
{ {
Console.WriteLine("Method called"); Console.WriteLine("Method called");
var user = JsonSerializer.Serialize(model);
Console.WriteLine(user);
await AccountService.Register(model); await AccountService.Register(model);
} }
} }

View File

@ -8,10 +8,12 @@
<ItemGroup> <ItemGroup>
<PackageReference Include="Blazor-ApexCharts" Version="0.9.20-beta" /> <PackageReference Include="Blazor-ApexCharts" Version="0.9.20-beta" />
<PackageReference Include="Blazored.LocalStorage" Version="4.3.0" />
<PackageReference Include="Bunit" Version="1.19.14" /> <PackageReference Include="Bunit" Version="1.19.14" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.5.0" /> <PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.5.0" />
<PackageReference Include="Moq" Version="4.18.4" /> <PackageReference Include="Moq" Version="4.18.4" />
<PackageReference Include="xunit" Version="2.4.2" /> <PackageReference Include="xunit" Version="2.4.2" />
</ItemGroup> </ItemGroup>
</Project> </Project>

View File

@ -1,6 +1,7 @@
using Microsoft.AspNetCore.Components; using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.Web; using Microsoft.AspNetCore.Components.Web;
using PanoptesFrontend.Services; using PanoptesFrontend.Services;
using Blazored.LocalStorage;
var builder = WebApplication.CreateBuilder(args); var builder = WebApplication.CreateBuilder(args);
@ -8,8 +9,9 @@ var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages(); builder.Services.AddRazorPages();
builder.Services.AddServerSideBlazor(); builder.Services.AddServerSideBlazor();
builder.Services.AddHttpClient(); builder.Services.AddHttpClient();
builder.Services.AddSingleton<IHttpService, HttpService>(); builder.Services.AddScoped<IHttpService, HttpService>();
builder.Services.AddSingleton<IAccountService, AccountService>(); builder.Services.AddScoped<IAccountService, AccountService>();
builder.Services.AddBlazoredLocalStorage();
var app = builder.Build(); var app = builder.Build();

View File

@ -1,8 +1,7 @@
using PanoptesFrontend.Data.Account; using PanoptesFrontend.Data.Account;
using PanoptesFrontend.Data; using PanoptesFrontend.Data;
using Microsoft.AspNetCore.Components; using Blazored.LocalStorage;
using System.Collections.Generic; using System.Text.Json;
using System.Threading.Tasks;
namespace PanoptesFrontend.Services; namespace PanoptesFrontend.Services;
@ -17,24 +16,30 @@ public interface IAccountService
public class AccountService : IAccountService public class AccountService : IAccountService
{ {
private IHttpService httpService; private IHttpService httpService;
private ILocalStorageService localStorage;
public AccountService(IHttpService httpService) { public AccountService(IHttpService httpService, ILocalStorageService localStorage) {
this.httpService = httpService; this.httpService = httpService;
this.localStorage = localStorage;
} }
public async Task Register(AddUser model){ public async Task Register(AddUser model){
// endpoint doesnt exist yet await httpService.PostAsync("http://localhost:10000/user/register", model);
await httpService.PostAsync("http://localhost:8080/user/register", model);
} }
public async Task Login(LoginUser model){ public async Task Login(LoginUser model){
// endpoint doesnt exist yet var response = await httpService.PostAsync("http://localhost:10000/user/login", model);
await httpService.PostAsync("http://localhost:8080/user/authenticate", model);
var jsonDoc = JsonDocument.Parse(response);
var token = jsonDoc.RootElement.GetProperty("token").GetString();
// Save the JWT token to local storage
await localStorage.SetItemAsync("authToken", token);
} }
public async Task Logout(User model){ public async Task Logout(User model){
// endpoint doesnt exist yet await httpService.PostAsync("http://localhost:10000/user/logout", model);
await httpService.PostAsync("http://localhost:8080/user/logout", model); await localStorage.RemoveItemAsync("authToken");
} }
} }

View File

@ -8,7 +8,7 @@ using System.Text.Json;
public interface IHttpService public interface IHttpService
{ {
Task<T> GetAsync<T>(string endpoint); Task<T> GetAsync<T>(string endpoint);
Task<HttpStatusCode> PostAsync(string endpoint, object value); Task<string> PostAsync(string endpoint, object value);
} }
public class HttpService : IHttpService { public class HttpService : IHttpService {
@ -32,11 +32,9 @@ public class HttpService : IHttpService {
} }
} }
public async Task<HttpStatusCode> PostAsync(string endpoint, object value){ public async Task<string> PostAsync(string endpoint, object value){
var request = await httpClient.PostAsJsonAsync(endpoint, value); var response = await httpClient.PostAsJsonAsync(endpoint, value);
response.EnsureSuccessStatusCode();
request.EnsureSuccessStatusCode(); return await response.Content.ReadAsStringAsync();
return request.StatusCode;
} }
} }

View File

@ -3,11 +3,13 @@ package main
import ( import (
"database/sql" "database/sql"
"encoding/json" _"encoding/json"
"fmt" "fmt"
"io/ioutil" "io/ioutil"
"log" "log"
"net/http" "net/http"
"github.com/dgrijalva/jwt-go"
"golang.org/x/crypto/bcrypt"
"github.com/labstack/echo/v4" "github.com/labstack/echo/v4"
"gitlab.computing.dcu.ie/murphg62/2023-ca400-murphg62-byrnm257/src/backend/pkg/database" "gitlab.computing.dcu.ie/murphg62/2023-ca400-murphg62-byrnm257/src/backend/pkg/database"
@ -23,6 +25,7 @@ const (
) )
var db, err = database.ConnectDB(host, port, user, password, dbname) var db, err = database.ConnectDB(host, port, user, password, dbname)
var jwtSecret = []byte("fAHr+Hlho9qhCePEuMxLVG2i/1tiEqtocAWkcYRJx0s=")
type Schema struct { type Schema struct {
Name string `json:"Name"` Name string `json:"Name"`
@ -35,6 +38,11 @@ type Module struct {
Container string `json:"Container"` Container string `json:"Container"`
} }
type User struct {
Username string `json:"Username"`
Password string `json:"Password"`
}
func homePage(c echo.Context) error { func homePage(c echo.Context) error {
return c.String(http.StatusOK, "Welcome to the home page!") return c.String(http.StatusOK, "Welcome to the home page!")
@ -80,44 +88,131 @@ func getStats(c echo.Context) error {
} }
func GetModules(db *sql.DB) http.HandlerFunc{ func GetModules(db *sql.DB) echo.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) { return func(c echo.Context) error {
if r.Method == "GET" { modules := make([]Module, 0)
var Modules []Module rows, err := db.Query("SELECT name, container_name FROM Module")
rows, err := db.Query("Select name, container_name FROM Module")
if err != nil { if err != nil {
panic(err) return err
} }
defer rows.Close() defer rows.Close()
for rows.Next() { for rows.Next() {
var module Module var module Module
if err := rows.Scan(&module.Name, &module.Container); err != nil { if err := rows.Scan(&module.Name, &module.Container); err != nil {
panic(err) return err
} }
Modules = append(Modules, module) modules = append(modules, module)
} }
w.Header().Set("Content-Type", "application/json") return c.JSON(http.StatusOK, modules)
if err := json.NewEncoder(w).Encode(Modules); err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
}
}
} }
} }
func RegisterUser(db *sql.DB) echo.HandlerFunc {
return func(c echo.Context) error {
user := new(User)
if err := c.Bind(user); err != nil {
return err
}
// Check if user already exists
var count int
if err := db.QueryRow("SELECT COUNT(*) FROM users WHERE name = $1", user.Username).Scan(&count); err != nil {
return err
}
if count > 0 {
return c.JSON(http.StatusBadRequest, map[string]string{"error": "Username already in use"})
}
// Hash password
hashedPassword, err := bcrypt.GenerateFromPassword([]byte(user.Password), bcrypt.DefaultCost)
if err != nil {
return err
}
// Insert new user into database
_, err = db.Exec("INSERT INTO users(name, password) VALUES ($1, $2)", user.Username, string(hashedPassword))
if err != nil {
return err
}
return c.JSON(http.StatusOK, map[string]string{"message": "User created"})
}
}
func LoginUser(db *sql.DB, jwtSecret []byte) echo.HandlerFunc {
return func(c echo.Context) error {
login := new(User)
if err := c.Bind(login); err != nil {
return err
}
// Check if user exists
var user User
if err := db.QueryRow("SELECT name, password FROM users WHERE name = $1", login.Username).Scan(&user.Username, &user.Password); err != nil {
if err == sql.ErrNoRows {
return c.JSON(http.StatusBadRequest, map[string]string{"error": "Invalid username or password"})
}
return err
}
if err := bcrypt.CompareHashAndPassword([]byte(user.Password), []byte(login.Password)); err != nil {
return c.JSON(http.StatusBadRequest, map[string]string{"error": "Invalid username or password"})
}
// Generate JWT token
token := jwt.New(jwt.SigningMethodHS256)
claims := token.Claims.(jwt.MapClaims)
claims["name"] = user.Username
tokenString, err := token.SignedString(jwtSecret)
if err != nil {
return err
}
return c.JSON(http.StatusOK, map[string]string{"token": tokenString})
}
}
func LogoutUser() echo.HandlerFunc {
return func(c echo.Context) error {
// Clear JWT token cookie
cookie := &http.Cookie{
Name: "jwt",
Value: "",
HttpOnly: true,
Path: "/",
}
http.SetCookie(c.Response().Writer, cookie)
return c.NoContent(http.StatusOK)
}
}
func main() { func main() {
if err != nil { if err != nil {
panic(err) panic(err)
} }
db.Exec(`CREATE TABLE IF NOT EXISTS Module ( db.Exec(`CREATE TABLE IF NOT EXISTS Module (
name VARCHAR(64), name VARCHAR(64),
container_name VARCHAR(64) container_name VARCHAR(64));
)`)
CREATE TABLE IF NOT EXISTS users (
id SERIAL PRIMARY KEY,
name VARCHAR(64) UNIQUE NOT NULL,
password VARCHAR(255) NOT NULL
)
`)
e := echo.New() e := echo.New()
e.GET("/", homePage) e.GET("/", homePage)
e.GET("/:container/schema", getSchema) e.GET("/:container/schema", getSchema)
e.GET("/:container/stats", getStats) e.GET("/:container/stats", getStats)
e.GET("/modules", GetModules(db))
e.POST("/user/register", RegisterUser(db))
e.POST("/user/login", LoginUser(db, jwtSecret))
e.POST("/user/logout", LogoutUser())
e.Logger.Fatal(e.Start(":10000")) e.Logger.Fatal(e.Start(":10000"))
defer db.Close() defer db.Close()
} }

View File

@ -12,15 +12,16 @@ require (
require ( require (
github.com/davecgh/go-spew v1.1.1 // indirect github.com/davecgh/go-spew v1.1.1 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect github.com/dgrijalva/jwt-go v3.2.0+incompatible // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
github.com/labstack/gommon v0.4.0 // indirect github.com/labstack/gommon v0.4.0 // indirect
github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-colorable v0.1.13 // indirect
github.com/mattn/go-isatty v0.0.17 // indirect github.com/mattn/go-isatty v0.0.17 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/valyala/bytebufferpool v1.0.0 // indirect github.com/valyala/bytebufferpool v1.0.0 // indirect
github.com/valyala/fasttemplate v1.2.2 // indirect github.com/valyala/fasttemplate v1.2.2 // indirect
golang.org/x/crypto v0.6.0 // indirect golang.org/x/crypto v0.8.0 // indirect
golang.org/x/net v0.7.0 // indirect golang.org/x/net v0.9.0 // indirect
golang.org/x/sys v0.5.0 // indirect golang.org/x/sys v0.7.0 // indirect
golang.org/x/text v0.7.0 // indirect golang.org/x/text v0.9.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
) )

View File

@ -2,8 +2,9 @@ github.com/DATA-DOG/go-sqlmock v1.5.0 h1:Shsta01QNfFxHCfpW6YH2STWB0MudeXXEWMr20O
github.com/DATA-DOG/go-sqlmock v1.5.0/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM= github.com/DATA-DOG/go-sqlmock v1.5.0/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM=
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI= github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI=
github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So=
github.com/labstack/echo/v4 v4.10.2 h1:n1jAhnq/elIFTHr1EYpiYtyKgx4RW9ccVgkqByZaN2M= github.com/labstack/echo/v4 v4.10.2 h1:n1jAhnq/elIFTHr1EYpiYtyKgx4RW9ccVgkqByZaN2M=
@ -12,22 +13,6 @@ github.com/labstack/gommon v0.4.0 h1:y7cvthEAEbU0yHOf4axH8ZG2NH8knB9iNSoTO8dyIk8
github.com/labstack/gommon v0.4.0/go.mod h1:uW6kP17uPlLJsD3ijUYn3/M5bAxtlZhMI6m3MFxTMTM= github.com/labstack/gommon v0.4.0/go.mod h1:uW6kP17uPlLJsD3ijUYn3/M5bAxtlZhMI6m3MFxTMTM=
github.com/lib/pq v1.10.8 h1:3fdt97i/cwSU83+E0hZTC/Xpc9mTZxc6UWSCRcSbxiE= github.com/lib/pq v1.10.8 h1:3fdt97i/cwSU83+E0hZTC/Xpc9mTZxc6UWSCRcSbxiE=
github.com/lib/pq v1.10.8/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= github.com/lib/pq v1.10.8/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8=
github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
golang.org/x/mod v0.8.0 h1:LUYupSeNrTNCGzR/hVBk2NHZO4hXcVaW1k4Qx7rjPx8=
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
github.com/mattn/go-colorable v0.1.11/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= github.com/mattn/go-colorable v0.1.11/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4=
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
@ -35,9 +20,16 @@ github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27k
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
github.com/mattn/go-isatty v0.0.17 h1:BTarxUcIeDqL27Mc+vyvdWYSL28zpIhv3RoTdsLMPng= github.com/mattn/go-isatty v0.0.17 h1:BTarxUcIeDqL27Mc+vyvdWYSL28zpIhv3RoTdsLMPng=
github.com/mattn/go-isatty v0.0.17/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= github.com/mattn/go-isatty v0.0.17/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8=
github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw= github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw=
github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
github.com/valyala/fasttemplate v1.2.1/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ= github.com/valyala/fasttemplate v1.2.1/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ=
@ -45,18 +37,29 @@ github.com/valyala/fasttemplate v1.2.2 h1:lxLXG0uE3Qnshl9QyaK6XJxMXlQZELvChBOCmQ
github.com/valyala/fasttemplate v1.2.2/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ= github.com/valyala/fasttemplate v1.2.2/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ=
golang.org/x/crypto v0.6.0 h1:qfktjS5LUO+fFKeJXZ+ikTRijMmljikvG68fpMMruSc= golang.org/x/crypto v0.6.0 h1:qfktjS5LUO+fFKeJXZ+ikTRijMmljikvG68fpMMruSc=
golang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58= golang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58=
golang.org/x/crypto v0.8.0 h1:pd9TJtTueMTVQXzk8E2XESSMQDj/U7OUu0PqJqPXQjQ=
golang.org/x/crypto v0.8.0/go.mod h1:mRqEX+O9/h5TFCrQhkgjo2yKi0yYA+9ecGkdQoHrywE=
golang.org/x/mod v0.8.0 h1:LUYupSeNrTNCGzR/hVBk2NHZO4hXcVaW1k4Qx7rjPx8= golang.org/x/mod v0.8.0 h1:LUYupSeNrTNCGzR/hVBk2NHZO4hXcVaW1k4Qx7rjPx8=
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
golang.org/x/net v0.7.0 h1:rJrUqqhjsgNp7KqAIc25s9pZnjU7TUcSY7HcVZjdn1g= golang.org/x/net v0.7.0 h1:rJrUqqhjsgNp7KqAIc25s9pZnjU7TUcSY7HcVZjdn1g=
golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
golang.org/x/net v0.9.0 h1:aWJ/m6xSmxWBx+V0XRHTlrYrPG56jKsLdTFmsSsCzOM=
golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns=
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211103235746-7861aae1554b/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211103235746-7861aae1554b/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.5.0 h1:MUK/U/4lj1t1oPg0HfuXDN/Z1wv31ZJ/YcPiGccS4DU= golang.org/x/sys v0.5.0 h1:MUK/U/4lj1t1oPg0HfuXDN/Z1wv31ZJ/YcPiGccS4DU=
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.7.0 h1:3jlCCIQZPdOYu1h8BkNvLz8Kgwtae2cagcG/VamtZRU=
golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/text v0.7.0 h1:4BRB4x83lYWy72KwLD/qYDuTu7q9PjSagHvijDw7cLo= golang.org/x/text v0.7.0 h1:4BRB4x83lYWy72KwLD/qYDuTu7q9PjSagHvijDw7cLo=
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/text v0.9.0 h1:2sjJmO8cDvYveuX97RDLsxlyUxLl+GHoLxBiRdHllBE=
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=