mirror of
https://github.com/matrix-org/dendrite.git
synced 2026-01-16 02:23:10 -06:00
refactoring, implement db layer
This commit is contained in:
parent
f5039be461
commit
2c339a6bfd
|
|
@ -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,
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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.
|
||||||
|
|
|
||||||
27
roomserver/storage/postgres/registration_tokens_table.go
Normal file
27
roomserver/storage/postgres/registration_tokens_table.go
Normal 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
|
||||||
|
}
|
||||||
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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 {
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue