Loads of updates #1
11
README.md
11
README.md
|
@ -32,4 +32,13 @@ Obtain an admin GWT: `curl -d '"api-key-goes-here"' -H "Content-Type: applicatio
|
|||
|
||||
Use a bearer token to make a call: `curl -H "Content-Type: application/json" -H "Authorization: bearer your-JWT-token-goes-here" -i http://localhost:4000/accounts/{accountID}`
|
||||
|
||||
Create account: `curl -d '{"name": "Bosse", "password": "Hemligt", "fields": [{ "name":"role", "values":["user"]}]}' -H "Content-Type: application/json" -H "Authorization: bearer your-JWT-token-goes-here" -i http://localhost:4000/account`
|
||||
Create account: `curl -d '{"name": "Bosse", "password": "Hemligt", "fields": [{ "name":"role", "values":["user"]}]}' -H "Content-Type: application/json" -H "Authorization: bearer your-JWT-token-goes-here" -i http://localhost:4000/account`
|
||||
|
||||
## Development
|
||||
|
||||
For local development, run with .env like: `eval $(cat .env) go run src/main.go`
|
||||
|
||||
To regenerate the swagger docs folder:
|
||||
|
||||
1. Make sure you have swag installed: https://github.com/swaggo/swag
|
||||
2. cd src && swag init
|
1
go.mod
1
go.mod
|
@ -9,7 +9,6 @@ require (
|
|||
github.com/gofiber/fiber/v2 v2.44.0
|
||||
github.com/google/uuid v1.3.0
|
||||
github.com/jackc/pgx/v4 v4.18.1
|
||||
github.com/joho/godotenv v1.5.1
|
||||
github.com/swaggo/swag v1.16.1
|
||||
golang.org/x/crypto v0.8.0
|
||||
)
|
||||
|
|
2
go.sum
2
go.sum
|
@ -101,8 +101,6 @@ github.com/jackc/puddle v0.0.0-20190608224051-11cab39313c9/go.mod h1:m4B5Dj62Y0f
|
|||
github.com/jackc/puddle v1.1.3/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk=
|
||||
github.com/jackc/puddle v1.3.0 h1:eHK/5clGOatcjX3oWGBO/MpxpbHzSwud5EWTSCI+MX0=
|
||||
github.com/jackc/puddle v1.3.0/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk=
|
||||
github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0=
|
||||
github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4=
|
||||
github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY=
|
||||
github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y=
|
||||
github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
|
||||
|
|
|
@ -3,7 +3,7 @@ package db
|
|||
import (
|
||||
"context"
|
||||
|
||||
"gitea.larvit.se/pwrpln/auth-api/pkgs/utils"
|
||||
"gitea.larvit.se/pwrpln/auth-api/src/utils"
|
||||
)
|
||||
|
||||
// RenewalTokenCreate obtain a new renewal token
|
|
@ -37,9 +37,10 @@ func (h Handlers) AccountDel(c *fiber.Ctx) error {
|
|||
|
||||
err := h.Db.AccountDel(accountID)
|
||||
if err != nil {
|
||||
if err.Error() == "No account found for given accountID" {
|
||||
if err.Error() == "no account found for given accountID" {
|
||||
return c.Status(404).JSON([]ResJSONError{{Error: err.Error()}})
|
||||
} else {
|
||||
h.Log.Error("Database error when trying to remove account", "err", err.Error())
|
||||
return c.Status(500).JSON([]ResJSONError{{Error: "Database error when trying to remove account"}})
|
||||
}
|
||||
}
|
|
@ -5,7 +5,7 @@ import (
|
|||
"strings"
|
||||
"time"
|
||||
|
||||
"gitea.larvit.se/pwrpln/auth-api/pkgs/db"
|
||||
"gitea.larvit.se/pwrpln/auth-api/src/db"
|
||||
jwt "github.com/dgrijalva/jwt-go"
|
||||
"github.com/gofiber/fiber/v2"
|
||||
)
|
|
@ -3,8 +3,8 @@ package handlers
|
|||
import (
|
||||
"strings"
|
||||
|
||||
"gitea.larvit.se/pwrpln/auth-api/pkgs/db"
|
||||
"gitea.larvit.se/pwrpln/auth-api/pkgs/utils"
|
||||
"gitea.larvit.se/pwrpln/auth-api/src/db"
|
||||
"gitea.larvit.se/pwrpln/auth-api/src/utils"
|
||||
"github.com/gofiber/fiber/v2"
|
||||
"github.com/google/uuid"
|
||||
)
|
|
@ -1,7 +1,7 @@
|
|||
package handlers
|
||||
|
||||
import (
|
||||
"gitea.larvit.se/pwrpln/auth-api/pkgs/db"
|
||||
"gitea.larvit.se/pwrpln/auth-api/src/db"
|
||||
"github.com/gofiber/fiber/v2"
|
||||
"github.com/google/uuid"
|
||||
)
|
|
@ -1,7 +1,7 @@
|
|||
package handlers
|
||||
|
||||
import (
|
||||
"gitea.larvit.se/pwrpln/auth-api/pkgs/db"
|
||||
"gitea.larvit.se/pwrpln/auth-api/src/db"
|
||||
"gitea.larvit.se/pwrpln/go_log"
|
||||
jwt "github.com/dgrijalva/jwt-go"
|
||||
)
|
|
@ -6,21 +6,20 @@ import (
|
|||
"strings"
|
||||
"time"
|
||||
|
||||
"gitea.larvit.se/pwrpln/auth-api/pkgs/db"
|
||||
h "gitea.larvit.se/pwrpln/auth-api/pkgs/handlers"
|
||||
"gitea.larvit.se/pwrpln/auth-api/src/db"
|
||||
h "gitea.larvit.se/pwrpln/auth-api/src/handlers"
|
||||
"gitea.larvit.se/pwrpln/go_log"
|
||||
swagger "github.com/arsmn/fiber-swagger/v2"
|
||||
"github.com/gofiber/fiber/v2"
|
||||
"github.com/google/uuid"
|
||||
"github.com/jackc/pgx/v4/pgxpool"
|
||||
"github.com/joho/godotenv"
|
||||
|
||||
// docs are generated by Swag CLI, you have to import them.
|
||||
_ "gitea.larvit.se/pwrpln/auth-api/docs"
|
||||
_ "gitea.larvit.se/pwrpln/auth-api/src/docs"
|
||||
)
|
||||
|
||||
// Don't put in utils, because it creates import cycle with db... just left it here for now
|
||||
func createAdminAccount(Db db.Db, log go_log.Log) {
|
||||
func createAdminAccount(Db db.Db, log go_log.Log, ADMIN_API_KEY string) {
|
||||
adminAccountID, uuidErr := uuid.NewRandom()
|
||||
if uuidErr != nil {
|
||||
log.Error("Could not create new Uuid", "err", uuidErr.Error())
|
||||
|
@ -29,7 +28,7 @@ func createAdminAccount(Db db.Db, log go_log.Log) {
|
|||
_, adminAccountErr := Db.AccountCreate(db.AccountCreateInput{
|
||||
ID: adminAccountID,
|
||||
Name: "admin",
|
||||
APIKey: os.Getenv("ADMIN_API_KEY"),
|
||||
APIKey: ADMIN_API_KEY,
|
||||
Password: "",
|
||||
Fields: []db.AccountCreateInputFields{{Name: "role", Values: []string{"admin"}}},
|
||||
})
|
||||
|
@ -55,11 +54,6 @@ func createAdminAccount(Db db.Db, log go_log.Log) {
|
|||
func main() {
|
||||
log := go_log.GetLog()
|
||||
|
||||
err := godotenv.Load()
|
||||
if err != nil {
|
||||
log.Warn("Error loading .env file, this could be ok if the env file does not exist", "err", err.Error())
|
||||
}
|
||||
|
||||
if os.Getenv("JWT_SHARED_SECRET") == "changeMe" {
|
||||
log.Warn("JWT_SHARED_SECRET ENV is not set, using very insecure \"changeMe\"")
|
||||
}
|
||||
|
@ -79,13 +73,18 @@ func main() {
|
|||
log.MinLogLvl = minLogLvl
|
||||
}
|
||||
}
|
||||
|
||||
ADMIN_API_KEY := os.Getenv("ADMIN_API_KEY")
|
||||
WEB_BIND_HOST := os.Getenv("WEB_BIND_HOST")
|
||||
DATABASE_URL := os.Getenv("DATABASE_URL")
|
||||
|
||||
jwtKey := []byte(os.Getenv("JWT_SHARED_SECRET"))
|
||||
|
||||
dbPool, err := pgxpool.Connect(context.Background(), os.Getenv("DATABASE_URL"))
|
||||
dbPool, err := pgxpool.Connect(context.Background(), DATABASE_URL)
|
||||
for err != nil {
|
||||
log.Warn("Failed to open connection to PostgreSQL database, retrying in 1 second", "err", err.Error())
|
||||
time.Sleep(1 * time.Second)
|
||||
dbPool, err = pgxpool.Connect(context.Background(), os.Getenv("DATABASE_URL"))
|
||||
dbPool, err = pgxpool.Connect(context.Background(), DATABASE_URL)
|
||||
}
|
||||
log.Verbose("Connected to PostgreSQL database")
|
||||
defer dbPool.Close()
|
||||
|
@ -95,7 +94,7 @@ func main() {
|
|||
Db := db.Db{DbPool: dbPool, Log: log}
|
||||
handlers := h.Handlers{Db: Db, JwtKey: jwtKey, Log: log}
|
||||
|
||||
createAdminAccount(Db, log)
|
||||
createAdminAccount(Db, log, ADMIN_API_KEY)
|
||||
|
||||
// Log all requests
|
||||
app.Use(handlers.LogReq)
|
||||
|
@ -116,14 +115,13 @@ func main() {
|
|||
app.Post("/renew-token", handlers.RenewToken)
|
||||
app.Put("/accounts/:accountID/fields", handlers.AccountUpdateFields)
|
||||
|
||||
log.Info("Starting web server", "WEB_BIND_HOST", os.Getenv("WEB_BIND_HOST"))
|
||||
log.Info("Starting web server", "WEB_BIND_HOST", WEB_BIND_HOST)
|
||||
|
||||
webBindHost := os.Getenv("WEB_BIND_HOST")
|
||||
err = app.Listen(webBindHost)
|
||||
err = app.Listen(WEB_BIND_HOST)
|
||||
for err != nil {
|
||||
log.Warn("Could not start web server", "err", err.Error(), "WEB_BIND_HOST", webBindHost)
|
||||
log.Warn("Could not start web server", "err", err.Error(), "WEB_BIND_HOST", WEB_BIND_HOST)
|
||||
time.Sleep(1 * time.Second)
|
||||
err = app.Listen(webBindHost)
|
||||
err = app.Listen(WEB_BIND_HOST)
|
||||
}
|
||||
|
||||
log.Info("Web server closed, shutting down")
|
|
@ -1,3 +1,3 @@
|
|||
ADMIN_API_KEY=hihi
|
||||
AUTH_URL=http://localhost:4000
|
||||
AUTH_URL=http://127.0.0.1:4000
|
||||
JWT_SHARED_SECRET=hihi
|
||||
|
|
|
@ -6,7 +6,7 @@ import setConfig from '../test-helpers/config.js';
|
|||
test('test-cases/00start.js: Wait for auth API to be ready', async t => {
|
||||
setConfig({ printConfig: true });
|
||||
|
||||
const backendHealthCheck = await got(process.env.AUTH_URL, { retry: 2000 });
|
||||
const backendHealthCheck = await got(process.env.AUTH_URL, { retry: { limit: 2000 }});
|
||||
|
||||
t.equal(backendHealthCheck.statusCode, 200, 'Auth API should answer with status code 200');
|
||||
});
|
||||
|
|
|
@ -54,7 +54,7 @@ test('test-cases/01basic.js: GETting the admin account, with the token we just o
|
|||
});
|
||||
|
||||
test('test-cases/01basic.js: Creating a new account', async t => {
|
||||
const res = await got.post(`${process.env.AUTH_URL}/account`, {
|
||||
const res = await got.post(`${process.env.AUTH_URL}/accounts`, {
|
||||
headers: { 'Authorization': `bearer ${adminJWTString}`},
|
||||
json: {
|
||||
fields: [
|
||||
|
@ -79,7 +79,7 @@ test('test-cases/01basic.js: Creating a new account', async t => {
|
|||
t.notEqual(user.apiKey, undefined, 'The new account should have an apiKey');
|
||||
|
||||
try {
|
||||
await got.post(`${process.env.AUTH_URL}/account`, {
|
||||
await got.post(`${process.env.AUTH_URL}/accounts`, {
|
||||
headers: { 'Authorization': `bearer ${adminJWTString}`},
|
||||
json: {
|
||||
fields: [{name: 'role',values: ['user'],}],
|
||||
|
@ -187,7 +187,7 @@ test('test-cases/01basic.js: Remove an account', async t => {
|
|||
await got.delete(`${process.env.AUTH_URL}/accounts/a423e690-74b9-4f37-9976-f5bf75a5ea32`, {
|
||||
headers: { 'Authorization': `bearer ${adminJWTString}`},
|
||||
responseType: 'json',
|
||||
retry: 0,
|
||||
retry: { limit: 0 },
|
||||
});
|
||||
t.fail('Response status for DELETing an account that does not exist should be 404');
|
||||
} catch (err) {
|
||||
|
@ -197,7 +197,7 @@ test('test-cases/01basic.js: Remove an account', async t => {
|
|||
const delRes = await got.delete(`${process.env.AUTH_URL}/accounts/${user.id}`, {
|
||||
headers: { 'Authorization': `bearer ${adminJWTString}`},
|
||||
responseType: 'json',
|
||||
retry: 0,
|
||||
retry: { limit: 0 },
|
||||
});
|
||||
|
||||
t.equal(delRes.statusCode, 204, 'Response status for DELETE should be 204');
|
||||
|
@ -206,7 +206,7 @@ test('test-cases/01basic.js: Remove an account', async t => {
|
|||
await got(`${process.env.AUTH_URL}/accounts/${user.id}`, {
|
||||
headers: { 'Authorization': `bearer ${adminJWTString}`},
|
||||
responseType: 'json',
|
||||
retry: 0,
|
||||
retry: { limit: 0 },
|
||||
});
|
||||
t.fail('Response status for GETing the account again should be 404');
|
||||
} catch (err) {
|
||||
|
|
Loading…
Reference in New Issue
Block a user