aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--backend/api/routes.go27
-rw-r--r--backend/cache/cache.go13
-rw-r--r--backend/db/db.go50
-rw-r--r--backend/db/schemas.go11
-rw-r--r--backend/go.mod1
-rw-r--r--backend/hashing/hash.go6
6 files changed, 82 insertions, 26 deletions
diff --git a/backend/api/routes.go b/backend/api/routes.go
index 07bea5a..7fb2114 100644
--- a/backend/api/routes.go
+++ b/backend/api/routes.go
@@ -27,6 +27,7 @@ func insertFunc(w http.ResponseWriter, r *http.Request) {
expiry := r.FormValue("expiry")
content := r.FormValue("content")
title := r.FormValue("title")
+ password := r.FormValue("password")
// get ip
ip := getIP(r)
@@ -34,11 +35,20 @@ func insertFunc(w http.ResponseWriter, r *http.Request) {
log.Infof("got content '%s' and ip '%s'", content, ip)
// insert content
- err := db.New(ip, content, expiry, title)
+ hash, err := db.New(ip, content, expiry, title, password)
if err != nil {
w.WriteHeader(http.StatusBadRequest)
fmt.Fprintf(w, "got err: %s", err.Error())
}
+
+ // if successful return paste hash
+ w.Header().Set("Content-Type", "application/json")
+ pasteMap := map[string]interface{}{
+ "hash": hash,
+ }
+
+ jsonData, _ := json.Marshal(pasteMap)
+ fmt.Fprintf(w, "%+v", string(jsonData))
}
func getHashFunc(w http.ResponseWriter, r *http.Request) {
@@ -50,17 +60,26 @@ func getHashFunc(w http.ResponseWriter, r *http.Request) {
paste, err := cache.C.Get(hash)
// if hash was not found
- if err != nil {
+ if err == cache.PasteNotFound {
w.WriteHeader(http.StatusNotFound)
- fmt.Fprintf(w, "got err: %s", err.Error())
+ fmt.Fprintf(w, "got err: %s", err)
+ return
+ }
+
+ // if paste is password protected
+ if err == cache.UserUnauthorized {
+ w.WriteHeader(http.StatusUnauthorized)
+ fmt.Fprintf(w, "got err: %s", err)
return
}
- // otherwise, return paste content and current time
+ // otherwise, return paste content, title, and current time
w.Header().Set("Content-Type", "application/json")
pasteMap := map[string]interface{}{
"timestamp": time.Now(),
+ "title": paste.Title,
"content": paste.Content,
+ "expiry": paste.Expiry,
}
jsonData, _ := json.Marshal(pasteMap)
diff --git a/backend/cache/cache.go b/backend/cache/cache.go
index bac7ea8..1a8a7a1 100644
--- a/backend/cache/cache.go
+++ b/backend/cache/cache.go
@@ -1,6 +1,7 @@
package cache
import (
+ "errors"
"sync"
"github.com/jackyzha0/ctrl-v/db"
@@ -13,6 +14,9 @@ type Cache struct {
var C *Cache
+var PasteNotFound = errors.New("could not find a paste with that hash")
+var UserUnauthorized = errors.New("paste is password protected")
+
func init() {
C = &Cache{
m: map[string]db.Paste{},
@@ -32,6 +36,15 @@ func (c *Cache) Get(hash string) (db.Paste, error) {
// if it doesnt, lookup from db
p, err := db.Lookup(hash)
+ if err != nil {
+ return p, PasteNotFound
+ }
+
+ // if there is a password
+ if p.Password != "" {
+ return db.Paste{}, UserUnauthorized
+ }
+
c.add(p)
return p, err
}
diff --git a/backend/db/db.go b/backend/db/db.go
index 4451f34..9bfe55a 100644
--- a/backend/db/db.go
+++ b/backend/db/db.go
@@ -27,29 +27,29 @@ func init() {
const TitleLimit = 100
const ContentLimit = 100000
-// creates a new paste with title, content and hash
-func New(ip, content, expiry, title string) error {
+// creates a new paste with title, content and hash, returns the hash of the created paste
+func New(ip, content, expiry, title, password string) (string, error) {
// generate hash from ip
hash := hashing.GenerateURI(ip)
// check for size of title and content
- errs := ""
- if len(title) > TitleLimit {
- errs += fmt.Sprintf("title is longer than character limit of %d\n", TitleLimit)
+ errs := checkLengths(title, content)
+ if errs != nil {
+ return "", errs
}
- if len(content) > ContentLimit {
- errs += fmt.Sprintf("content is longer than character limit of %d\n", ContentLimit)
- }
- // if any errors were found
- if errs != "" {
- return fmt.Errorf(errs)
+
+ // hash given password
+ hashedPass, err := hashing.HashPassword(password)
+ if err != nil {
+ return "", fmt.Errorf("could not hash password: %s", err.Error())
}
// create new struct
new := Paste{
- Hash: hash,
- Content: content,
- Title: title,
+ Hash: hash,
+ Content: content,
+ Title: title,
+ Password: hashedPass,
}
// check if expiry
@@ -58,12 +58,12 @@ func New(ip, content, expiry, title string) error {
// if time format not current
if err != nil {
- return err
+ return "", err
}
// time is in the past
if time.Now().After(t) {
- return fmt.Errorf("time %s is in the past", t.String())
+ return "", fmt.Errorf("time %s is in the past", t.String())
}
new.Expiry = t
@@ -76,7 +76,23 @@ func New(ip, content, expiry, title string) error {
// insert struct
log.Infof("create new paste with hash %s", hash)
insertErr := insert(new)
- return insertErr
+ return hash, insertErr
+}
+
+func checkLengths(title string, content string) error {
+ errs := ""
+ if len(title) > TitleLimit {
+ errs += fmt.Sprintf("title is longer than character limit of %d\n", TitleLimit)
+ }
+ if len(content) > ContentLimit {
+ errs += fmt.Sprintf("content is longer than character limit of %d\n", ContentLimit)
+ }
+ // if any errors were found
+ if errs != "" {
+ return fmt.Errorf(errs)
+ }
+
+ return nil
}
// lookup
diff --git a/backend/db/schemas.go b/backend/db/schemas.go
index 62c5a11..4c73f82 100644
--- a/backend/db/schemas.go
+++ b/backend/db/schemas.go
@@ -8,9 +8,10 @@ import (
// Paste represents a single paste
type Paste struct {
- ID bson.ObjectId `bson:"_id,omitempty"`
- Hash string
- Content string
- Expiry time.Time `bson:"expiry"`
- Title string
+ ID bson.ObjectId `bson:"_id,omitempty"`
+ Hash string
+ Content string
+ Expiry time.Time `bson:"expiry"`
+ Title string
+ Password string
}
diff --git a/backend/go.mod b/backend/go.mod
index fc4b4dd..0832637 100644
--- a/backend/go.mod
+++ b/backend/go.mod
@@ -8,6 +8,7 @@ require (
github.com/joho/godotenv v1.3.0
github.com/kr/pretty v0.2.0 // indirect
github.com/sirupsen/logrus v1.6.0
+ golang.org/x/crypto v0.0.0-20200510223506-06a226fb4e37
golang.org/x/sys v0.0.0-20200413165638-669c56c373c4 // indirect
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 // indirect
)
diff --git a/backend/hashing/hash.go b/backend/hashing/hash.go
index 400659e..93a9cf9 100644
--- a/backend/hashing/hash.go
+++ b/backend/hashing/hash.go
@@ -3,6 +3,7 @@ package hashing
import (
"crypto/md5"
"encoding/hex"
+ "golang.org/x/crypto/bcrypt"
"math/big"
"time"
)
@@ -23,4 +24,9 @@ func hashString(text string) string {
bi := big.NewInt(0)
bi.SetString(hexStr, 16)
return bi.Text(62)
+}
+
+func HashPassword(password string) (string, error) {
+ hashedPassword, err := bcrypt.GenerateFromPassword([]byte(password), bcrypt.DefaultCost)
+ return string(hashedPassword), err
} \ No newline at end of file