@ -0,0 +1,140 @@ | |||
package Auth_test | |||
import ( | |||
"bytes" | |||
"encoding/base64" | |||
"encoding/json" | |||
"io/ioutil" | |||
"log" | |||
"net/http" | |||
"net/http/httptest" | |||
"testing" | |||
"git.tovijaeschke.xyz/tovi/Capsule/Backend/Api" | |||
"git.tovijaeschke.xyz/tovi/Capsule/Backend/Api/Auth" | |||
"git.tovijaeschke.xyz/tovi/Capsule/Backend/Database" | |||
"git.tovijaeschke.xyz/tovi/Capsule/Backend/Database/Seeder" | |||
"git.tovijaeschke.xyz/tovi/Capsule/Backend/Models" | |||
"github.com/gorilla/mux" | |||
) | |||
func Test_Login(t *testing.T) { | |||
log.SetOutput(ioutil.Discard) | |||
Database.InitTest() | |||
r := mux.NewRouter() | |||
Api.InitAPIEndpoints(r) | |||
ts := httptest.NewServer(r) | |||
defer ts.Close() | |||
userKey, _ := Seeder.GenerateAesKey() | |||
pubKey := Seeder.GetPubKey() | |||
p, _ := Auth.HashPassword("password") | |||
u := Models.User{ | |||
Username: "test", | |||
Password: p, | |||
AsymmetricPublicKey: Seeder.PublicKey, | |||
AsymmetricPrivateKey: Seeder.EncryptedPrivateKey, | |||
SymmetricKey: base64.StdEncoding.EncodeToString( | |||
Seeder.EncryptWithPublicKey(userKey.Key, pubKey), | |||
), | |||
} | |||
err := Database.CreateUser(&u) | |||
if err != nil { | |||
t.Errorf("Expected nil, recieved %s", err.Error()) | |||
return | |||
} | |||
d := struct { | |||
Username string `json:"username"` | |||
Password string `json:"password"` | |||
}{ | |||
Username: "test", | |||
Password: "password", | |||
} | |||
jsonStr, _ := json.Marshal(d) | |||
req, _ := http.NewRequest("POST", ts.URL+"/api/v1/login", bytes.NewBuffer(jsonStr)) | |||
req.Header.Set("Content-Type", "application/json") | |||
client := &http.Client{} | |||
resp, err := client.Do(req) | |||
if err != nil { | |||
t.Errorf("Expected nil, recieved %s", err.Error()) | |||
return | |||
} | |||
if resp.StatusCode != http.StatusOK { | |||
t.Errorf("Expected %d, recieved %d", http.StatusOK, resp.StatusCode) | |||
return | |||
} | |||
var session Models.Session | |||
err = Database.DB.First(&session, "user_id = ?", u.ID.String()).Error | |||
if err != nil { | |||
t.Errorf("Expected user record, recieved %s", err.Error()) | |||
return | |||
} | |||
} | |||
func Test_Login_PasswordFails(t *testing.T) { | |||
log.SetOutput(ioutil.Discard) | |||
Database.InitTest() | |||
r := mux.NewRouter() | |||
Api.InitAPIEndpoints(r) | |||
ts := httptest.NewServer(r) | |||
defer ts.Close() | |||
userKey, _ := Seeder.GenerateAesKey() | |||
pubKey := Seeder.GetPubKey() | |||
p, _ := Auth.HashPassword("password") | |||
u := Models.User{ | |||
Username: "test", | |||
Password: p, | |||
AsymmetricPublicKey: Seeder.PublicKey, | |||
AsymmetricPrivateKey: Seeder.EncryptedPrivateKey, | |||
SymmetricKey: base64.StdEncoding.EncodeToString( | |||
Seeder.EncryptWithPublicKey(userKey.Key, pubKey), | |||
), | |||
} | |||
err := Database.CreateUser(&u) | |||
if err != nil { | |||
t.Errorf("Expected nil, recieved %s", err.Error()) | |||
return | |||
} | |||
d := struct { | |||
Username string `json:"username"` | |||
Password string `json:"password"` | |||
}{ | |||
Username: "test", | |||
Password: "password1", | |||
} | |||
jsonStr, _ := json.Marshal(d) | |||
req, _ := http.NewRequest("POST", ts.URL+"/api/v1/login", bytes.NewBuffer(jsonStr)) | |||
req.Header.Set("Content-Type", "application/json") | |||
client := &http.Client{} | |||
resp, err := client.Do(req) | |||
if err != nil { | |||
t.Errorf("Expected nil, recieved %s", err.Error()) | |||
return | |||
} | |||
if resp.StatusCode != http.StatusUnauthorized { | |||
t.Errorf("Expected %d, recieved %d", http.StatusUnauthorized, resp.StatusCode) | |||
return | |||
} | |||
} |
@ -0,0 +1,131 @@ | |||
package Auth_test | |||
import ( | |||
"bytes" | |||
"encoding/base64" | |||
"encoding/json" | |||
"io/ioutil" | |||
"log" | |||
"net/http" | |||
"net/http/cookiejar" | |||
"net/http/httptest" | |||
"net/url" | |||
"sync" | |||
"testing" | |||
"git.tovijaeschke.xyz/tovi/Capsule/Backend/Api" | |||
"git.tovijaeschke.xyz/tovi/Capsule/Backend/Api/Auth" | |||
"git.tovijaeschke.xyz/tovi/Capsule/Backend/Database" | |||
"git.tovijaeschke.xyz/tovi/Capsule/Backend/Database/Seeder" | |||
"git.tovijaeschke.xyz/tovi/Capsule/Backend/Models" | |||
"github.com/gorilla/mux" | |||
) | |||
type Jar struct { | |||
lk sync.Mutex | |||
cookies map[string][]*http.Cookie | |||
} | |||
func Test_Logout(t *testing.T) { | |||
log.SetOutput(ioutil.Discard) | |||
Database.InitTest() | |||
r := mux.NewRouter() | |||
Api.InitAPIEndpoints(r) | |||
ts := httptest.NewServer(r) | |||
defer ts.Close() | |||
userKey, _ := Seeder.GenerateAesKey() | |||
pubKey := Seeder.GetPubKey() | |||
p, _ := Auth.HashPassword("password") | |||
u := Models.User{ | |||
Username: "test", | |||
Password: p, | |||
AsymmetricPublicKey: Seeder.PublicKey, | |||
AsymmetricPrivateKey: Seeder.EncryptedPrivateKey, | |||
SymmetricKey: base64.StdEncoding.EncodeToString( | |||
Seeder.EncryptWithPublicKey(userKey.Key, pubKey), | |||
), | |||
} | |||
err := Database.CreateUser(&u) | |||
if err != nil { | |||
t.Errorf("Expected nil, recieved %s", err.Error()) | |||
return | |||
} | |||
d := struct { | |||
Username string `json:"username"` | |||
Password string `json:"password"` | |||
}{ | |||
Username: "test", | |||
Password: "password", | |||
} | |||
jsonStr, _ := json.Marshal(d) | |||
req, _ := http.NewRequest("POST", ts.URL+"/api/v1/login", bytes.NewBuffer(jsonStr)) | |||
req.Header.Set("Content-Type", "application/json") | |||
client := &http.Client{} | |||
resp, err := client.Do(req) | |||
if err != nil { | |||
t.Errorf("Expected nil, recieved %s", err.Error()) | |||
return | |||
} | |||
if resp.StatusCode != http.StatusOK { | |||
t.Errorf("Expected %d, recieved %d", http.StatusOK, resp.StatusCode) | |||
return | |||
} | |||
var session Models.Session | |||
err = Database.DB.First(&session, "user_id = ?", u.ID.String()).Error | |||
if err != nil { | |||
t.Errorf("Expected session record, recieved %s", err.Error()) | |||
return | |||
} | |||
jar, err := cookiejar.New(nil) | |||
if err != nil { | |||
t.Errorf("Expected nil, recieved %s", err.Error()) | |||
} | |||
url, _ := url.Parse(ts.URL) | |||
jar.SetCookies( | |||
url, | |||
[]*http.Cookie{ | |||
&http.Cookie{ | |||
Name: "session_token", | |||
Value: session.ID.String(), | |||
MaxAge: 300, | |||
}, | |||
}, | |||
) | |||
client = &http.Client{ | |||
Jar: jar, | |||
} | |||
resp, err = client.Get(ts.URL + "/api/v1/logout") | |||
if err != nil { | |||
t.Errorf("Expected user record, recieved %s", err.Error()) | |||
return | |||
} | |||
if resp.StatusCode != http.StatusOK { | |||
t.Errorf("Expected %d, recieved %d", http.StatusOK, resp.StatusCode) | |||
return | |||
} | |||
err = Database.DB.First(&session, "user_id = ?", u.ID.String()).Error | |||
if err == nil { | |||
t.Errorf("Expected no session record, recieved %s", session.UserID) | |||
return | |||
} | |||
} |
@ -0,0 +1,168 @@ | |||
package Auth_test | |||
import ( | |||
"bytes" | |||
"encoding/base64" | |||
"encoding/json" | |||
"io/ioutil" | |||
"log" | |||
"net/http" | |||
"net/http/httptest" | |||
"testing" | |||
"git.tovijaeschke.xyz/tovi/Capsule/Backend/Api" | |||
"git.tovijaeschke.xyz/tovi/Capsule/Backend/Database" | |||
"git.tovijaeschke.xyz/tovi/Capsule/Backend/Database/Seeder" | |||
"git.tovijaeschke.xyz/tovi/Capsule/Backend/Models" | |||
"github.com/gorilla/mux" | |||
) | |||
func Test_Signup(t *testing.T) { | |||
log.SetOutput(ioutil.Discard) | |||
Database.InitTest() | |||
r := mux.NewRouter() | |||
Api.InitAPIEndpoints(r) | |||
ts := httptest.NewServer(r) | |||
defer ts.Close() | |||
userKey, _ := Seeder.GenerateAesKey() | |||
pubKey := Seeder.GetPubKey() | |||
d := struct { | |||
Username string `json:"username"` | |||
Password string `json:"password"` | |||
ConfirmPassword string `json:"confirm_password"` | |||
PubKey string `json:"asymmetric_public_key"` | |||
PrivKey string `json:"asymmetric_private_key"` | |||
SymKey string `json:"symmetric_key"` | |||
}{ | |||
Username: "test", | |||
Password: "password", | |||
ConfirmPassword: "password", | |||
PubKey: Seeder.PublicKey, | |||
PrivKey: Seeder.EncryptedPrivateKey, | |||
SymKey: base64.StdEncoding.EncodeToString( | |||
Seeder.EncryptWithPublicKey(userKey.Key, pubKey), | |||
), | |||
} | |||
jsonStr, _ := json.Marshal(d) | |||
req, _ := http.NewRequest("POST", ts.URL+"/api/v1/signup", bytes.NewBuffer(jsonStr)) | |||
req.Header.Set("Content-Type", "application/json") | |||
client := &http.Client{} | |||
resp, err := client.Do(req) | |||
if err != nil { | |||
t.Errorf("Expected nil, recieved %s", err.Error()) | |||
return | |||
} | |||
if resp.StatusCode != http.StatusNoContent { | |||
t.Errorf("Expected %d, recieved %d", http.StatusNoContent, resp.StatusCode) | |||
return | |||
} | |||
var user Models.User | |||
err = Database.DB.First(&user, "username = ?", "test").Error | |||
if err != nil { | |||
t.Errorf("Expected user record, recieved %s", err.Error()) | |||
return | |||
} | |||
} | |||
func Test_Signup_PasswordMismatchFails(t *testing.T) { | |||
log.SetOutput(ioutil.Discard) | |||
Database.InitTest() | |||
r := mux.NewRouter() | |||
Api.InitAPIEndpoints(r) | |||
ts := httptest.NewServer(r) | |||
defer ts.Close() | |||
userKey, _ := Seeder.GenerateAesKey() | |||
pubKey := Seeder.GetPubKey() | |||
d := struct { | |||
Username string `json:"username"` | |||
Password string `json:"password"` | |||
ConfirmPassword string `json:"confirm_password"` | |||
PubKey string `json:"asymmetric_public_key"` | |||
PrivKey string `json:"asymmetric_private_key"` | |||
SymKey string `json:"symmetric_key"` | |||
}{ | |||
Username: "test", | |||
Password: "password", | |||
ConfirmPassword: "password1", | |||
PubKey: Seeder.PublicKey, | |||
PrivKey: Seeder.EncryptedPrivateKey, | |||
SymKey: base64.StdEncoding.EncodeToString( | |||
Seeder.EncryptWithPublicKey(userKey.Key, pubKey), | |||
), | |||
} | |||
jsonStr, _ := json.Marshal(d) | |||
req, _ := http.NewRequest("POST", ts.URL+"/api/v1/signup", bytes.NewBuffer(jsonStr)) | |||
req.Header.Set("X-Custom-Header", "myvalue") | |||
req.Header.Set("Content-Type", "application/json") | |||
client := &http.Client{} | |||
resp, err := client.Do(req) | |||
if err != nil { | |||
t.Errorf("Expected nil, recieved %s", err.Error()) | |||
return | |||
} | |||
if resp.StatusCode != http.StatusUnprocessableEntity { | |||
t.Errorf("Expected %d, recieved %d", http.StatusUnprocessableEntity, resp.StatusCode) | |||
return | |||
} | |||
} | |||
func Test_Signup_MissingDataFails(t *testing.T) { | |||
log.SetOutput(ioutil.Discard) | |||
Database.InitTest() | |||
r := mux.NewRouter() | |||
Api.InitAPIEndpoints(r) | |||
ts := httptest.NewServer(r) | |||
defer ts.Close() | |||
d := struct { | |||
Username string `json:"username"` | |||
Password string `json:"password"` | |||
ConfirmPassword string `json:"confirm_password"` | |||
PubKey string `json:"asymmetric_public_key"` | |||
PrivKey string `json:"asymmetric_private_key"` | |||
SymKey string `json:"symmetric_key"` | |||
}{ | |||
Username: "test", | |||
Password: "password", | |||
ConfirmPassword: "password", | |||
PubKey: "", | |||
PrivKey: "", | |||
SymKey: "", | |||
} | |||
jsonStr, _ := json.Marshal(d) | |||
req, _ := http.NewRequest("POST", ts.URL+"/api/v1/signup", bytes.NewBuffer(jsonStr)) | |||
req.Header.Set("X-Custom-Header", "myvalue") | |||
req.Header.Set("Content-Type", "application/json") | |||
client := &http.Client{} | |||
resp, err := client.Do(req) | |||
if err != nil { | |||
t.Errorf("Expected nil, recieved %s", err.Error()) | |||
} | |||
if resp.StatusCode != http.StatusUnprocessableEntity { | |||
t.Errorf("Expected %d, recieved %d", http.StatusUnprocessableEntity, resp.StatusCode) | |||
} | |||
} |
@ -0,0 +1,16 @@ | |||
FROM golang:1.19-alpine | |||
RUN mkdir -p /go/src/git.tovijaeschke.xyz/Capsule/Backend | |||
COPY ./ /go/src/git.tovijaeschke.xyz/Capsule/Backend | |||
WORKDIR /go/src/git.tovijaeschke.xyz/Capsule/Backend | |||
# For "go test" | |||
RUN apk add gcc libc-dev | |||
RUN go mod download | |||
RUN go build -o /go/bin/capsule-server main.go | |||
CMD [ "/go/bin/capsule-server" ] |
@ -0,0 +1,49 @@ | |||
version: "3" | |||
services: | |||
server: | |||
build: | |||
context: ./Backend | |||
ports: | |||
- "8080:8080" | |||
volumes: | |||
- "./Backend:/app" | |||
links: | |||
- postgres | |||
- postgres-testing | |||
depends_on: | |||
postgres: | |||
condition: service_healthy | |||
depends_on: | |||
postgres-testing: | |||
condition: service_healthy | |||
postgres: | |||
image: postgres:14.5 | |||
ports: | |||
- "54321:5432" | |||
environment: | |||
POSTGRES_DB: capsule | |||
POSTGRES_PASSWORD: password | |||
volumes: | |||
- /var/lib/postgres | |||
healthcheck: | |||
test: ["CMD-SHELL", "pg_isready -U postgres"] | |||
interval: 5s | |||
timeout: 5s | |||
retries: 5 | |||
postgres-testing: | |||
image: postgres:14.5 | |||
ports: | |||
- "54322:5432" | |||
environment: | |||
POSTGRES_DB: capsule-testing | |||
POSTGRES_PASSWORD: password | |||
tmpfs: | |||
- /var/lib/mysql | |||
healthcheck: | |||
test: ["CMD-SHELL", "pg_isready -U postgres"] | |||
interval: 5s | |||
timeout: 5s | |||
retries: 5 | |||
@ -0,0 +1,3 @@ | |||
#!/bin/sh | |||
docker-compose exec server sh -c "cd /app && go test -v ./Api/Auth" |