package api_impl import ( "database/sql" "net/http" "atlas9.dev/c/core/dbi" "atlas9.dev/c/core/iam" "atlas9.dev/c/demo/api" "atlas9.dev/c/demo/lib/access" ) type GroupsImpl struct { DB *sql.DB Guard access.Guard Groups dbi.Factory[iam.GroupStore] Audit dbi.Factory[iam.AuditStore] } func (s *GroupsImpl) ServeMux(mux *http.ServeMux) { mux.HandleFunc(api.Path_Groups_Save, s.Save) mux.HandleFunc(api.Path_Groups_Get, s.Get) mux.HandleFunc(api.Path_Groups_Delete, s.Delete) mux.HandleFunc(api.Path_Groups_List, s.List) mux.HandleFunc(api.Path_Groups_ListByTenant, s.ListByTenant) mux.HandleFunc(api.Path_Groups_AddMember, s.AddMember) mux.HandleFunc(api.Path_Groups_RemoveMember, s.RemoveMember) mux.HandleFunc(api.Path_Groups_ListMembers, s.ListMembers) mux.HandleFunc(api.Path_Groups_ListMemberGroups, s.ListMemberGroups) } func (s *GroupsImpl) Save(w http.ResponseWriter, r *http.Request) { // Read and validate the request body var req api.Groups_SaveReq if read(w, r, &req) { return } // Write to the database ctx := r.Context() err := dbi.ReadWrite(ctx, s.DB, func(tx dbi.DBI) error { if err := s.Groups(tx).Save(ctx, &req.Group); err != nil { return err } return audit(ctx, s.Audit(tx), iam.AuditEntry{ Tenant: req.Group.Tenant, Action: "Groups_Save", Resource: string(req.Group.Path), Detail: req.Group.Name, }) }) write(ctx, w, err, nil) } func (s *GroupsImpl) Get(w http.ResponseWriter, r *http.Request) { // Read and validate the request body var req api.Groups_GetReq if read(w, r, &req) { return } // Get group from database ctx := r.Context() var group iam.Group err := dbi.ReadOnly(ctx, s.DB, func(tx dbi.DBI) error { return s.Groups(tx).Get(ctx, req.Tenant, req.Path, &group) }) write(ctx, w, err, api.Groups_GetRes{Group: &group}) } func (s *GroupsImpl) Delete(w http.ResponseWriter, r *http.Request) { // Read and validate the request body var req api.Groups_DeleteReq if read(w, r, &req) { return } // Delete the record from the database ctx := r.Context() err := dbi.ReadWrite(ctx, s.DB, func(tx dbi.DBI) error { if err := s.Groups(tx).Delete(ctx, req.Tenant, req.Path); err != nil { return err } return audit(ctx, s.Audit(tx), iam.AuditEntry{ Tenant: req.Tenant, Action: "Groups_Delete", Resource: string(req.Path), }) }) write(ctx, w, err, api.Groups_DeleteRes{}) } func (s *GroupsImpl) List(w http.ResponseWriter, r *http.Request) { // Read and validate the request body var req api.Groups_ListReq if read(w, r, &req) { return } // Load the data from the database ctx := r.Context() var res api.Groups_ListRes err := dbi.ReadOnly(ctx, s.DB, func(tx dbi.DBI) error { return s.Groups(tx).List(ctx, req.Tenant, req.Page, &res.Page) }) write(ctx, w, err, res) } func (s *GroupsImpl) ListByTenant(w http.ResponseWriter, r *http.Request) { // Read and validate the request body var req api.Groups_ListByTenantReq if read(w, r, &req) { return } // Load the data from the database ctx := r.Context() var res api.Groups_ListRes err := dbi.ReadOnly(ctx, s.DB, func(tx dbi.DBI) error { return s.Groups(tx).List(ctx, req.Tenant, req.Page, &res.Page) }) write(ctx, w, err, res) } func (s *GroupsImpl) AddMember(w http.ResponseWriter, r *http.Request) { // Read and validate the request body var req api.Groups_AddMemberReq if read(w, r, &req) { return } // Write to the database ctx := r.Context() err := dbi.ReadWrite(ctx, s.DB, func(tx dbi.DBI) error { if err := s.Groups(tx).AddMember(ctx, req.Tenant, req.Group, req.UserID); err != nil { return err } return audit(ctx, s.Audit(tx), iam.AuditEntry{ Tenant: req.Tenant, Action: "Groups_AddMember", Resource: req.UserID.String(), Detail: string(req.Group), }) }) write(ctx, w, err, api.Groups_AddMemberRes{}) } func (s *GroupsImpl) RemoveMember(w http.ResponseWriter, r *http.Request) { // Read and validate the request body var req api.Groups_RemoveMemberReq if read(w, r, &req) { return } // Write to the database ctx := r.Context() err := dbi.ReadWrite(ctx, s.DB, func(tx dbi.DBI) error { if err := s.Groups(tx).RemoveMember(ctx, req.Tenant, req.Group, req.UserID); err != nil { return err } return audit(ctx, s.Audit(tx), iam.AuditEntry{ Tenant: req.Tenant, Action: "Groups_RemoveMember", Resource: req.UserID.String(), Detail: string(req.Group), }) }) write(ctx, w, err, api.Groups_RemoveMemberRes{}) } func (s *GroupsImpl) ListMembers(w http.ResponseWriter, r *http.Request) { // Read and validate the request body var req api.Groups_ListMembersReq if read(w, r, &req) { return } // Load the data from the database ctx := r.Context() var res api.Groups_ListMembersRes err := dbi.ReadOnly(ctx, s.DB, func(tx dbi.DBI) error { return s.Groups(tx).ListMembers(ctx, req.Tenant, req.Group, req.Page, &res.Page) }) write(ctx, w, err, res) } func (s *GroupsImpl) ListMemberGroups(w http.ResponseWriter, r *http.Request) { // Read and validate the request body var req api.Groups_ListMemberGroupsReq if read(w, r, &req) { return } // Load the data from the database ctx := r.Context() var res api.Groups_ListMemberGroupsRes err := dbi.ReadOnly(ctx, s.DB, func(tx dbi.DBI) error { return s.Groups(tx).ListMemberGroups(ctx, req.UserID, req.Page, &res.Page) }) write(ctx, w, err, res) }