You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

124 lines
2.4 KiB
Go

package main
import (
"encoding/json"
"errors"
"fmt"
"regexp"
"github.com/gorilla/websocket"
)
const (
MSG_TYPE_AUTH string = "auth"
MSG_TYPE_SET_ID string = "set-id"
MSG_TYPE_INVALID_HOST string = "invalid-host"
MSG_TYPE_FULFILL string = "fulfill"
)
type AuthRequestClient struct {
conn *websocket.Conn
app *App
}
type AuthRequestProtocolMessage struct {
MessageType string `json:"type"`
Parameters map[string]string `json:"parameters"`
}
func (c *AuthRequestClient) ReceiveRequest() (*AuthRequest, error) {
message, err := c.receiveProtocolMessage()
if err != nil {
return nil, err
}
if message.MessageType != MSG_TYPE_AUTH {
return nil, errors.New(
fmt.Sprintf(
"Wrong protocol message type, expected message of type \"%s\", got \"%s\"",
MSG_TYPE_AUTH,
message.MessageType,
),
)
}
host, ok := message.Parameters["host"]
if !ok || !validHost(host) {
response := &AuthRequestProtocolMessage{
MessageType: MSG_TYPE_INVALID_HOST,
Parameters: make(map[string]string),
}
c.conn.WriteJSON(response)
// Invalid or no host provided, let's try again
return c.ReceiveRequest()
}
r := &AuthRequest{
Client: c,
Instance: host,
}
(*c.app.Logger).Info("Returning AuthRequest")
return r, nil
}
func (c *AuthRequestClient) receiveProtocolMessage() (*AuthRequestProtocolMessage, error) {
_, message, err := c.conn.ReadMessage()
(*c.app.Logger).Info("Read message")
if err != nil {
return nil, err
}
protocolMessage := &AuthRequestProtocolMessage{}
err = json.Unmarshal(message, protocolMessage)
if err != nil {
return nil, err
}
return protocolMessage, nil
}
func (c *AuthRequestClient) PropagateID(ID string) error {
message := &AuthRequestProtocolMessage{
MessageType: MSG_TYPE_SET_ID,
Parameters: map[string]string{
"id": ID,
},
}
return c.conn.WriteJSON(message)
}
func (c *AuthRequestClient) Close() {
c.conn.Close()
}
func (c *AuthRequestClient) FulFillRequest(token *AuthToken) error {
message := &AuthRequestProtocolMessage{
MessageType: MSG_TYPE_FULFILL,
Parameters: map[string]string{
"token": token.Token,
},
}
return c.conn.WriteJSON(message)
}
func validHost(host string) bool {
re, _ := regexp.Compile(`^(([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]*[a-zA-Z0-9])\.)*([A-Za-z0-9]|[A-Za-z0-9][A-Za-z0-9\-]*[A-Za-z0-9])$`)
if re.MatchString(host) {
return true
}
return false
}