token.go 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674
  1. package controller
  2. import (
  3. "errors"
  4. "fmt"
  5. "net/http"
  6. "strconv"
  7. "time"
  8. "github.com/bytedance/sonic"
  9. "github.com/gin-gonic/gin"
  10. "github.com/labring/aiproxy/core/common/network"
  11. "github.com/labring/aiproxy/core/middleware"
  12. "github.com/labring/aiproxy/core/model"
  13. )
  14. // TokenResponse represents the response structure for token endpoints
  15. type TokenResponse struct {
  16. *model.Token
  17. AccessedAt time.Time `json:"accessed_at"`
  18. }
  19. func (t *TokenResponse) MarshalJSON() ([]byte, error) {
  20. type Alias TokenResponse
  21. return sonic.Marshal(&struct {
  22. *Alias
  23. CreatedAt int64 `json:"created_at"`
  24. ExpiredAt int64 `json:"expired_at"`
  25. AccessedAt int64 `json:"accessed_at"`
  26. }{
  27. Alias: (*Alias)(t),
  28. CreatedAt: t.CreatedAt.UnixMilli(),
  29. ExpiredAt: t.ExpiredAt.UnixMilli(),
  30. AccessedAt: t.AccessedAt.UnixMilli(),
  31. })
  32. }
  33. type (
  34. AddTokenRequest struct {
  35. Name string `json:"name"`
  36. Subnets []string `json:"subnets"`
  37. Models []string `json:"models"`
  38. ExpiredAt int64 `json:"expiredAt"`
  39. Quota float64 `json:"quota"`
  40. }
  41. UpdateTokenStatusRequest struct {
  42. Status int `json:"status"`
  43. }
  44. UpdateTokenNameRequest struct {
  45. Name string `json:"name"`
  46. }
  47. )
  48. func (at *AddTokenRequest) ToToken() *model.Token {
  49. var expiredAt time.Time
  50. if at.ExpiredAt > 0 {
  51. expiredAt = time.UnixMilli(at.ExpiredAt)
  52. }
  53. return &model.Token{
  54. Name: model.EmptyNullString(at.Name),
  55. Subnets: at.Subnets,
  56. Models: at.Models,
  57. ExpiredAt: expiredAt,
  58. Quota: at.Quota,
  59. }
  60. }
  61. func validateToken(token AddTokenRequest) error {
  62. if token.Name == "" {
  63. return errors.New("token name cannot be empty")
  64. }
  65. if len(token.Name) > 30 {
  66. return errors.New("token name is too long")
  67. }
  68. if err := network.IsValidSubnets(token.Subnets); err != nil {
  69. return fmt.Errorf("invalid subnet: %w", err)
  70. }
  71. return nil
  72. }
  73. func validateTokenUpdate(token AddTokenRequest) error {
  74. if err := network.IsValidSubnets(token.Subnets); err != nil {
  75. return fmt.Errorf("invalid subnet: %w", err)
  76. }
  77. return nil
  78. }
  79. func buildTokenResponse(token *model.Token) *TokenResponse {
  80. lastRequestAt, _ := model.GetGroupTokenLastRequestTime(token.GroupID, string(token.Name))
  81. return &TokenResponse{
  82. Token: token,
  83. AccessedAt: lastRequestAt,
  84. }
  85. }
  86. func buildTokenResponses(tokens []*model.Token) []*TokenResponse {
  87. responses := make([]*TokenResponse, len(tokens))
  88. for i, token := range tokens {
  89. responses[i] = buildTokenResponse(token)
  90. }
  91. return responses
  92. }
  93. // GetTokens godoc
  94. //
  95. // @Summary Get all tokens
  96. // @Description Returns a paginated list of all tokens
  97. // @Tags tokens
  98. // @Produce json
  99. // @Security ApiKeyAuth
  100. // @Param page query int false "Page number"
  101. // @Param per_page query int false "Items per page"
  102. // @Param group query string false "Group name"
  103. // @Param order query string false "Order"
  104. // @Param status query int false "Status"
  105. // @Success 200 {object} middleware.APIResponse{data=map[string]any{tokens=[]TokenResponse,total=int}}
  106. // @Router /api/tokens/ [get]
  107. func GetTokens(c *gin.Context) {
  108. page, perPage := parsePageParams(c)
  109. group := c.Query("group")
  110. order := c.Query("order")
  111. status, _ := strconv.Atoi(c.Query("status"))
  112. tokens, total, err := model.GetTokens(group, page, perPage, order, status)
  113. if err != nil {
  114. middleware.ErrorResponse(c, http.StatusOK, err.Error())
  115. return
  116. }
  117. middleware.SuccessResponse(c, gin.H{
  118. "tokens": buildTokenResponses(tokens),
  119. "total": total,
  120. })
  121. }
  122. // GetGroupTokens godoc
  123. //
  124. // @Summary Get all tokens for a specific group
  125. // @Description Returns a paginated list of all tokens for a specific group
  126. // @Tags tokens
  127. // @Produce json
  128. // @Security ApiKeyAuth
  129. // @Param group path string true "Group name"
  130. // @Param page query int false "Page number"
  131. // @Param per_page query int false "Items per page"
  132. // @Param order query string false "Order"
  133. // @Param status query int false "Status"
  134. // @Success 200 {object} middleware.APIResponse{data=map[string]any{tokens=[]TokenResponse,total=int}}
  135. // @Router /api/tokens/{group} [get]
  136. func GetGroupTokens(c *gin.Context) {
  137. group := c.Param("group")
  138. if group == "" {
  139. middleware.ErrorResponse(c, http.StatusOK, "group is required")
  140. return
  141. }
  142. page, perPage := parsePageParams(c)
  143. order := c.Query("order")
  144. status, _ := strconv.Atoi(c.Query("status"))
  145. tokens, total, err := model.GetTokens(group, page, perPage, order, status)
  146. if err != nil {
  147. middleware.ErrorResponse(c, http.StatusOK, err.Error())
  148. return
  149. }
  150. middleware.SuccessResponse(c, gin.H{
  151. "tokens": buildTokenResponses(tokens),
  152. "total": total,
  153. })
  154. }
  155. // SearchTokens godoc
  156. //
  157. // @Summary Search tokens
  158. // @Description Returns a paginated list of tokens based on search criteria
  159. // @Tags tokens
  160. // @Produce json
  161. // @Security ApiKeyAuth
  162. // @Param keyword query string false "Keyword"
  163. // @Param page query int false "Page number"
  164. // @Param per_page query int false "Items per page"
  165. // @Param order query string false "Order"
  166. // @Param name query string false "Name"
  167. // @Param key query string false "Key"
  168. // @Param status query int false "Status"
  169. // @Param group query string false "Group"
  170. // @Success 200 {object} middleware.APIResponse{data=map[string]any{tokens=[]TokenResponse,total=int}}
  171. // @Router /api/tokens/search [get]
  172. func SearchTokens(c *gin.Context) {
  173. page, perPage := parsePageParams(c)
  174. keyword := c.Query("keyword")
  175. order := c.Query("order")
  176. name := c.Query("name")
  177. key := c.Query("key")
  178. status, _ := strconv.Atoi(c.Query("status"))
  179. group := c.Query("group")
  180. tokens, total, err := model.SearchTokens(group, keyword, page, perPage, order, status, name, key)
  181. if err != nil {
  182. middleware.ErrorResponse(c, http.StatusOK, err.Error())
  183. return
  184. }
  185. middleware.SuccessResponse(c, gin.H{
  186. "tokens": buildTokenResponses(tokens),
  187. "total": total,
  188. })
  189. }
  190. // SearchGroupTokens godoc
  191. //
  192. // @Summary Search tokens for a specific group
  193. // @Description Returns a paginated list of tokens for a specific group based on search criteria
  194. // @Tags token
  195. // @Produce json
  196. // @Security ApiKeyAuth
  197. // @Param group path string true "Group name"
  198. // @Param keyword query string false "Keyword"
  199. // @Param page query int false "Page number"
  200. // @Param per_page query int false "Items per page"
  201. // @Param order query string false "Order"
  202. // @Param name query string false "Name"
  203. // @Param key query string false "Key"
  204. // @Param status query int false "Status"
  205. // @Success 200 {object} middleware.APIResponse{data=map[string]any{tokens=[]TokenResponse,total=int}}
  206. // @Router /api/token/{group}/search [get]
  207. func SearchGroupTokens(c *gin.Context) {
  208. group := c.Param("group")
  209. if group == "" {
  210. middleware.ErrorResponse(c, http.StatusOK, "group is required")
  211. return
  212. }
  213. page, perPage := parsePageParams(c)
  214. keyword := c.Query("keyword")
  215. order := c.Query("order")
  216. name := c.Query("name")
  217. key := c.Query("key")
  218. status, _ := strconv.Atoi(c.Query("status"))
  219. tokens, total, err := model.SearchGroupTokens(group, keyword, page, perPage, order, status, name, key)
  220. if err != nil {
  221. middleware.ErrorResponse(c, http.StatusOK, err.Error())
  222. return
  223. }
  224. middleware.SuccessResponse(c, gin.H{
  225. "tokens": buildTokenResponses(tokens),
  226. "total": total,
  227. })
  228. }
  229. // GetToken godoc
  230. //
  231. // @Summary Get token by ID
  232. // @Description Returns detailed information about a specific token
  233. // @Tags tokens
  234. // @Produce json
  235. // @Security ApiKeyAuth
  236. // @Param id path int true "Token ID"
  237. // @Success 200 {object} middleware.APIResponse{data=TokenResponse}
  238. // @Router /api/tokens/{id} [get]
  239. func GetToken(c *gin.Context) {
  240. id, err := strconv.Atoi(c.Param("id"))
  241. if err != nil {
  242. middleware.ErrorResponse(c, http.StatusOK, err.Error())
  243. return
  244. }
  245. token, err := model.GetTokenByID(id)
  246. if err != nil {
  247. middleware.ErrorResponse(c, http.StatusOK, err.Error())
  248. return
  249. }
  250. middleware.SuccessResponse(c, buildTokenResponse(token))
  251. }
  252. // GetGroupToken godoc
  253. //
  254. // @Summary Get token by ID for a specific group
  255. // @Description Returns detailed information about a specific token for a specific group
  256. // @Tags token
  257. // @Produce json
  258. // @Security ApiKeyAuth
  259. // @Param group path string true "Group name"
  260. // @Param id path int true "Token ID"
  261. // @Success 200 {object} middleware.APIResponse{data=TokenResponse}
  262. // @Router /api/token/{group}/{id} [get]
  263. func GetGroupToken(c *gin.Context) {
  264. group := c.Param("group")
  265. if group == "" {
  266. middleware.ErrorResponse(c, http.StatusOK, "group is required")
  267. return
  268. }
  269. id, err := strconv.Atoi(c.Param("id"))
  270. if err != nil {
  271. middleware.ErrorResponse(c, http.StatusOK, err.Error())
  272. return
  273. }
  274. token, err := model.GetGroupTokenByID(group, id)
  275. if err != nil {
  276. middleware.ErrorResponse(c, http.StatusOK, err.Error())
  277. return
  278. }
  279. middleware.SuccessResponse(c, buildTokenResponse(token))
  280. }
  281. // AddGroupToken godoc
  282. //
  283. // @Summary Add group token
  284. // @Description Adds a new token to a specific group
  285. // @Tags token
  286. // @Accept json
  287. // @Produce json
  288. // @Security ApiKeyAuth
  289. // @Param group path string true "Group name"
  290. // @Param auto_create_group query bool false "Auto create group"
  291. // @Param ignore_exist query bool false "Ignore exist"
  292. // @Param token body AddTokenRequest true "Token information"
  293. // @Success 200 {object} middleware.APIResponse{data=TokenResponse}
  294. // @Router /api/token/{group} [post]
  295. func AddGroupToken(c *gin.Context) {
  296. group := c.Param("group")
  297. var req AddTokenRequest
  298. if err := c.ShouldBindJSON(&req); err != nil {
  299. middleware.ErrorResponse(c, http.StatusOK, err.Error())
  300. return
  301. }
  302. if err := validateToken(req); err != nil {
  303. middleware.ErrorResponse(c, http.StatusOK, "parameter error: "+err.Error())
  304. return
  305. }
  306. token := req.ToToken()
  307. token.GroupID = group
  308. if err := model.InsertToken(token, c.Query("auto_create_group") == "true", c.Query("ignore_exist") == "true"); err != nil {
  309. middleware.ErrorResponse(c, http.StatusOK, err.Error())
  310. return
  311. }
  312. middleware.SuccessResponse(c, &TokenResponse{Token: token})
  313. }
  314. // DeleteToken godoc
  315. //
  316. // @Summary Delete token
  317. // @Description Deletes a specific token by ID
  318. // @Tags tokens
  319. // @Produce json
  320. // @Security ApiKeyAuth
  321. // @Param id path int true "Token ID"
  322. // @Success 200 {object} middleware.APIResponse
  323. // @Router /api/tokens/{id} [delete]
  324. func DeleteToken(c *gin.Context) {
  325. id, err := strconv.Atoi(c.Param("id"))
  326. if err != nil {
  327. middleware.ErrorResponse(c, http.StatusOK, err.Error())
  328. return
  329. }
  330. if err := model.DeleteTokenByID(id); err != nil {
  331. middleware.ErrorResponse(c, http.StatusOK, err.Error())
  332. return
  333. }
  334. middleware.SuccessResponse(c, nil)
  335. }
  336. // DeleteTokens godoc
  337. //
  338. // @Summary Delete multiple tokens
  339. // @Description Deletes multiple tokens by their IDs
  340. // @Tags tokens
  341. // @Accept json
  342. // @Produce json
  343. // @Security ApiKeyAuth
  344. // @Param ids body []int true "Token IDs"
  345. // @Success 200 {object} middleware.APIResponse
  346. // @Router /api/tokens/batch_delete [post]
  347. func DeleteTokens(c *gin.Context) {
  348. var ids []int
  349. if err := c.ShouldBindJSON(&ids); err != nil {
  350. middleware.ErrorResponse(c, http.StatusOK, err.Error())
  351. return
  352. }
  353. if err := model.DeleteTokensByIDs(ids); err != nil {
  354. middleware.ErrorResponse(c, http.StatusOK, err.Error())
  355. return
  356. }
  357. middleware.SuccessResponse(c, nil)
  358. }
  359. // DeleteGroupToken godoc
  360. //
  361. // @Summary Delete group token
  362. // @Description Deletes a specific token from a group
  363. // @Tags token
  364. // @Produce json
  365. // @Security ApiKeyAuth
  366. // @Param group path string true "Group name"
  367. // @Param id path int true "Token ID"
  368. // @Success 200 {object} middleware.APIResponse
  369. // @Router /api/token/{group}/{id} [delete]
  370. func DeleteGroupToken(c *gin.Context) {
  371. group := c.Param("group")
  372. id, err := strconv.Atoi(c.Param("id"))
  373. if err != nil {
  374. middleware.ErrorResponse(c, http.StatusOK, err.Error())
  375. return
  376. }
  377. if err := model.DeleteGroupTokenByID(group, id); err != nil {
  378. middleware.ErrorResponse(c, http.StatusOK, err.Error())
  379. return
  380. }
  381. middleware.SuccessResponse(c, nil)
  382. }
  383. // DeleteGroupTokens godoc
  384. //
  385. // @Summary Delete group tokens
  386. // @Description Deletes multiple tokens from a specific group
  387. // @Tags token
  388. // @Produce json
  389. // @Security ApiKeyAuth
  390. // @Param group path string true "Group name"
  391. // @Param ids body []int true "Token IDs"
  392. // @Success 200 {object} middleware.APIResponse
  393. // @Router /api/token/{group}/batch_delete [post]
  394. func DeleteGroupTokens(c *gin.Context) {
  395. group := c.Param("group")
  396. var ids []int
  397. if err := c.ShouldBindJSON(&ids); err != nil {
  398. middleware.ErrorResponse(c, http.StatusOK, err.Error())
  399. return
  400. }
  401. if err := model.DeleteGroupTokensByIDs(group, ids); err != nil {
  402. middleware.ErrorResponse(c, http.StatusOK, err.Error())
  403. return
  404. }
  405. middleware.SuccessResponse(c, nil)
  406. }
  407. // UpdateToken godoc
  408. //
  409. // @Summary Update token
  410. // @Description Updates an existing token's information
  411. // @Tags tokens
  412. // @Accept json
  413. // @Produce json
  414. // @Security ApiKeyAuth
  415. // @Param id path int true "Token ID"
  416. // @Param token body AddTokenRequest true "Updated token information"
  417. // @Success 200 {object} middleware.APIResponse{data=TokenResponse}
  418. // @Router /api/tokens/{id} [put]
  419. func UpdateToken(c *gin.Context) {
  420. id, err := strconv.Atoi(c.Param("id"))
  421. if err != nil {
  422. middleware.ErrorResponse(c, http.StatusOK, err.Error())
  423. return
  424. }
  425. var req AddTokenRequest
  426. if err := c.ShouldBindJSON(&req); err != nil {
  427. middleware.ErrorResponse(c, http.StatusOK, err.Error())
  428. return
  429. }
  430. if err := validateTokenUpdate(req); err != nil {
  431. middleware.ErrorResponse(c, http.StatusOK, "parameter error: "+err.Error())
  432. return
  433. }
  434. token := req.ToToken()
  435. if err := model.UpdateToken(id, token); err != nil {
  436. middleware.ErrorResponse(c, http.StatusOK, err.Error())
  437. return
  438. }
  439. middleware.SuccessResponse(c, &TokenResponse{Token: token})
  440. }
  441. // UpdateGroupToken godoc
  442. //
  443. // @Summary Update group token
  444. // @Description Updates an existing token in a specific group
  445. // @Tags token
  446. // @Accept json
  447. // @Produce json
  448. // @Security ApiKeyAuth
  449. // @Param group path string true "Group name"
  450. // @Param id path int true "Token ID"
  451. // @Param token body AddTokenRequest true "Updated token information"
  452. // @Success 200 {object} middleware.APIResponse{data=TokenResponse}
  453. // @Router /api/token/{group}/{id} [put]
  454. func UpdateGroupToken(c *gin.Context) {
  455. group := c.Param("group")
  456. id, err := strconv.Atoi(c.Param("id"))
  457. if err != nil {
  458. middleware.ErrorResponse(c, http.StatusOK, err.Error())
  459. return
  460. }
  461. var req AddTokenRequest
  462. if err := c.ShouldBindJSON(&req); err != nil {
  463. middleware.ErrorResponse(c, http.StatusOK, err.Error())
  464. return
  465. }
  466. if err := validateTokenUpdate(req); err != nil {
  467. middleware.ErrorResponse(c, http.StatusOK, "parameter error: "+err.Error())
  468. return
  469. }
  470. token := req.ToToken()
  471. if err := model.UpdateGroupToken(id, group, token); err != nil {
  472. middleware.ErrorResponse(c, http.StatusOK, err.Error())
  473. return
  474. }
  475. middleware.SuccessResponse(c, &TokenResponse{Token: token})
  476. }
  477. // UpdateTokenStatus godoc
  478. //
  479. // @Summary Update token status
  480. // @Description Updates the status of a specific token
  481. // @Tags tokens
  482. // @Accept json
  483. // @Produce json
  484. // @Security ApiKeyAuth
  485. // @Param id path int true "Token ID"
  486. // @Param status body UpdateTokenStatusRequest true "Status information"
  487. // @Success 200 {object} middleware.APIResponse
  488. // @Router /api/tokens/{id}/status [post]
  489. func UpdateTokenStatus(c *gin.Context) {
  490. id, err := strconv.Atoi(c.Param("id"))
  491. if err != nil {
  492. middleware.ErrorResponse(c, http.StatusOK, err.Error())
  493. return
  494. }
  495. var req UpdateTokenStatusRequest
  496. if err := c.ShouldBindJSON(&req); err != nil {
  497. middleware.ErrorResponse(c, http.StatusOK, err.Error())
  498. return
  499. }
  500. if err := model.UpdateTokenStatus(id, req.Status); err != nil {
  501. middleware.ErrorResponse(c, http.StatusOK, err.Error())
  502. return
  503. }
  504. middleware.SuccessResponse(c, nil)
  505. }
  506. // UpdateGroupTokenStatus godoc
  507. //
  508. // @Summary Update group token status
  509. // @Description Updates the status of a token in a specific group
  510. // @Tags token
  511. // @Accept json
  512. // @Produce json
  513. // @Security ApiKeyAuth
  514. // @Param group path string true "Group name"
  515. // @Param id path int true "Token ID"
  516. // @Param status body UpdateTokenStatusRequest true "Status information"
  517. // @Success 200 {object} middleware.APIResponse
  518. // @Router /api/token/{group}/{id}/status [post]
  519. func UpdateGroupTokenStatus(c *gin.Context) {
  520. group := c.Param("group")
  521. id, err := strconv.Atoi(c.Param("id"))
  522. if err != nil {
  523. middleware.ErrorResponse(c, http.StatusOK, err.Error())
  524. return
  525. }
  526. var req UpdateTokenStatusRequest
  527. if err := c.ShouldBindJSON(&req); err != nil {
  528. middleware.ErrorResponse(c, http.StatusOK, err.Error())
  529. return
  530. }
  531. if err := model.UpdateGroupTokenStatus(group, id, req.Status); err != nil {
  532. middleware.ErrorResponse(c, http.StatusOK, err.Error())
  533. return
  534. }
  535. middleware.SuccessResponse(c, nil)
  536. }
  537. // UpdateTokenName godoc
  538. //
  539. // @Summary Update token name
  540. // @Description Updates the name of a specific token
  541. // @Tags tokens
  542. // @Accept json
  543. // @Produce json
  544. // @Security ApiKeyAuth
  545. // @Param id path int true "Token ID"
  546. // @Param name body UpdateTokenNameRequest true "Name information"
  547. // @Success 200 {object} middleware.APIResponse
  548. // @Router /api/tokens/{id}/name [post]
  549. func UpdateTokenName(c *gin.Context) {
  550. id, err := strconv.Atoi(c.Param("id"))
  551. if err != nil {
  552. middleware.ErrorResponse(c, http.StatusOK, err.Error())
  553. return
  554. }
  555. var req UpdateTokenNameRequest
  556. if err := c.ShouldBindJSON(&req); err != nil {
  557. middleware.ErrorResponse(c, http.StatusOK, err.Error())
  558. return
  559. }
  560. if err := model.UpdateTokenName(id, req.Name); err != nil {
  561. middleware.ErrorResponse(c, http.StatusOK, err.Error())
  562. return
  563. }
  564. middleware.SuccessResponse(c, nil)
  565. }
  566. // UpdateGroupTokenName godoc
  567. //
  568. // @Summary Update group token name
  569. // @Description Updates the name of a token in a specific group
  570. // @Tags token
  571. // @Accept json
  572. // @Produce json
  573. // @Security ApiKeyAuth
  574. // @Param group path string true "Group name"
  575. // @Param id path int true "Token ID"
  576. // @Param name body UpdateTokenNameRequest true "Name information"
  577. // @Success 200 {object} middleware.APIResponse
  578. // @Router /api/token/{group}/{id}/name [post]
  579. func UpdateGroupTokenName(c *gin.Context) {
  580. group := c.Param("group")
  581. id, err := strconv.Atoi(c.Param("id"))
  582. if err != nil {
  583. middleware.ErrorResponse(c, http.StatusOK, err.Error())
  584. return
  585. }
  586. var req UpdateTokenNameRequest
  587. if err := c.ShouldBindJSON(&req); err != nil {
  588. middleware.ErrorResponse(c, http.StatusOK, err.Error())
  589. return
  590. }
  591. if err := model.UpdateGroupTokenName(group, id, req.Name); err != nil {
  592. middleware.ErrorResponse(c, http.StatusOK, err.Error())
  593. return
  594. }
  595. middleware.SuccessResponse(c, nil)
  596. }