Nie możesz wybrać więcej, niż 25 tematów Tematy muszą się zaczynać od litery lub cyfry, mogą zawierać myślniki ('-') i mogą mieć do 35 znaków.
 
 
 

142 wiersze
3.7 KiB

  1. // Copyright 2015 Google Inc. All rights reserved.
  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 provides filtering support for a martian.Proxy based on auth
  15. // ID.
  16. package auth
  17. import (
  18. "fmt"
  19. "net/http"
  20. "sync"
  21. "github.com/google/martian"
  22. )
  23. // Filter filters RequestModifiers and ResponseModifiers by auth ID.
  24. type Filter struct {
  25. authRequired bool
  26. mu sync.RWMutex
  27. reqmods map[string]martian.RequestModifier
  28. resmods map[string]martian.ResponseModifier
  29. }
  30. // NewFilter returns a new auth.Filter.
  31. func NewFilter() *Filter {
  32. return &Filter{
  33. reqmods: make(map[string]martian.RequestModifier),
  34. resmods: make(map[string]martian.ResponseModifier),
  35. }
  36. }
  37. // SetAuthRequired determines whether the auth ID must have an associated
  38. // RequestModifier or ResponseModifier. If true, it will set auth error.
  39. func (f *Filter) SetAuthRequired(required bool) {
  40. f.authRequired = required
  41. }
  42. // SetRequestModifier sets the RequestModifier for the given ID. It will
  43. // overwrite any existing modifier with the same ID.
  44. func (f *Filter) SetRequestModifier(id string, reqmod martian.RequestModifier) error {
  45. f.mu.Lock()
  46. defer f.mu.Unlock()
  47. if reqmod != nil {
  48. f.reqmods[id] = reqmod
  49. } else {
  50. delete(f.reqmods, id)
  51. }
  52. return nil
  53. }
  54. // SetResponseModifier sets the ResponseModifier for the given ID. It will
  55. // overwrite any existing modifier with the same ID.
  56. func (f *Filter) SetResponseModifier(id string, resmod martian.ResponseModifier) error {
  57. f.mu.Lock()
  58. defer f.mu.Unlock()
  59. if resmod != nil {
  60. f.resmods[id] = resmod
  61. } else {
  62. delete(f.resmods, id)
  63. }
  64. return nil
  65. }
  66. // RequestModifier retrieves the RequestModifier for the given ID. Returns nil
  67. // if no modifier exists for the given ID.
  68. func (f *Filter) RequestModifier(id string) martian.RequestModifier {
  69. f.mu.RLock()
  70. defer f.mu.RUnlock()
  71. return f.reqmods[id]
  72. }
  73. // ResponseModifier retrieves the ResponseModifier for the given ID. Returns nil
  74. // if no modifier exists for the given ID.
  75. func (f *Filter) ResponseModifier(id string) martian.ResponseModifier {
  76. f.mu.RLock()
  77. defer f.mu.RUnlock()
  78. return f.resmods[id]
  79. }
  80. // ModifyRequest runs the RequestModifier for the associated auth ID. If no
  81. // modifier is found for auth ID then auth error is set.
  82. func (f *Filter) ModifyRequest(req *http.Request) error {
  83. ctx := martian.NewContext(req)
  84. actx := FromContext(ctx)
  85. if reqmod, ok := f.reqmods[actx.ID()]; ok {
  86. return reqmod.ModifyRequest(req)
  87. }
  88. if err := f.requireKnownAuth(actx.ID()); err != nil {
  89. actx.SetError(err)
  90. }
  91. return nil
  92. }
  93. // ModifyResponse runs the ResponseModifier for the associated auth ID. If no
  94. // modifier is found for the auth ID then the auth error is set.
  95. func (f *Filter) ModifyResponse(res *http.Response) error {
  96. ctx := martian.NewContext(res.Request)
  97. actx := FromContext(ctx)
  98. if resmod, ok := f.resmods[actx.ID()]; ok {
  99. return resmod.ModifyResponse(res)
  100. }
  101. if err := f.requireKnownAuth(actx.ID()); err != nil {
  102. actx.SetError(err)
  103. }
  104. return nil
  105. }
  106. func (f *Filter) requireKnownAuth(id string) error {
  107. _, reqok := f.reqmods[id]
  108. _, resok := f.resmods[id]
  109. if !reqok && !resok && f.authRequired {
  110. return fmt.Errorf("auth: unrecognized credentials: %s", id)
  111. }
  112. return nil
  113. }