Commit 2ce591e6 authored by ale's avatar ale

Fix the server package for the new backend API

parent a0c1b63b
......@@ -64,8 +64,6 @@ type FindResourceRequest struct {
// AccountService implements the business logic and high-level
// functionality of the user accounts management service.
type AccountService struct {
backend Backend
validator sso.Validator
ssoService string
ssoGroups []string
......@@ -86,7 +84,6 @@ func NewAccountService(backend Backend, config *Config) (*AccountService, error)
func newAccountServiceWithSSO(backend Backend, config *Config, ssoValidator sso.Validator) *AccountService {
s := &AccountService{
backend: backend,
validator: ssoValidator,
ssoService: config.SSO.Service,
ssoGroups: config.SSO.Groups,
......
......@@ -113,7 +113,7 @@ func main() {
log.Fatal(err)
}
as := server.New(service)
as := server.New(service, be)
if err := serverutil.Serve(as.Handler(), config.ServerConfig, *addr); err != nil {
log.Fatal(err)
......
package server
import (
"errors"
"log"
"net/http"
......@@ -9,12 +10,20 @@ import (
as "git.autistici.org/ai3/accountserver"
)
type txHandler func(as.TX, http.ResponseWriter, *http.Request) error
var errBadRequest = errors.New("bad request")
type AccountServer struct {
service *as.AccountService
backend as.Backend
}
func New(service *as.AccountService) *AccountServer {
return &AccountServer{service}
func New(service *as.AccountService, backend as.Backend) *AccountServer {
return &AccountServer{
service: service,
backend: backend,
}
}
var emptyResponse = map[string]string{}
......@@ -32,171 +41,202 @@ func errToStatus(err error) int {
}
}
func (s *AccountServer) handleGetUser(w http.ResponseWriter, r *http.Request) {
func (s *AccountServer) handleGetUser(tx as.TX, w http.ResponseWriter, r *http.Request) error {
var req as.GetUserRequest
if !serverutil.DecodeJSONRequest(w, r, &req) {
return
return errBadRequest
}
user, err := s.service.GetUser(r.Context(), &req)
user, err := s.service.GetUser(r.Context(), tx, &req)
if err != nil {
log.Printf("GetUser(%s): error: %v", req.Username, err)
http.Error(w, err.Error(), errToStatus(err))
return
return err
}
serverutil.EncodeJSONResponse(w, user)
return nil
}
func (s *AccountServer) handleChangeUserPassword(w http.ResponseWriter, r *http.Request) {
func (s *AccountServer) handleChangeUserPassword(tx as.TX, w http.ResponseWriter, r *http.Request) error {
var req as.ChangeUserPasswordRequest
if !serverutil.DecodeJSONRequest(w, r, &req) {
return
return errBadRequest
}
if err := s.service.ChangeUserPassword(r.Context(), &req); err != nil {
if err := s.service.ChangeUserPassword(r.Context(), tx, &req); err != nil {
log.Printf("ChangeUserPassword(%s): error: %v", req.Username, err)
http.Error(w, err.Error(), errToStatus(err))
return
return err
}
serverutil.EncodeJSONResponse(w, emptyResponse)
return nil
}
func (s *AccountServer) handleCreateApplicationSpecificPassword(w http.ResponseWriter, r *http.Request) {
func (s *AccountServer) handleCreateApplicationSpecificPassword(tx as.TX, w http.ResponseWriter, r *http.Request) error {
var req as.CreateApplicationSpecificPasswordRequest
if !serverutil.DecodeJSONRequest(w, r, &req) {
return
return errBadRequest
}
resp, err := s.service.CreateApplicationSpecificPassword(r.Context(), &req)
resp, err := s.service.CreateApplicationSpecificPassword(r.Context(), tx, &req)
if err != nil {
log.Printf("CreateApplicationSpecificPassword(%s): error: %v", req.Username, err)
http.Error(w, err.Error(), errToStatus(err))
return
return err
}
serverutil.EncodeJSONResponse(w, resp)
return nil
}
func (s *AccountServer) handleDeleteApplicationSpecificPassword(w http.ResponseWriter, r *http.Request) {
func (s *AccountServer) handleDeleteApplicationSpecificPassword(tx as.TX, w http.ResponseWriter, r *http.Request) error {
var req as.DeleteApplicationSpecificPasswordRequest
if !serverutil.DecodeJSONRequest(w, r, &req) {
return
return errBadRequest
}
if err := s.service.DeleteApplicationSpecificPassword(r.Context(), &req); err != nil {
if err := s.service.DeleteApplicationSpecificPassword(r.Context(), tx, &req); err != nil {
log.Printf("DeleteApplicationSpecificPassword(%s): error: %v", req.Username, err)
http.Error(w, err.Error(), errToStatus(err))
return
return err
}
serverutil.EncodeJSONResponse(w, emptyResponse)
return nil
}
func (s *AccountServer) handleEnableResource(w http.ResponseWriter, r *http.Request) {
func (s *AccountServer) handleEnableResource(tx as.TX, w http.ResponseWriter, r *http.Request) error {
var req as.EnableResourceRequest
if !serverutil.DecodeJSONRequest(w, r, &req) {
return
return errBadRequest
}
if err := s.service.EnableResource(r.Context(), &req); err != nil {
if err := s.service.EnableResource(r.Context(), tx, &req); err != nil {
log.Printf("EnableResource(%s): error: %v", req.Username, err)
http.Error(w, err.Error(), errToStatus(err))
return
return err
}
serverutil.EncodeJSONResponse(w, emptyResponse)
return nil
}
func (s *AccountServer) handleDisableResource(w http.ResponseWriter, r *http.Request) {
func (s *AccountServer) handleDisableResource(tx as.TX, w http.ResponseWriter, r *http.Request) error {
var req as.DisableResourceRequest
if !serverutil.DecodeJSONRequest(w, r, &req) {
return
return errBadRequest
}
if err := s.service.DisableResource(r.Context(), &req); err != nil {
if err := s.service.DisableResource(r.Context(), tx, &req); err != nil {
log.Printf("DisableResource(%s): error: %v", req.Username, err)
http.Error(w, err.Error(), errToStatus(err))
return
return err
}
serverutil.EncodeJSONResponse(w, emptyResponse)
return nil
}
func (s *AccountServer) handleChangeResourcePassword(w http.ResponseWriter, r *http.Request) {
func (s *AccountServer) handleChangeResourcePassword(tx as.TX, w http.ResponseWriter, r *http.Request) error {
var req as.ChangeResourcePasswordRequest
if !serverutil.DecodeJSONRequest(w, r, &req) {
return
return errBadRequest
}
if err := s.service.ChangeResourcePassword(r.Context(), &req); err != nil {
if err := s.service.ChangeResourcePassword(r.Context(), tx, &req); err != nil {
log.Printf("ChangeResourcePassword(%s): error: %v", req.Username, err)
http.Error(w, err.Error(), errToStatus(err))
return
return err
}
serverutil.EncodeJSONResponse(w, emptyResponse)
return nil
}
func (s *AccountServer) handleMoveResource(w http.ResponseWriter, r *http.Request) {
func (s *AccountServer) handleMoveResource(tx as.TX, w http.ResponseWriter, r *http.Request) error {
var req as.MoveResourceRequest
if !serverutil.DecodeJSONRequest(w, r, &req) {
return
return errBadRequest
}
resp, err := s.service.MoveResource(r.Context(), &req)
resp, err := s.service.MoveResource(r.Context(), tx, &req)
if err != nil {
log.Printf("MoveResource(%s): error: %v", req.Username, err)
http.Error(w, err.Error(), errToStatus(err))
return
return err
}
serverutil.EncodeJSONResponse(w, resp)
return nil
}
func (s *AccountServer) handleEnableOTP(w http.ResponseWriter, r *http.Request) {
func (s *AccountServer) handleEnableOTP(tx as.TX, w http.ResponseWriter, r *http.Request) error {
var req as.EnableOTPRequest
if !serverutil.DecodeJSONRequest(w, r, &req) {
return
return errBadRequest
}
resp, err := s.service.EnableOTP(r.Context(), &req)
resp, err := s.service.EnableOTP(r.Context(), tx, &req)
if err != nil {
log.Printf("EnableOTP(%s): error: %v", req.Username, err)
http.Error(w, err.Error(), errToStatus(err))
return
return err
}
serverutil.EncodeJSONResponse(w, resp)
return nil
}
func (s *AccountServer) handleDisableOTP(w http.ResponseWriter, r *http.Request) {
func (s *AccountServer) handleDisableOTP(tx as.TX, w http.ResponseWriter, r *http.Request) error {
var req as.DisableOTPRequest
if !serverutil.DecodeJSONRequest(w, r, &req) {
return
return errBadRequest
}
if err := s.service.DisableOTP(r.Context(), &req); err != nil {
if err := s.service.DisableOTP(r.Context(), tx, &req); err != nil {
log.Printf("DisableOTP(%s): error: %v", req.Username, err)
http.Error(w, err.Error(), errToStatus(err))
return
return err
}
serverutil.EncodeJSONResponse(w, emptyResponse)
return nil
}
func (s *AccountServer) withTx(f txHandler) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
tx, err := s.backend.NewTransaction()
if err != nil {
log.Printf("NewTransaction error: %v", err)
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
if err := f(tx, w, r); err == nil {
// Automatically commit the transaction (if
// the handler didn't do this itself).
if err := tx.Commit(r.Context()); err != nil {
log.Printf("Commit error: %v", err)
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
}
}
}
func (s *AccountServer) Handler() http.Handler {
h := http.NewServeMux()
h.HandleFunc("/api/user/get", s.handleGetUser)
h.HandleFunc("/api/user/change_password", s.handleChangeUserPassword)
h.HandleFunc("/api/user/enable_otp", s.handleEnableOTP)
h.HandleFunc("/api/user/disable_otp", s.handleDisableOTP)
h.HandleFunc("/api/app_specific_password/create", s.handleCreateApplicationSpecificPassword)
h.HandleFunc("/api/app_specific_password/delete", s.handleDeleteApplicationSpecificPassword)
h.HandleFunc("/api/resource/enable", s.handleEnableResource)
h.HandleFunc("/api/resource/disable", s.handleDisableResource)
h.HandleFunc("/api/resource/change_password", s.handleChangeResourcePassword)
h.HandleFunc("/api/resource/move", s.handleMoveResource)
h.HandleFunc("/api/user/get", s.withTx(s.handleGetUser))
h.HandleFunc("/api/user/change_password", s.withTx(s.handleChangeUserPassword))
h.HandleFunc("/api/user/enable_otp", s.withTx(s.handleEnableOTP))
h.HandleFunc("/api/user/disable_otp", s.withTx(s.handleDisableOTP))
h.HandleFunc("/api/app_specific_password/create", s.withTx(s.handleCreateApplicationSpecificPassword))
h.HandleFunc("/api/app_specific_password/delete", s.withTx(s.handleDeleteApplicationSpecificPassword))
h.HandleFunc("/api/resource/enable", s.withTx(s.handleEnableResource))
h.HandleFunc("/api/resource/disable", s.withTx(s.handleDisableResource))
h.HandleFunc("/api/resource/change_password", s.withTx(s.handleChangeResourcePassword))
h.HandleFunc("/api/resource/move", s.withTx(s.handleMoveResource))
return h
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment