github.com/crewjam/saml@v0.4.14/samlidp/user.go (about) 1 package samlidp 2 3 import ( 4 "encoding/json" 5 "fmt" 6 "net/http" 7 8 "github.com/zenazn/goji/web" 9 "golang.org/x/crypto/bcrypt" 10 ) 11 12 // User represents a stored user. The data here are used to 13 // populate user once the user has authenticated. 14 type User struct { 15 Name string `json:"name"` 16 PlaintextPassword *string `json:"password,omitempty"` // not stored 17 HashedPassword []byte `json:"hashed_password,omitempty"` 18 Groups []string `json:"groups,omitempty"` 19 Email string `json:"email,omitempty"` 20 CommonName string `json:"common_name,omitempty"` 21 Surname string `json:"surname,omitempty"` 22 GivenName string `json:"given_name,omitempty"` 23 ScopedAffiliation string `json:"scoped_affiliation,omitempty"` 24 } 25 26 // HandleListUsers handles the `GET /users/` request and responds with a JSON formatted list 27 // of user names. 28 func (s *Server) HandleListUsers(_ web.C, w http.ResponseWriter, _ *http.Request) { 29 users, err := s.Store.List("/users/") 30 if err != nil { 31 s.logger.Printf("ERROR: %s", err) 32 http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError) 33 return 34 } 35 36 err = json.NewEncoder(w).Encode(struct { 37 Users []string `json:"users"` 38 }{Users: users}) 39 if err != nil { 40 s.logger.Printf("ERROR: %s", err) 41 http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError) 42 return 43 } 44 } 45 46 // HandleGetUser handles the `GET /users/:id` request and responds with the user object in JSON 47 // format. The HashedPassword field is excluded. 48 func (s *Server) HandleGetUser(c web.C, w http.ResponseWriter, _ *http.Request) { 49 user := User{} 50 err := s.Store.Get(fmt.Sprintf("/users/%s", c.URLParams["id"]), &user) 51 if err != nil { 52 s.logger.Printf("ERROR: %s", err) 53 http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError) 54 return 55 } 56 user.HashedPassword = nil 57 if err := json.NewEncoder(w).Encode(user); err != nil { 58 s.logger.Printf("ERROR: %s", err) 59 http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError) 60 return 61 } 62 } 63 64 // HandlePutUser handles the `PUT /users/:id` request. It accepts a JSON formatted user object in 65 // the request body and stores it. If the PlaintextPassword field is present then it is hashed 66 // and stored in HashedPassword. If the PlaintextPassword field is not present then 67 // HashedPassword retains it's stored value. 68 func (s *Server) HandlePutUser(c web.C, w http.ResponseWriter, r *http.Request) { 69 user := User{} 70 if err := json.NewDecoder(r.Body).Decode(&user); err != nil { 71 s.logger.Printf("ERROR: %s", err) 72 http.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest) 73 return 74 } 75 user.Name = c.URLParams["id"] 76 77 if user.PlaintextPassword != nil { 78 var err error 79 user.HashedPassword, err = bcrypt.GenerateFromPassword([]byte(*user.PlaintextPassword), bcrypt.DefaultCost) 80 if err != nil { 81 s.logger.Printf("ERROR: %s", err) 82 http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError) 83 return 84 } 85 } else { 86 existingUser := User{} 87 err := s.Store.Get(fmt.Sprintf("/users/%s", c.URLParams["id"]), &existingUser) 88 switch { 89 case err == nil: 90 user.HashedPassword = existingUser.HashedPassword 91 case err == ErrNotFound: 92 // nop 93 default: 94 s.logger.Printf("ERROR: %s", err) 95 http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError) 96 return 97 } 98 } 99 user.PlaintextPassword = nil 100 101 err := s.Store.Put(fmt.Sprintf("/users/%s", c.URLParams["id"]), &user) 102 if err != nil { 103 s.logger.Printf("ERROR: %s", err) 104 http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError) 105 return 106 } 107 w.WriteHeader(http.StatusNoContent) 108 } 109 110 // HandleDeleteUser handles the `DELETE /users/:id` request. 111 func (s *Server) HandleDeleteUser(c web.C, w http.ResponseWriter, _ *http.Request) { 112 err := s.Store.Delete(fmt.Sprintf("/users/%s", c.URLParams["id"])) 113 if err != nil { 114 s.logger.Printf("ERROR: %s", err) 115 http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError) 116 return 117 } 118 w.WriteHeader(http.StatusNoContent) 119 }