package auth import ( "bytes" "encoding/json" "fmt" "log" "net/http" urlpkg "net/url" "git.phc.dm.unipi.it/phc/website/model" ) // ldapUser represents an LDAP User, most fields are inherited from [auth.User] type ldapUser struct { Uid string `json:"username"` NumericId int `json:"id"` Name string `json:"name"` Surname string `json:"surname"` Email string `json:"email"` Role string `json:"role"` Gecos string `json:"gecos"` } // AsUser converts an [ldapUser] to an instance of [auth.User] func (u ldapUser) AsUser() *model.User { return &model.User{ Username: u.Uid, Name: u.Name, Surname: u.Surname, Email: u.Email, FullName: u.Gecos, } } // ldapAuthService just holds the remote host of the HTTP LDAP service to make requests to type ldapAuthService struct { Host string } func newLDAPAuthService(host string) Service { return &ldapAuthService{host} } // doGetRequest is a utility to make HTTP GET requests func (a *ldapAuthService) doGetRequest(url string, response interface{}) error { u, err := urlpkg.JoinPath(a.Host, "poisson-ldap", url) if err != nil { return err } req, err := http.NewRequest( "GET", u, bytes.NewBuffer([]byte("")), ) log.Printf(`%q`, a.Host) if err != nil { log.Printf(`GET %q resulted in %v`, url, err) return err } res, err := http.DefaultClient.Do(req) if err != nil { log.Printf(`GET %q resulted in %v`, url, err) return err } if err := json.NewDecoder(res.Body).Decode(response); err != nil { log.Printf(`GET %q resulted in %v`, url, err) return err } return nil } // doPostRequest is a utility to make HTTP POST requests func (a *ldapAuthService) doPostRequest(url string, request interface{}, response interface{}) error { jsonStr, err := json.Marshal(request) if err != nil { return err } u, err := urlpkg.JoinPath(a.Host, "poisson-ldap", url) if err != nil { return err } req, err := http.NewRequest("POST", u, bytes.NewBuffer(jsonStr)) if err != nil { return err } req.Header.Set("Content-Type", "application/json") res, err := http.DefaultClient.Do(req) if err != nil { return err } return json.NewDecoder(res.Body).Decode(response) } func (a *ldapAuthService) GetUser(username string) (*model.User, error) { var user ldapUser if err := a.doGetRequest(fmt.Sprintf("/user/%s", username), &user); err != nil { return nil, err } return user.AsUser(), nil } func (a *ldapAuthService) GetUsers() ([]*model.User, error) { ldapUsers := []*ldapUser{} if err := a.doGetRequest("/users", &ldapUsers); err != nil { return nil, err } users := make([]*model.User, len(ldapUsers)) for i, u := range ldapUsers { users[i] = u.AsUser() } return users, nil } func (a *ldapAuthService) GetSession(token string) (*model.Session, error) { var response model.Session if err := a.doGetRequest(fmt.Sprintf("/session/%s", token), &response); err != nil { return nil, err } return &response, nil } func (a *ldapAuthService) Login(username, password string) (*model.Session, error) { reqBody := map[string]interface{}{ "username": username, "password": password, } var response model.Session if err := a.doPostRequest("/login", reqBody, &response); err != nil { return nil, err } return &response, nil }