registry.go 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546
  1. package main
  2. import (
  3. "errors"
  4. "flag"
  5. "fmt"
  6. "sparrow/pkg/generator"
  7. "sparrow/pkg/models"
  8. "sparrow/pkg/rpcs"
  9. )
  10. const (
  11. flagAESKey = "aeskey"
  12. )
  13. var confAESKey = flag.String(flagAESKey, "", "use your own aes encryting key.")
  14. type Registry struct {
  15. keygen *generator.KeyGenerator
  16. }
  17. func NewRegistry() (*Registry, error) {
  18. gen, err := generator.NewKeyGenerator(*confAESKey)
  19. if err != nil {
  20. return nil, err
  21. }
  22. return &Registry{
  23. keygen: gen,
  24. }, nil
  25. }
  26. func setVendor(target *models.Vendor, src *models.Vendor) {
  27. target.ID = src.ID
  28. target.VendorName = src.VendorName
  29. target.VendorDescription = src.VendorDescription
  30. target.VendorKey = src.VendorKey
  31. target.CreatedAt = src.CreatedAt
  32. target.UpdatedAt = src.UpdatedAt
  33. }
  34. func setProduct(target *models.Product, src *models.Product) {
  35. target.ID = src.ID
  36. target.ProductName = src.ProductName
  37. target.ProductDescription = src.ProductDescription
  38. target.ProductKey = src.ProductKey
  39. target.ProductConfig = src.ProductConfig
  40. target.VendorID = src.VendorID
  41. target.CreatedAt = src.CreatedAt
  42. target.UpdatedAt = src.UpdatedAt
  43. }
  44. func setApplication(target *models.Application, src *models.Application) {
  45. target.ID = src.ID
  46. target.AppName = src.AppName
  47. target.AppDescription = src.AppDescription
  48. target.AppKey = src.AppKey
  49. target.ReportUrl = src.ReportUrl
  50. target.AppToken = src.AppToken
  51. target.AppDomain = src.AppDomain
  52. target.CreatedAt = src.CreatedAt
  53. target.UpdatedAt = src.UpdatedAt
  54. }
  55. func setDevice(target *models.Device, src *models.Device) {
  56. target.ID = src.ID
  57. target.ProductID = src.ProductID
  58. target.DeviceIdentifier = src.DeviceIdentifier
  59. target.DeviceSecret = src.DeviceIdentifier
  60. target.DeviceKey = src.DeviceKey
  61. target.DeviceName = src.DeviceName
  62. target.DeviceDescription = src.DeviceDescription
  63. target.DeviceVersion = src.DeviceVersion
  64. target.CreatedAt = src.CreatedAt
  65. target.UpdatedAt = src.UpdatedAt
  66. }
  67. // SaveVendor will create a vendor if the ID field is not initialized
  68. // if ID field is initialized, it will update the conresponding vendor.
  69. func (r *Registry) SaveVendor(vendor *models.Vendor, reply *models.Vendor) error {
  70. db, err := getDB()
  71. if err != nil {
  72. return err
  73. }
  74. if vendor.ID == 0 {
  75. // if ID field is not initialized, will generate key first
  76. err = db.Save(vendor).Error
  77. if err != nil {
  78. return err
  79. }
  80. key, err := r.keygen.GenRandomKey(vendor.ID)
  81. if err != nil {
  82. return err
  83. }
  84. vendor.VendorKey = key
  85. }
  86. err = db.Save(vendor).Error
  87. if err != nil {
  88. return err
  89. }
  90. cache := getCache()
  91. cacheKey := fmt.Sprintf("Vendor:%v", vendor.ID)
  92. if _, ok := cache.Get(cacheKey); ok {
  93. cache.Delete(cacheKey)
  94. }
  95. setVendor(reply, vendor)
  96. return nil
  97. }
  98. // SaveProduct will create a product if the ID field is not initialized
  99. // if ID field is initialized, it will update the conresponding product.
  100. func (r *Registry) SaveProduct(product *models.Product, reply *models.Product) error {
  101. db, err := getDB()
  102. if err != nil {
  103. return err
  104. }
  105. if product.ID == 0 {
  106. // create product
  107. err = db.Save(product).Error
  108. if err != nil {
  109. return err
  110. }
  111. key, err := r.keygen.GenRandomKey(product.ID)
  112. if err != nil {
  113. return err
  114. }
  115. product.ProductKey = key
  116. }
  117. err = db.Save(product).Error
  118. if err != nil {
  119. return err
  120. }
  121. cache := getCache()
  122. cacheKey := fmt.Sprintf("Product:%v", product.ID)
  123. if _, ok := cache.Get(cacheKey); ok {
  124. cache.Delete(cacheKey)
  125. }
  126. setProduct(reply, product)
  127. return nil
  128. }
  129. // SaveApplication will create a application if the ID field is not initialized
  130. // if ID field is initialized, it will update the conresponding application.
  131. func (r *Registry) SaveApplication(app *models.Application, reply *models.Application) error {
  132. db, err := getDB()
  133. if err != nil {
  134. return err
  135. }
  136. if app.ID == 0 {
  137. err = db.Save(app).Error
  138. if err != nil {
  139. return err
  140. }
  141. key, err := r.keygen.GenRandomKey(app.ID)
  142. if err != nil {
  143. return err
  144. }
  145. app.AppKey = key
  146. }
  147. err = db.Save(app).Error
  148. if err != nil {
  149. return err
  150. }
  151. cache := getCache()
  152. cacheKey := fmt.Sprintf("Application:%v", app.ID)
  153. if _, ok := cache.Get(cacheKey); ok {
  154. cache.Delete(cacheKey)
  155. }
  156. setApplication(reply, app)
  157. return nil
  158. }
  159. // ValidateApplication try to validate the given app key.
  160. // if success, it will reply the corresponding application
  161. func (r *Registry) ValidateApplication(key string, reply *models.Application) error {
  162. db, err := getDB()
  163. if err != nil {
  164. return err
  165. }
  166. id, err := r.keygen.DecodeIdFromRandomKey(key)
  167. if err != nil {
  168. return err
  169. }
  170. cache := getCache()
  171. cacheKey := fmt.Sprintf("Application:%v", id)
  172. if cacheValue, ok := cache.Get(cacheKey); ok {
  173. app := cacheValue.(*models.Application)
  174. setApplication(reply, app)
  175. } else {
  176. err = db.First(reply, id).Error
  177. if err != nil {
  178. return err
  179. }
  180. var storage models.Application
  181. storage = *reply
  182. cache.Set(cacheKey, &storage)
  183. }
  184. if reply.AppKey != key {
  185. return errors.New("app key not match.")
  186. }
  187. return nil
  188. }
  189. // FindVendor will find product by specified ID
  190. func (r *Registry) FindVendor(id int32, reply *models.Vendor) error {
  191. db, err := getDB()
  192. if err != nil {
  193. return err
  194. }
  195. cache := getCache()
  196. cacheKey := fmt.Sprintf("Vendor:%v", id)
  197. if cacheValue, ok := cache.Get(cacheKey); ok {
  198. vendor := cacheValue.(*models.Vendor)
  199. setVendor(reply, vendor)
  200. } else {
  201. err = db.First(reply, id).Error
  202. if err != nil {
  203. return err
  204. }
  205. var storage models.Vendor
  206. storage = *reply
  207. cache.Set(cacheKey, &storage)
  208. }
  209. return nil
  210. }
  211. // GetVendors will get all vendors in the platform.
  212. func (r *Registry) GetVendors(noarg int, reply *[]models.Vendor) error {
  213. db, err := getDB()
  214. if err != nil {
  215. return err
  216. }
  217. return db.Find(reply).Error
  218. }
  219. // GetProducts will get all products in the platform.
  220. func (r *Registry) GetProducts(noarg int, reply *[]models.Product) error {
  221. db, err := getDB()
  222. if err != nil {
  223. return err
  224. }
  225. return db.Find(reply).Error
  226. }
  227. // GetApplications will get all applications in the platform.
  228. func (r *Registry) GetApplications(noarg int, reply *[]models.Application) error {
  229. db, err := getDB()
  230. if err != nil {
  231. return err
  232. }
  233. return db.Find(reply).Error
  234. }
  235. // FindProduct will find product by specified ID
  236. func (r *Registry) FindProduct(id int32, reply *models.Product) error {
  237. db, err := getDB()
  238. if err != nil {
  239. return err
  240. }
  241. cache := getCache()
  242. cacheKey := fmt.Sprintf("Product:%v", id)
  243. if cacheValue, ok := cache.Get(cacheKey); ok {
  244. product := cacheValue.(*models.Product)
  245. setProduct(reply, product)
  246. } else {
  247. err = db.First(reply, id).Error
  248. if err != nil {
  249. return err
  250. }
  251. var storage models.Product
  252. storage = *reply
  253. cache.Set(cacheKey, &storage)
  254. }
  255. return nil
  256. }
  257. // FindAppliation will find product by specified ID
  258. func (r *Registry) FindApplication(id int32, reply *models.Application) error {
  259. db, err := getDB()
  260. if err != nil {
  261. return err
  262. }
  263. cache := getCache()
  264. cacheKey := fmt.Sprintf("Application:%v", id)
  265. if cacheValue, ok := cache.Get(cacheKey); ok {
  266. app := cacheValue.(*models.Application)
  267. setApplication(reply, app)
  268. } else {
  269. err = db.First(reply, id).Error
  270. if err != nil {
  271. return err
  272. }
  273. var storage models.Application
  274. storage = *reply
  275. cache.Set(cacheKey, &storage)
  276. }
  277. return nil
  278. }
  279. // ValidProduct try to validate the given product key.
  280. // if success, it will reply the corresponding product
  281. func (r *Registry) ValidateProduct(key string, reply *models.Product) error {
  282. db, err := getDB()
  283. if err != nil {
  284. return err
  285. }
  286. id, err := r.keygen.DecodeIdFromRandomKey(key)
  287. if err != nil {
  288. return err
  289. }
  290. cache := getCache()
  291. cacheKey := fmt.Sprintf("Product:%v", id)
  292. if cacheValue, ok := cache.Get(cacheKey); ok {
  293. product := cacheValue.(*models.Product)
  294. setProduct(reply, product)
  295. } else {
  296. err = db.First(reply, id).Error
  297. if err != nil {
  298. return err
  299. }
  300. var storage models.Product
  301. storage = *reply
  302. cache.Set(cacheKey, &storage)
  303. }
  304. if reply.ProductKey != key {
  305. return errors.New("product key not match.")
  306. }
  307. return nil
  308. }
  309. // RegisterDevice try to register a device to our platform.
  310. // if the device has already been registered,
  311. // the registration will success return the registered device before.
  312. func (r *Registry) RegisterDevice(args *rpcs.ArgsDeviceRegister, reply *models.Device) error {
  313. db, err := getDB()
  314. if err != nil {
  315. return err
  316. }
  317. product := &models.Product{}
  318. err = r.ValidateProduct(args.ProductKey, product)
  319. if err != nil {
  320. return err
  321. }
  322. identifier := genDeviceIdentifier(product.VendorID, product.ID, args.DeviceCode)
  323. if db.Where(&models.Device{DeviceIdentifier: identifier}).First(reply).RecordNotFound() {
  324. // device is not registered yet.
  325. reply.ProductID = int32(product.ID)
  326. reply.DeviceIdentifier = identifier
  327. reply.DeviceName = product.ProductName // product name as default device name.
  328. reply.DeviceDescription = product.ProductDescription
  329. reply.DeviceVersion = args.DeviceVersion
  330. err = db.Save(reply).Error
  331. if err != nil {
  332. return err
  333. }
  334. // generate a random device key with hex encoding.
  335. reply.DeviceKey, err = r.keygen.GenRandomKey(reply.ID)
  336. if err != nil {
  337. return err
  338. }
  339. // generate a random password with base64 encoding.
  340. reply.DeviceSecret, err = generator.GenRandomPassword()
  341. if err != nil {
  342. return err
  343. }
  344. err = db.Save(reply).Error
  345. if err != nil {
  346. return err
  347. }
  348. } else {
  349. //delete cache
  350. cache := getCache()
  351. cacheKey := fmt.Sprintf("Device:%v", identifier)
  352. if _, ok := cache.Get(cacheKey); ok {
  353. cache.Delete(cacheKey)
  354. }
  355. // device has aleady been saved. just update version info.
  356. reply.DeviceVersion = args.DeviceVersion
  357. err = db.Save(reply).Error
  358. if err != nil {
  359. return err
  360. }
  361. }
  362. return nil
  363. }
  364. // FindDeviceByIdentifier will find the device by indentifier
  365. func (r *Registry) FindDeviceByIdentifier(identifier string, reply *models.Device) error {
  366. db, err := getDB()
  367. if err != nil {
  368. return err
  369. }
  370. cache := getCache()
  371. cacheKey := fmt.Sprintf("Device:%v", identifier)
  372. if cacheValue, ok := cache.Get(identifier); ok {
  373. device := cacheValue.(*models.Device)
  374. setDevice(reply, device)
  375. } else {
  376. err = db.Where(&models.Device{
  377. DeviceIdentifier: identifier,
  378. }).First(reply).Error
  379. if err != nil {
  380. return err
  381. }
  382. var storage models.Device
  383. storage = *reply
  384. cache.Set(cacheKey, &storage)
  385. }
  386. return nil
  387. }
  388. // FindDeviceById will find the device with given id
  389. func (r *Registry) FindDeviceById(id int64, reply *models.Device) error {
  390. db, err := getDB()
  391. if err != nil {
  392. return err
  393. }
  394. d := &models.Device{}
  395. d.ID = uint(id)
  396. err = db.Where(d).First(reply).Error
  397. if err != nil {
  398. return err
  399. }
  400. return nil
  401. }
  402. // ValidateDevice will validate a device key and return the model if success.
  403. func (r *Registry) ValidateDevice(key string, device *models.Device) error {
  404. id, err := r.keygen.DecodeIdFromRandomKey(key)
  405. if err != nil {
  406. return err
  407. }
  408. err = r.FindDeviceById(id, device)
  409. if err != nil {
  410. return err
  411. }
  412. if device.DeviceKey != key {
  413. return errors.New("device key not match.")
  414. }
  415. return nil
  416. }
  417. // UpdateDevice will update a device info by identifier
  418. func (r *Registry) UpdateDeviceInfo(args *rpcs.ArgsDeviceUpdate, reply *models.Device) error {
  419. db, err := getDB()
  420. if err != nil {
  421. return err
  422. }
  423. err = r.FindDeviceByIdentifier(args.DeviceIdentifier, reply)
  424. if err != nil {
  425. return err
  426. }
  427. //delete cache
  428. cache := getCache()
  429. cacheKey := fmt.Sprintf("Device:%v", args.DeviceIdentifier)
  430. if _, ok := cache.Get(cacheKey); ok {
  431. cache.Delete(cacheKey)
  432. }
  433. reply.DeviceName = args.DeviceName
  434. reply.DeviceDescription = args.DeviceDescription
  435. err = db.Save(reply).Error
  436. if err != nil {
  437. return err
  438. }
  439. return nil
  440. }
  441. // createRule create a new rule with specified parameters.
  442. func (r *Registry) CreateRule(args *models.Rule, reply *rpcs.ReplyEmptyResult) error {
  443. db, err := getDB()
  444. if err != nil {
  445. return err
  446. }
  447. return db.Save(args).Error
  448. }
  449. // queryRules queries rules by trigger and rule type.
  450. func (r *Registry) QueryRules(args *models.Rule, reply *[]models.Rule) error {
  451. db, err := getDB()
  452. if err != nil {
  453. return err
  454. }
  455. err = db.Where(args).Find(reply).Error
  456. if err != nil {
  457. return err
  458. }
  459. return nil
  460. }