You can not 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.4KB

  1. package main
  2. import (
  3. "encoding/json"
  4. "errors"
  5. "fmt"
  6. "regexp"
  7. "github.com/gorilla/websocket"
  8. )
  9. const (
  10. MSG_TYPE_AUTH string = "auth"
  11. MSG_TYPE_SET_ID string = "set-id"
  12. MSG_TYPE_INVALID_HOST string = "invalid-host"
  13. MSG_TYPE_FULFILL string = "fulfill"
  14. )
  15. type AuthRequestClient struct {
  16. conn *websocket.Conn
  17. app *App
  18. }
  19. type AuthRequestProtocolMessage struct {
  20. MessageType string `json:"type"`
  21. Parameters map[string]string `json:"parameters"`
  22. }
  23. func (c *AuthRequestClient) ReceiveRequest() (*AuthRequest, error) {
  24. message, err := c.receiveProtocolMessage()
  25. if err != nil {
  26. return nil, err
  27. }
  28. if message.MessageType != MSG_TYPE_AUTH {
  29. return nil, errors.New(
  30. fmt.Sprintf(
  31. "Wrong protocol message type, expected message of type \"%s\", got \"%s\"",
  32. MSG_TYPE_AUTH,
  33. message.MessageType,
  34. ),
  35. )
  36. }
  37. host, ok := message.Parameters["host"]
  38. if !ok || !validHost(host) {
  39. response := &AuthRequestProtocolMessage{
  40. MessageType: MSG_TYPE_INVALID_HOST,
  41. Parameters: make(map[string]string),
  42. }
  43. c.conn.WriteJSON(response)
  44. // Invalid or no host provided, let's try again
  45. return c.ReceiveRequest()
  46. }
  47. r := &AuthRequest{
  48. Client: c,
  49. Instance: host,
  50. }
  51. (*c.app.Logger).Info("Returning AuthRequest")
  52. return r, nil
  53. }
  54. func (c *AuthRequestClient) receiveProtocolMessage() (*AuthRequestProtocolMessage, error) {
  55. _, message, err := c.conn.ReadMessage()
  56. (*c.app.Logger).Info("Read message")
  57. if err != nil {
  58. return nil, err
  59. }
  60. protocolMessage := &AuthRequestProtocolMessage{}
  61. err = json.Unmarshal(message, protocolMessage)
  62. if err != nil {
  63. return nil, err
  64. }
  65. return protocolMessage, nil
  66. }
  67. func (c *AuthRequestClient) PropagateID(ID string) error {
  68. message := &AuthRequestProtocolMessage{
  69. MessageType: MSG_TYPE_SET_ID,
  70. Parameters: map[string]string{
  71. "id": ID,
  72. },
  73. }
  74. return c.conn.WriteJSON(message)
  75. }
  76. func (c *AuthRequestClient) Close() {
  77. c.conn.Close()
  78. }
  79. func (c *AuthRequestClient) FulFillRequest(token *AuthToken) error {
  80. message := &AuthRequestProtocolMessage{
  81. MessageType: MSG_TYPE_FULFILL,
  82. Parameters: map[string]string{
  83. "token": token.Token,
  84. },
  85. }
  86. return c.conn.WriteJSON(message)
  87. }
  88. func validHost(host string) bool {
  89. 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])$`)
  90. if re.MatchString(host) {
  91. return true
  92. }
  93. return false
  94. }