diff options
| author | Andrew <saintruler@gmail.com> | 2021-04-28 14:37:37 +0400 |
|---|---|---|
| committer | Andrew <saintruler@gmail.com> | 2021-04-28 14:37:37 +0400 |
| commit | 9c4348d402441dc8bac2cb3ecc41efc825307f0b (patch) | |
| tree | b4635d914d49e7f59275c21afe338fc08d6534df | |
| parent | 3f672bf327b949a8335fb53b4649bdeef90fdd98 (diff) | |
Added Added view for getting keys of registered users.
| -rw-r--r-- | http-server/database.go | 17 | ||||
| -rw-r--r-- | http-server/main.go | 103 | ||||
| -rw-r--r-- | http-tester.py | 24 |
3 files changed, 128 insertions, 16 deletions
diff --git a/http-server/database.go b/http-server/database.go index d13e8c1..e79b3e7 100644 --- a/http-server/database.go +++ b/http-server/database.go @@ -2,6 +2,7 @@ package main import ( "database/sql" + "errors" _ "github.com/mattn/go-sqlite3" ) @@ -32,6 +33,22 @@ func (conn *SQLConnection) checkUserRegistered(username string) (bool, error) { return false, nil } +func (conn *SQLConnection) getUserKey(username string) (string, error) { + query := "SELECT key FROM users WHERE username = ?" + result, err := conn.db.Query(query, username) + if err != nil { + return "", err + } + if result.Next() { + var key string + _ = result.Scan(&key) + _ = result.Close() + return key, nil + } else { + return "", errors.New("user not found") + } +} + func (conn *SQLConnection) saveMessage(message Message) error { var err error diff --git a/http-server/main.go b/http-server/main.go index af7d4be..55306e8 100644 --- a/http-server/main.go +++ b/http-server/main.go @@ -2,6 +2,7 @@ package main import ( "encoding/json" + "errors" "fmt" "io" "net/http" @@ -15,8 +16,9 @@ type Response struct { } type Request struct { - User string - Data string + User string + Data string + Signature string } type Message struct { @@ -67,10 +69,6 @@ func serverError(w http.ResponseWriter) error { }) } -func index(w http.ResponseWriter, r *http.Request) { - _, _ = fmt.Fprintf(w, "Hello there") -} - func register(w http.ResponseWriter, r *http.Request) { if r.Method != http.MethodPost { _ = methodNotAllowedResponse(w) @@ -88,19 +86,19 @@ func register(w http.ResponseWriter, r *http.Request) { return } - // TODO(andrew): Добавить проверку действительности ключа - if false { + if userRegistered { w.WriteHeader(http.StatusBadRequest) _ = jsonResponse(w, Response{ - Message: "Указанный ключ не является действительным", + Message: "Пользователь с таким именем уже зарегистрирован", }) return } - if userRegistered { + // TODO(andrew): Добавить проверку действительности ключа + if false { w.WriteHeader(http.StatusBadRequest) _ = jsonResponse(w, Response{ - Message: "Пользователь с таким именем уже зарегистрирован", + Message: "Указанный ключ не является действительным", }) return } @@ -119,6 +117,27 @@ func register(w http.ResponseWriter, r *http.Request) { }) } +func handleAuthentication(req Request) (error, error) { + userRegistered, dbError := db.checkUserRegistered(req.User) + if dbError != nil { + return nil, dbError + } + + if !userRegistered { + return errors.New("такой пользователь не зарегистрирован"), nil + } + + key, err := db.getUserKey(req.User) + if err != nil { + return nil, err + } + + // TODO(andrew): Добавить проверку подписи req.Signature + fmt.Sprintf("%s", key) + + return nil, nil +} + func sendMessage(w http.ResponseWriter, r *http.Request) { if r.Method != http.MethodPost { _ = methodNotAllowedResponse(w) @@ -130,14 +149,18 @@ func sendMessage(w http.ResponseWriter, r *http.Request) { return } - // TODO(andrew): Добавить аутентификацию - if false { + authErr, dbErr := handleAuthentication(req) + if authErr != nil { w.WriteHeader(http.StatusForbidden) _ = jsonResponse(w, Response{ Message: "Запрос не прошёл аутентификацию", }) return } + if dbErr != nil { + _ = serverError(w) + return + } msg := Message{ User: req.User, @@ -170,14 +193,18 @@ func pollMessages(w http.ResponseWriter, r *http.Request) { return } - // TODO(andrew): Добавить аутентификацию - if false { + authErr, dbErr := handleAuthentication(req) + if authErr != nil { w.WriteHeader(http.StatusForbidden) _ = jsonResponse(w, Response{ Message: "Запрос не прошёл аутентификацию", }) return } + if dbErr != nil { + _ = serverError(w) + return + } timestamp, err := strconv.ParseInt(req.Data, 10, 64) if err != nil { @@ -200,6 +227,50 @@ func pollMessages(w http.ResponseWriter, r *http.Request) { }) } +func getUserKey(w http.ResponseWriter, r *http.Request) { + if r.Method != http.MethodPost { + _ = methodNotAllowedResponse(w) + return + } + + req, err := parseRequest(w, r) + if err != nil { + return + } + + authErr, dbErr := handleAuthentication(req) + if authErr != nil { + w.WriteHeader(http.StatusForbidden) + _ = jsonResponse(w, Response{ + Message: "Запрос не прошёл аутентификацию", + }) + return + } + if dbErr != nil { + _ = serverError(w) + return + } + + userRegistered, err := db.checkUserRegistered(req.Data) + if !userRegistered { + w.WriteHeader(http.StatusBadRequest) + _ = jsonResponse(w, Response{ + Message: "Пользователь с таким именем не зарегистрирован", + }) + return + } + + key, err := db.getUserKey(req.Data) + if err != nil { + _ = serverError(w) + return + } + + _ = jsonResponse(w, Response{ + Message: key, + }) +} + var db SQLConnection func main() { @@ -209,10 +280,10 @@ func main() { os.Exit(1) } - http.HandleFunc("/", index) http.HandleFunc("/api/register", register) http.HandleFunc("/api/sendMessage", sendMessage) http.HandleFunc("/api/pollMessages", pollMessages) + http.HandleFunc("/api/getUserKey", getUserKey) err = http.ListenAndServe("localhost:8080", nil) if err != nil { fmt.Println(err) diff --git a/http-tester.py b/http-tester.py new file mode 100644 index 0000000..28206dc --- /dev/null +++ b/http-tester.py @@ -0,0 +1,24 @@ +from hashlib import sha256 +from base64 import b64encode +import json +import requests + + +URL = "http://localhost:8080/api" + + +def sign_data(data): + dump = json.dumps(data, separators=[",", ":"]) + payload = b64encode(dump.encode()) + signature = sha256(payload).hexdigest() + return f"{payload.decode()}.{signature}" + + +def test_get_user_key(): + data = { + "user": "ivan", + "data": "andrew" + } + + signed_data = sign_data(data) + requests.post(f"{URL}/register", data=signed_data) |