adding attach app use case

This commit is contained in:
Roland Osborne 2022-01-17 21:48:42 -08:00
parent 4fd8bd9b45
commit 51c0864817
8 changed files with 108 additions and 17 deletions

View File

@ -13,11 +13,6 @@ import (
"net/http"
)
func AddAccountApp(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json; charset=UTF-8")
w.WriteHeader(http.StatusOK)
}
func AddAccountAuthentication(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json; charset=UTF-8")
w.WriteHeader(http.StatusOK)

View File

@ -4,12 +4,14 @@ import (
"net/http"
"crypto/sha256"
"encoding/hex"
"gorm.io/gorm"
"databag/internal/store"
)
func AddAccount(w http.ResponseWriter, r *http.Request) {
if _, err := BearerAccountToken(r); err != nil {
token, res := BearerAccountToken(r);
if res != nil || token.TokenType != "create" {
LogMsg("authentication failed")
w.WriteHeader(http.StatusUnauthorized)
return
@ -51,8 +53,19 @@ func AddAccount(w http.ResponseWriter, r *http.Request) {
Password: password,
Guid: fingerprint,
};
if res := store.DB.Create(&account).Error; res != nil {
LogMsg("failed to store account")
// save account and delete token
err = store.DB.Transaction(func(tx *gorm.DB) error {
if res := store.DB.Create(&account).Error; res != nil {
return res;
}
if res := store.DB.Delete(token).Error; res != nil {
return res;
}
return nil;
});
if err != nil {
LogMsg("failed to create account");
w.WriteHeader(http.StatusInternalServerError)
return
}

View File

@ -0,0 +1,41 @@
package databag
import (
"net/http"
"time"
"encoding/hex"
"databag/internal/store"
"github.com/theckman/go-securerandom"
)
func AddAccountApp(w http.ResponseWriter, r *http.Request) {
id, err := AccountLogin(r)
if err != nil {
LogMsg("failed to login")
w.WriteHeader(http.StatusUnauthorized);
return
}
data, res := securerandom.Bytes(4)
if res != nil {
LogMsg("failed to generate token")
w.WriteHeader(http.StatusInternalServerError)
return
}
token := store.AccountToken{
AccountID: id,
TokenType: "attach",
Token: hex.EncodeToString(data),
Expires: time.Now().Unix() + APP_ATTACHEXPIRE,
};
if store.DB.Create(&token).Error != nil {
LogMsg("failed to store token")
w.WriteHeader(http.StatusInternalServerError)
return
}
WriteResponse(w, data);
}

View File

@ -2,6 +2,8 @@ package databag
import (
"net/http"
"encoding/hex"
"time"
"databag/internal/store"
"github.com/theckman/go-securerandom"
)
@ -14,20 +16,26 @@ func AddNodeAccount(w http.ResponseWriter, r *http.Request) {
return
}
data, err := securerandom.Base64OfBytes(32)
data, err := securerandom.Bytes(16)
if err != nil {
LogMsg("failed to generate token");
w.WriteHeader(http.StatusInternalServerError);
return
}
token := hex.EncodeToString(data)
token := store.AccountToken{TokenType: "create", Token: data };
if res := store.DB.Create(&token).Error; res != nil {
accountToken := store.AccountToken{
TokenType: "create",
Token: token,
Expires: time.Now().Unix() + APP_CREATEEXPIRE,
};
if store.DB.Create(&accountToken).Error != nil {
LogMsg("failed to store token");
w.WriteHeader(http.StatusInternalServerError);
return
}
WriteResponse(w, data);
WriteResponse(w, token);
}

View File

@ -11,9 +11,9 @@ type accountUsername struct {
func GetAccountUsername(w http.ResponseWriter, r *http.Request) {
_, err := BearerAccountToken(r);
if err != nil {
LogMsg("authentication failed")
token, err := BearerAccountToken(r);
if err != nil || (token.TokenType != "create" && token.TokenType != "reset") {
LogMsg("invalid token")
w.WriteHeader(http.StatusUnauthorized)
return
}

View File

@ -2,4 +2,5 @@ package databag
const APP_BODYLIMIT = 1048576
const APP_VERSION = "0.0.1"
const APP_ATTACHEXPIRE = 300
const APP_CREATEEXPIRE = 86400

View File

@ -3,12 +3,19 @@ package databag
import (
"errors"
"strings"
"time"
"net/http"
"encoding/base64"
"golang.org/x/crypto/bcrypt"
"databag/internal/store"
)
type accountLogin struct {
ID uint
Password []byte
Expires int64
}
func AdminLogin(r *http.Request) bool {
// extract request auth
@ -36,6 +43,28 @@ func AdminLogin(r *http.Request) bool {
return true;
}
func AccountLogin(r *http.Request) (uint, error) {
// extract request auth
username, password, ok := r.BasicAuth();
if !ok || username == "" || password == "" {
return 0, errors.New("invalid login")
}
// find account
var account accountLogin
if store.DB.Model(&Account{}).Where("Username = ?", username).First(&account).Error != nil {
return 0, errors.New("username not found");
}
// compare password
if bcrypt.CompareHashAndPassword(account.Password, []byte(password)) != nil {
return 0, errors.New("invalid password");
}
return account.ID, nil
}
func BearerAccountToken(r *http.Request) (store.AccountToken, error) {
// parse bearer authentication
@ -45,6 +74,9 @@ func BearerAccountToken(r *http.Request) (store.AccountToken, error) {
// find token record
var accountToken store.AccountToken
err := store.DB.Where("token = ?", token).First(&accountToken).Error
if accountToken.Expires < time.Now().Unix() {
return accountToken, errors.New("expired token")
}
return accountToken, err
}
@ -76,7 +108,7 @@ func BasicCredentials(r *http.Request) (string, []byte, error) {
password, err = bcrypt.GenerateFromPassword([]byte(login[1]), bcrypt.DefaultCost)
if err != nil {
LogMsg("failed to hash password")
return username, password, err
return username, password, err
}
return username, password, nil

View File

@ -40,6 +40,7 @@ type AccountToken struct {
AccountID uint `gorm:"index"`
TokenType string `gorm:"not null; `
Token string `gorm:"not null;uniqueIndex"`
Expires int64 `gorm:"not null"`
Created int64 `gorm:"autoCreateTime"`
Account Account
}