github.com/kjdelisle/consul@v1.4.5/agent/acl_endpoint_legacy.go (about) 1 package agent 2 3 import ( 4 "fmt" 5 "net/http" 6 "strings" 7 8 "github.com/hashicorp/consul/acl" 9 "github.com/hashicorp/consul/agent/structs" 10 ) 11 12 type aclCreateResponse struct { 13 ID string 14 } 15 16 func (s *HTTPServer) ACLDestroy(resp http.ResponseWriter, req *http.Request) (interface{}, error) { 17 if s.checkACLDisabled(resp, req) { 18 return nil, nil 19 } 20 21 args := structs.ACLRequest{ 22 Datacenter: s.agent.config.ACLDatacenter, 23 Op: structs.ACLDelete, 24 } 25 s.parseToken(req, &args.Token) 26 27 // Pull out the acl id 28 args.ACL.ID = strings.TrimPrefix(req.URL.Path, "/v1/acl/destroy/") 29 if args.ACL.ID == "" { 30 resp.WriteHeader(http.StatusBadRequest) 31 fmt.Fprint(resp, "Missing ACL") 32 return nil, nil 33 } 34 35 var out string 36 if err := s.agent.RPC("ACL.Apply", &args, &out); err != nil { 37 return nil, err 38 } 39 return true, nil 40 } 41 42 func (s *HTTPServer) ACLCreate(resp http.ResponseWriter, req *http.Request) (interface{}, error) { 43 if s.checkACLDisabled(resp, req) { 44 return nil, nil 45 } 46 return s.aclSet(resp, req, false) 47 } 48 49 func (s *HTTPServer) ACLUpdate(resp http.ResponseWriter, req *http.Request) (interface{}, error) { 50 if s.checkACLDisabled(resp, req) { 51 return nil, nil 52 } 53 return s.aclSet(resp, req, true) 54 } 55 56 func (s *HTTPServer) aclSet(resp http.ResponseWriter, req *http.Request, update bool) (interface{}, error) { 57 args := structs.ACLRequest{ 58 Datacenter: s.agent.config.ACLDatacenter, 59 Op: structs.ACLSet, 60 ACL: structs.ACL{ 61 Type: structs.ACLTokenTypeClient, 62 }, 63 } 64 s.parseToken(req, &args.Token) 65 66 // Handle optional request body 67 if req.ContentLength > 0 { 68 if err := decodeBody(req, &args.ACL, nil); err != nil { 69 resp.WriteHeader(http.StatusBadRequest) 70 fmt.Fprintf(resp, "Request decode failed: %v", err) 71 return nil, nil 72 } 73 } 74 75 // Ensure there is an ID set for update. ID is optional for 76 // create, as one will be generated if not provided. 77 if update && args.ACL.ID == "" { 78 resp.WriteHeader(http.StatusBadRequest) 79 fmt.Fprint(resp, "ACL ID must be set") 80 return nil, nil 81 } 82 83 // Create the acl, get the ID 84 var out string 85 if err := s.agent.RPC("ACL.Apply", &args, &out); err != nil { 86 return nil, err 87 } 88 89 // Format the response as a JSON object 90 return aclCreateResponse{out}, nil 91 } 92 93 func (s *HTTPServer) ACLClone(resp http.ResponseWriter, req *http.Request) (interface{}, error) { 94 if s.checkACLDisabled(resp, req) { 95 return nil, nil 96 } 97 98 args := structs.ACLSpecificRequest{ 99 Datacenter: s.agent.config.ACLDatacenter, 100 } 101 var dc string 102 if done := s.parse(resp, req, &dc, &args.QueryOptions); done { 103 return nil, nil 104 } 105 106 // Pull out the acl id 107 args.ACL = strings.TrimPrefix(req.URL.Path, "/v1/acl/clone/") 108 if args.ACL == "" { 109 resp.WriteHeader(http.StatusBadRequest) 110 fmt.Fprint(resp, "Missing ACL") 111 return nil, nil 112 } 113 114 var out structs.IndexedACLs 115 defer setMeta(resp, &out.QueryMeta) 116 if err := s.agent.RPC("ACL.Get", &args, &out); err != nil { 117 return nil, err 118 } 119 120 // Bail if the ACL is not found, this could be a 404 or a 403, so 121 // always just return a 403. 122 if len(out.ACLs) == 0 { 123 return nil, acl.ErrPermissionDenied 124 } 125 126 // Create a new ACL 127 createArgs := structs.ACLRequest{ 128 Datacenter: args.Datacenter, 129 Op: structs.ACLSet, 130 ACL: *out.ACLs[0], 131 } 132 createArgs.ACL.ID = "" 133 createArgs.Token = args.Token 134 135 // Create the acl, get the ID 136 var outID string 137 if err := s.agent.RPC("ACL.Apply", &createArgs, &outID); err != nil { 138 return nil, err 139 } 140 141 // Format the response as a JSON object 142 return aclCreateResponse{outID}, nil 143 } 144 145 func (s *HTTPServer) ACLGet(resp http.ResponseWriter, req *http.Request) (interface{}, error) { 146 if s.checkACLDisabled(resp, req) { 147 return nil, nil 148 } 149 150 args := structs.ACLSpecificRequest{ 151 Datacenter: s.agent.config.ACLDatacenter, 152 } 153 var dc string 154 if done := s.parse(resp, req, &dc, &args.QueryOptions); done { 155 return nil, nil 156 } 157 158 // Pull out the acl id 159 args.ACL = strings.TrimPrefix(req.URL.Path, "/v1/acl/info/") 160 if args.ACL == "" { 161 resp.WriteHeader(http.StatusBadRequest) 162 fmt.Fprint(resp, "Missing ACL") 163 return nil, nil 164 } 165 166 var out structs.IndexedACLs 167 defer setMeta(resp, &out.QueryMeta) 168 if err := s.agent.RPC("ACL.Get", &args, &out); err != nil { 169 return nil, err 170 } 171 172 // Use empty list instead of nil 173 if out.ACLs == nil { 174 out.ACLs = make(structs.ACLs, 0) 175 } 176 return out.ACLs, nil 177 } 178 179 func (s *HTTPServer) ACLList(resp http.ResponseWriter, req *http.Request) (interface{}, error) { 180 if s.checkACLDisabled(resp, req) { 181 return nil, nil 182 } 183 184 args := structs.DCSpecificRequest{ 185 Datacenter: s.agent.config.ACLDatacenter, 186 } 187 var dc string 188 if done := s.parse(resp, req, &dc, &args.QueryOptions); done { 189 return nil, nil 190 } 191 192 var out structs.IndexedACLs 193 defer setMeta(resp, &out.QueryMeta) 194 if err := s.agent.RPC("ACL.List", &args, &out); err != nil { 195 return nil, err 196 } 197 198 // Use empty list instead of nil 199 if out.ACLs == nil { 200 out.ACLs = make(structs.ACLs, 0) 201 } 202 return out.ACLs, nil 203 }