Skip to content

Commit

Permalink
feat: refactor store to mongodb
Browse files Browse the repository at this point in the history
  • Loading branch information
sikozonpc committed May 12, 2024
1 parent e0f75af commit c6dee4f
Show file tree
Hide file tree
Showing 24 changed files with 382 additions and 593 deletions.
9 changes: 1 addition & 8 deletions .envrc.example
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,7 @@ export PORT="3000"
export JWT_SECRET="mysuperbigsecret"
export API_KEY="myapikey"

export DB_HOST="127.0.0.1"
export DB_PORT="3306"
export DB_USER="root"
export DB_PASSWORD="mypassword"
export DB_NAME="highlights"

export GOOGLE_CLOUD_PROJECT_ID=""
export GOOGLE_CLOUD_BOOKS_BUCKET_NAME=""
export MONGODB_URI="mongodb://localhost:27017/boilerplate"

export SENDGRID_API_KEY=""
export SENDGRID_FROM_EMAIL=""
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,11 +33,5 @@ jobs:
- name: Run staticcheck
run: staticcheck ./...

- name: Install golint
run: go install golang.org/x/lint/golint@latest

- name: Run golint
run: golint ./...

- name: Run tests
run: go test -race -vet=off ./...
run: go test -race ./...
16 changes: 0 additions & 16 deletions .vscode/launch.json

This file was deleted.

6 changes: 3 additions & 3 deletions api.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package main

import (
"context"
"database/sql"
"log"
"net/http"
"os"
Expand All @@ -15,14 +14,15 @@ import (
"github.com/sikozonpc/notebase/medium"
"github.com/sikozonpc/notebase/storage"
"github.com/sikozonpc/notebase/user"
"go.mongodb.org/mongo-driver/mongo"
)

type APIServer struct {
addr string
db *sql.DB
db *mongo.Client
}

func NewAPIServer(addr string, db *sql.DB) *APIServer {
func NewAPIServer(addr string, db *mongo.Client) *APIServer {
return &APIServer{
addr: addr,
db: db,
Expand Down
27 changes: 7 additions & 20 deletions auth/jwt.go
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
package auth

import (
"context"
"fmt"
"log"
"net/http"
"os"
"strconv"
"time"

"github.com/golang-jwt/jwt/v5"
Expand All @@ -20,22 +20,16 @@ func permissionDenied(w http.ResponseWriter) {
})
}

func GetUserFromToken(t string) (int, error) {
func GetUserFromToken(t string) (string, error) {
token, err := validateJWT(t)
if err != nil {
return 0, err
return "", err
}

claims := token.Claims.(jwt.MapClaims)
claimsUserID := claims["userID"].(string)

userID, err := strconv.Atoi(claimsUserID)
if err != nil {
log.Println("failed to convert userID to int")
return 0, err
}

return userID, nil
return claimsUserID, nil
}

func WithAPIKey(handlerFunc http.HandlerFunc) http.HandlerFunc {
Expand Down Expand Up @@ -74,14 +68,7 @@ func WithJWTAuth(handlerFunc http.HandlerFunc, store t.UserStore) http.HandlerFu
claims := token.Claims.(jwt.MapClaims)
claimsUserID := claims["userID"].(string)

userID, err := strconv.Atoi(claimsUserID)
if err != nil {
log.Println("failed to convert userID to int")
permissionDenied(w)
return
}

_, err = store.GetUserByID(userID)
_, err = store.GetUserByID(context.Background(), claimsUserID)
if err != nil {
log.Printf("failed to get user by id: %v", err)
permissionDenied(w)
Expand All @@ -93,9 +80,9 @@ func WithJWTAuth(handlerFunc http.HandlerFunc, store t.UserStore) http.HandlerFu
}
}

func CreateJWT(secret []byte, userID int) (string, error) {
func CreateJWT(secret []byte, userID string) (string, error) {
token := jwt.NewWithClaims(jwt.SigningMethodHS256, jwt.MapClaims{
"userID": strconv.Itoa(userID),
"userID": userID,
"expiresAt": time.Now().Add(time.Hour * 24 * 120).Unix(),
})

Expand Down
2 changes: 1 addition & 1 deletion auth/jwt_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import (

func TestCreateJWT(t *testing.T) {
secret := []byte("secret")
userID := 1
userID := "1"

token, err := CreateJWT(secret, userID)
if err != nil {
Expand Down
11 changes: 0 additions & 11 deletions book/Book.go

This file was deleted.

63 changes: 26 additions & 37 deletions book/store.go
Original file line number Diff line number Diff line change
@@ -1,56 +1,45 @@
package book

import (
"database/sql"
"fmt"
"context"

t "github.com/sikozonpc/notebase/types"
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/bson/primitive"
"go.mongodb.org/mongo-driver/mongo"
)

const (
DbName = "notebase"
CollName = "books"
)

type Store struct {
db *sql.DB
db *mongo.Client
}

func NewStore(db *sql.DB) *Store {
func NewStore(db *mongo.Client) *Store {
return &Store{db: db}
}

func (s *Store) GetBookByISBN(ISBN string) (*t.Book, error) {
rows, err := s.db.Query("SELECT * FROM books WHERE isbn = ?", ISBN)
if err != nil {
return nil, err
}

book := new(t.Book)
for rows.Next() {
book, err = scanRowsIntoBook(rows)
if err != nil {
return nil, err
}
}

if book.ISBN == "" {
return nil, fmt.Errorf("book not found")
}

return book, nil
}
func (s *Store) GetByISBN(ctx context.Context, isbn string) (*t.Book, error) {
col := s.db.Database(DbName).Collection(CollName)

func (s *Store) CreateBook(book t.Book) error {
_, err := s.db.Exec("INSERT INTO books (isbn, title, authors) VALUES (?, ?, ?)", book.ISBN, book.Title, book.Authors)
if err != nil {
return err
}
oID, _ := primitive.ObjectIDFromHex(isbn)

return nil
var b t.Book
err := col.FindOne(ctx, bson.M{
"isbn": oID,
}).Decode(&b)

return &b, err
}

func scanRowsIntoBook(rows *sql.Rows) (*t.Book, error) {
b := new(t.Book)
err := rows.Scan(&b.ISBN, &b.Title, &b.Authors, &b.CreatedAt)
if err != nil {
return nil, err
}
func (s *Store) Create(ctx context.Context, b *t.CreateBookRequest) (primitive.ObjectID, error) {
col := s.db.Database(DbName).Collection(CollName)

newBook, err := col.InsertOne(ctx, b)

return b, nil
id := newBook.InsertedID.(primitive.ObjectID)
return id, err
}
32 changes: 10 additions & 22 deletions config/config.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package config

import (
"fmt"
"os"

t "github.com/sikozonpc/notebase/types"
Expand All @@ -11,19 +10,16 @@ var Envs = initConfig()

func initConfig() t.Config {
return t.Config{
Env: getEnv("ENV", "development"),
Port: getEnv("PORT", "8080"),
DBUser: getEnv("DB_USER", "root"),
DBPassword: getEnv("DB_PASSWORD", "password"),
DBAddress: fmt.Sprintf("%s:%s", getEnv("DB_HOST", "127.0.0.1"), getEnv("DB_PORT", "3306")),
DBName: getEnv("DB_NAME", "notebase"),
PublicURL: getEnv("PUBLIC_URL", "http://localhost:3000"),
JWTSecret: getEnvOrPanic("JWT_SECRET", "JWT secret is required"),
GCPID: getEnvOrPanic("GOOGLE_CLOUD_PROJECT_ID", "Google Cloud Project ID is required"),
GCPBooksBucketName: getEnvOrPanic("GOOGLE_CLOUD_BOOKS_BUCKET_NAME", "Google Cloud Books Bucket Name is required"),
SendGridAPIKey: getEnvOrPanic("SENDGRID_API_KEY", "SendGrid API KEY is required"),
SendGridFromEmail: getEnvOrPanic("SENDGRID_FROM_EMAIL", "SendGrid From email is required"),
APIKey: getEnvOrPanic("API_KEY", "API Key is required"),
Env: getEnv("ENV", "development"),
Port: getEnv("PORT", "8080"),
MongoURI: getEnv("MONGODB_URI", "mongodb://localhost:27017"),
PublicURL: getEnv("PUBLIC_URL", "http://localhost:3000"),
JWTSecret: getEnv("JWT_SECRET", "JWT secret is required"),
/* GCPID: getEnv("GOOGLE_CLOUD_PROJECT_ID", "Google Cloud Project ID is required"),
GCPBooksBucketName: getEnv("GOOGLE_CLOUD_BOOKS_BUCKET_NAME", "Google Cloud Books Bucket Name is required"), */
SendGridAPIKey: getEnv("SENDGRID_API_KEY", "SendGrid API KEY is required"),
SendGridFromEmail: getEnv("SENDGRID_FROM_EMAIL", "SendGrid From email is required"),
APIKey: getEnv("API_KEY", "API Key is required"),
}
}

Expand All @@ -34,11 +30,3 @@ func getEnv(key, fallback string) string {

return fallback
}

func getEnvOrPanic(key, err string) string {
if value, ok := os.LookupEnv(key); ok {
return value
}

panic(err)
}
Loading

0 comments on commit c6dee4f

Please sign in to comment.