refactoring, implement db layer

This commit is contained in:
santhoshivan23 2023-06-05 23:10:27 +05:30
parent f5039be461
commit 2c339a6bfd
7 changed files with 92 additions and 24 deletions

View file

@ -5,8 +5,10 @@ import (
"encoding/json" "encoding/json"
"errors" "errors"
"fmt" "fmt"
"math/rand"
"net/http" "net/http"
"regexp" "regexp"
"strings"
"time" "time"
"github.com/gorilla/mux" "github.com/gorilla/mux"
@ -25,6 +27,17 @@ import (
"github.com/matrix-org/dendrite/userapi/api" "github.com/matrix-org/dendrite/userapi/api"
) )
func generateRandomToken(length int) string {
allowedChars := "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_"
rand.Seed(time.Now().UnixNano())
var sb strings.Builder
for i := 0; i < length; i++ {
randomIndex := rand.Intn(len(allowedChars))
sb.WriteByte(allowedChars[randomIndex])
}
return sb.String()
}
func AdminCreateNewRegistrationToken(req *http.Request, cfg *config.ClientAPI, rsAPI roomserverAPI.ClientRoomserverAPI) util.JSONResponse { func AdminCreateNewRegistrationToken(req *http.Request, cfg *config.ClientAPI, rsAPI roomserverAPI.ClientRoomserverAPI) util.JSONResponse {
if !cfg.RegistrationRequiresToken { if !cfg.RegistrationRequiresToken {
return util.MatrixErrorResponse( return util.MatrixErrorResponse(
@ -47,13 +60,31 @@ func AdminCreateNewRegistrationToken(req *http.Request, cfg *config.ClientAPI, r
"Failed to decode request body:", "Failed to decode request body:",
) )
} }
token := request.Token token := request.Token
if len(token) == 0 || len(token) > 64 { usesAllowed := request.UsesAllowed
expiryTime := request.ExpiryTime
length := request.Length
if len(token) == 0 {
// Token not present in request body. Hence, generate a random token.
if !(length > 0 && length <= 64) {
return util.MatrixErrorResponse(
http.StatusBadRequest,
string(spec.ErrorInvalidParam),
"length must be greater than zero and not greater than 64")
}
token = generateRandomToken(int(length))
}
if len(token) > 64 {
//Token present in request body, but is too long.
return util.MatrixErrorResponse( return util.MatrixErrorResponse(
http.StatusBadRequest, http.StatusBadRequest,
string(spec.ErrorInvalidParam), string(spec.ErrorInvalidParam),
"token must not be empty and must not be longer than 64") "token must not be longer than 64")
} }
isTokenValid, _ := regexp.MatchString("^[[:ascii:][:digit:]_]*$", token) isTokenValid, _ := regexp.MatchString("^[[:ascii:][:digit:]_]*$", token)
if !isTokenValid { if !isTokenValid {
return util.MatrixErrorResponse( return util.MatrixErrorResponse(
@ -61,16 +92,8 @@ func AdminCreateNewRegistrationToken(req *http.Request, cfg *config.ClientAPI, r
string(spec.ErrorInvalidParam), string(spec.ErrorInvalidParam),
"token must consist only of characters matched by the regex [A-Za-z0-9-_]") "token must consist only of characters matched by the regex [A-Za-z0-9-_]")
} }
length := request.Length // At this point, we have a valid token, either through request body or through random generation.
if !(length > 0 && length <= 64) {
return util.MatrixErrorResponse(
http.StatusBadRequest,
string(spec.ErrorInvalidParam),
"length must be greater than zero and not greater than 64")
}
// TODO: Generate Random Token
// token = GenerateRandomToken(length)
usesAllowed := request.UsesAllowed
if usesAllowed < 0 { if usesAllowed < 0 {
return util.MatrixErrorResponse( return util.MatrixErrorResponse(
http.StatusBadRequest, http.StatusBadRequest,
@ -78,7 +101,6 @@ func AdminCreateNewRegistrationToken(req *http.Request, cfg *config.ClientAPI, r
"uses_allowed must be a non-negative integer or null") "uses_allowed must be a non-negative integer or null")
} }
expiryTime := request.ExpiryTime
if expiryTime != 0 && expiryTime < time.Now().UnixNano()/int64(time.Millisecond) { if expiryTime != 0 && expiryTime < time.Now().UnixNano()/int64(time.Millisecond) {
return util.MatrixErrorResponse( return util.MatrixErrorResponse(
http.StatusBadRequest, http.StatusBadRequest,

View file

@ -46,8 +46,14 @@ func (r *Admin) PerformAdminCreateRegistrationToken(
ctx context.Context, token string, ctx context.Context, token string,
usesAllowed, pending, completed int32, usesAllowed, pending, completed int32,
expiryTime int64) (bool, error) { expiryTime int64) (bool, error) {
//TODO: Implement logic to save token in DB. exists, err := r.DB.RegistrationTokenExists(ctx, token)
//Return false, if token already exists, else true. if err != nil {
return false, err
}
if exists {
fmt.Println(fmt.Sprintf("token: %s already exists", token))
return false, fmt.Errorf("token: %s already exists", token)
}
return true, nil return true, nil
} }

View file

@ -27,6 +27,7 @@ import (
) )
type Database interface { type Database interface {
RegistrationTokenExists(ctx context.Context, token string) (bool, error)
// Do we support processing input events for more than one room at a time? // Do we support processing input events for more than one room at a time?
SupportsConcurrentRoomInputs() bool SupportsConcurrentRoomInputs() bool
// RoomInfo returns room information for the given room ID, or nil if there is no room. // RoomInfo returns room information for the given room ID, or nil if there is no room.

View file

@ -0,0 +1,27 @@
package postgres
import (
"context"
"database/sql"
"fmt"
)
const registrationTokensSchema = `
CREATE TABLE IF NOT EXISTS roomserver_registration_tokens (
token TEXT PRIMARY KEY,
pending BIGINT,
completed BIGINT,
uses_allowed BIGINT,
expiry_time BIGINT
);
`
func CreateRegistrationTokensTable(db *sql.DB) error {
_, err := db.Exec(registrationTokensSchema)
return err
}
func RegistrationTokenExists(ctx context.Context, tx *sql.Tx, token string) (bool, error) {
fmt.Println("here!!")
return true, nil
}

View file

@ -92,6 +92,9 @@ func executeMigration(ctx context.Context, db *sql.DB) error {
} }
func (d *Database) create(db *sql.DB) error { func (d *Database) create(db *sql.DB) error {
if err := CreateRegistrationTokensTable(db); err != nil {
return err
}
if err := CreateEventStateKeysTable(db); err != nil { if err := CreateEventStateKeysTable(db); err != nil {
return err return err
} }

View file

@ -46,15 +46,20 @@ type Database struct {
// EventDatabase contains all tables needed to work with events // EventDatabase contains all tables needed to work with events
type EventDatabase struct { type EventDatabase struct {
DB *sql.DB DB *sql.DB
Cache caching.RoomServerCaches Cache caching.RoomServerCaches
Writer sqlutil.Writer Writer sqlutil.Writer
EventsTable tables.Events EventsTable tables.Events
EventJSONTable tables.EventJSON EventJSONTable tables.EventJSON
EventTypesTable tables.EventTypes EventTypesTable tables.EventTypes
EventStateKeysTable tables.EventStateKeys EventStateKeysTable tables.EventStateKeys
PrevEventsTable tables.PreviousEvents PrevEventsTable tables.PreviousEvents
RedactionsTable tables.Redactions RedactionsTable tables.Redactions
RegistrationTokensTable tables.RegistrationTokens
}
func (d *Database) RegistrationTokenExists(ctx context.Context, token string) (bool, error) {
return d.RegistrationTokensTable.RegistrationTokenExists(ctx, nil, token)
} }
func (d *Database) SupportsConcurrentRoomInputs() bool { func (d *Database) SupportsConcurrentRoomInputs() bool {

View file

@ -19,6 +19,10 @@ type EventJSONPair struct {
EventJSON []byte EventJSON []byte
} }
type RegistrationTokens interface {
RegistrationTokenExists(ctx context.Context, tx *sql.Tx, token string) (bool, error)
}
type EventJSON interface { type EventJSON interface {
// Insert the event JSON. On conflict, replace the event JSON with the new value (for redactions). // Insert the event JSON. On conflict, replace the event JSON with the new value (for redactions).
InsertEventJSON(ctx context.Context, tx *sql.Tx, eventNID types.EventNID, eventJSON []byte) error InsertEventJSON(ctx context.Context, tx *sql.Tx, eventNID types.EventNID, eventJSON []byte) error