aksk.go 2.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. // Copyright 2019 Yunion
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. package auth
  15. import (
  16. "net/http"
  17. "yunion.io/x/pkg/errors"
  18. "yunion.io/x/pkg/util/cache"
  19. "yunion.io/x/pkg/util/s3auth"
  20. "yunion.io/x/onecloud/pkg/mcclient"
  21. )
  22. type sAccessKeyCache struct {
  23. *cache.LRUCache
  24. }
  25. type sAkSkCacheItem struct {
  26. credential *mcclient.SAkskTokenCredential
  27. }
  28. func (item *sAkSkCacheItem) Size() int {
  29. return 1
  30. }
  31. func newAccessKeyCache() *sAccessKeyCache {
  32. return &sAccessKeyCache{
  33. LRUCache: cache.NewLRUCache(defaultCacheCount),
  34. }
  35. }
  36. func (c *sAccessKeyCache) addToken(cred *mcclient.SAkskTokenCredential) {
  37. item := &sAkSkCacheItem{cred}
  38. c.Set(cred.AccessKeySecret.AccessKey, item)
  39. }
  40. func (c *sAccessKeyCache) getToken(token string) (*mcclient.SAkskTokenCredential, bool) {
  41. item, found := c.Get(token)
  42. if !found {
  43. return nil, false
  44. }
  45. return item.(*sAkSkCacheItem).credential, true
  46. }
  47. func (c *sAccessKeyCache) deleteToken(token string) bool {
  48. return c.Delete(token)
  49. }
  50. func (c *sAccessKeyCache) Verify(cli *mcclient.Client, req http.Request, virtualHost bool) (mcclient.TokenCredential, error) {
  51. aksk, err := s3auth.DecodeAccessKeyRequest(req, virtualHost)
  52. if err != nil {
  53. return nil, errors.Wrap(err, "s3auth.DecodeAccessKeyRequestV2")
  54. }
  55. token, found := c.getToken(aksk.GetAccessKey())
  56. if found {
  57. if token.Token.IsValid() && token.AccessKeySecret.IsValid() {
  58. err = aksk.Verify(token.AccessKeySecret.Secret)
  59. if err != nil {
  60. return nil, errors.Wrap(err, "aksk.Verify")
  61. }
  62. return token.Token, nil
  63. } else {
  64. c.deleteToken(aksk.GetAccessKey())
  65. }
  66. }
  67. token, err = cli.VerifyRequest(req, aksk, virtualHost)
  68. if err != nil {
  69. return nil, errors.Wrap(err, "cli.VerifyRequest")
  70. }
  71. c.addToken(token)
  72. return token.Token, nil
  73. }