actions.go 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  1. package main
  2. import (
  3. "context"
  4. "encoding/hex"
  5. "errors"
  6. "math/rand"
  7. "net/http"
  8. "sparrow/pkg/models"
  9. "sparrow/pkg/rpcs"
  10. "sparrow/pkg/server"
  11. "sparrow/pkg/token"
  12. "github.com/opentracing/opentracing-go/ext"
  13. "github.com/opentracing/opentracing-go"
  14. "github.com/martini-contrib/render"
  15. )
  16. const (
  17. ErrOK = 0
  18. ErrSystemFault = 10001
  19. ErrDeviceNotFound = 10002
  20. ErrWrongSecret = 10003
  21. ErrProtocolNotSuported = 10004
  22. )
  23. func renderError(code int, err error) Common {
  24. result := Common{}
  25. result.Code = code
  26. result.Message = err.Error()
  27. server.Log.Error(err.Error())
  28. return result
  29. }
  30. // DeviceRegisterArgs device register args
  31. type DeviceRegisterArgs struct {
  32. ProductKey string `json:"product_key" binding:"required"`
  33. DeviceCode string `json:"device_code" binding:"required"`
  34. Version string `json:"version" binding:"required"`
  35. ModuleName string `json:"module" binding:"required"`
  36. }
  37. // DeviceAuthArgs device authentication args
  38. type DeviceAuthArgs struct {
  39. DeviceId int64 `json:"device_id" binding:"required"`
  40. DeviceSecret string `json:"device_secret" binding:"required"`
  41. Protocol string `json:"protocol" binding:"required"`
  42. }
  43. // RegisterDevice 设备激活
  44. func RegisterDevice(args DeviceRegisterArgs, r render.Render) {
  45. server.Log.Printf("ACTION RegisterDevice, args:: %v ", args)
  46. span, ctx := opentracing.StartSpanFromContext(context.Background(), "RegisterDevice")
  47. defer span.Finish()
  48. rpcargs := &rpcs.ArgsDeviceRegister{
  49. ProductKey: args.ProductKey,
  50. DeviceCode: args.DeviceCode,
  51. DeviceVersion: args.Version,
  52. ModuleName: args.ModuleName,
  53. }
  54. rpcargs.SpanCarrier = make(map[string]string)
  55. device := &models.Device{}
  56. ext.SpanKindRPCClient.Set(span)
  57. // span.Tracer().Inject(
  58. // span.Context(),
  59. // opentracing.TextMap,
  60. // opentracing.TextMapCarrier(rpcargs.SpanCarrier),
  61. // )
  62. err := server.RPCCallByName(ctx, "registry", "Registry.RegisterDevice", rpcargs, device)
  63. if err != nil {
  64. r.JSON(http.StatusOK, renderError(ErrSystemFault, err))
  65. return
  66. }
  67. server.Log.Infof("register device success: %v", device)
  68. result := DeviceRegisterResponse{}
  69. result.Data = DeviceRegisterData{
  70. DeviceId: int64(device.ID),
  71. DeviceSecret: device.DeviceSecret,
  72. DeviceKey: device.DeviceKey,
  73. DeviceIdentifier: device.DeviceIdentifier,
  74. }
  75. r.JSON(http.StatusOK, result)
  76. return
  77. }
  78. // AuthDevice device auth
  79. func AuthDevice(args DeviceAuthArgs, r render.Render) {
  80. server.Log.Printf("ACTION AuthDevice, args:: %v", args)
  81. device := &models.Device{}
  82. arg := &rpcs.ArgsDeviceAuth{
  83. DeviceID: args.DeviceId,
  84. }
  85. arg.SpanCarrier = make(map[string]string)
  86. span, ctx := opentracing.StartSpanFromContext(context.Background(), "AuthDevice")
  87. defer span.Finish()
  88. ext.SpanKindRPCClient.Set(span)
  89. // span.Tracer().Inject(
  90. // span.Context(),
  91. // opentracing.TextMap,
  92. // opentracing.TextMapCarrier(arg.SpanCarrier),
  93. // )
  94. err := server.RPCCallByName(ctx, "registry", "Registry.FindDeviceById", arg, device)
  95. if err != nil {
  96. r.JSON(http.StatusOK, renderError(ErrDeviceNotFound, err))
  97. return
  98. }
  99. if device.DeviceSecret != args.DeviceSecret {
  100. // device secret is wrong.
  101. r.JSON(http.StatusOK, renderError(ErrWrongSecret, errors.New("wrong device secret.")))
  102. return
  103. }
  104. hepler := token.NewHelper(*confRedisHost)
  105. token, err := hepler.GenerateToken(uint64(int64(device.ID)))
  106. if err != nil {
  107. r.JSON(http.StatusOK, renderError(ErrSystemFault, err))
  108. return
  109. }
  110. var hosts []string
  111. switch args.Protocol {
  112. case "http":
  113. hosts, err = server.GetServerHosts(args.Protocol+"access", "httphost")
  114. case "mqtt":
  115. hosts, err = server.GetServerHosts(args.Protocol+"access", "tcphost")
  116. case "coap":
  117. hosts, err = server.GetServerHosts(args.Protocol+"access", "udphost")
  118. default:
  119. err = errors.New("unsuported protocol: " + args.Protocol)
  120. }
  121. if err != nil {
  122. r.JSON(http.StatusOK, renderError(ErrProtocolNotSuported, err))
  123. return
  124. }
  125. // just get a random host
  126. host := hosts[rand.Intn(len(hosts))]
  127. result := DeviceAuthResponse{}
  128. result.Data = DeviceAuthData{
  129. AccessToken: hex.EncodeToString(token),
  130. AccessAddr: host,
  131. }
  132. server.Log.Infof("auth device success: %v, token: %x, access: %v", device, token, host)
  133. r.JSON(http.StatusOK, result)
  134. return
  135. }