Browse Source

Empty groups instead of deleting them

And don't allow to add an unexisting user to a group.
communities
meskio 1 year ago
parent
commit
7926084e8c
Signed by: meskio
GPG Key ID: 52B8F5AC97A2DA86
  1. 72
      db/collective.go
  2. 85
      db/collective_test.go
  3. 72
      db/community.go
  4. 85
      db/community_test.go
  5. 2
      db/db.go
  6. 27
      ldap/group.go
  7. 12
      main.go
  8. 2
      server/add_user.go
  9. 215
      server/collective.go
  10. 215
      server/community.go
  11. 18
      server/server.go
  12. 6
      server/template.go
  13. 30
      tmpl/add_collective.html
  14. 30
      tmpl/add_community.html
  15. 12
      tmpl/collective.html
  16. 4
      tmpl/collectives.html
  17. 4
      tmpl/index.html
  18. 6
      tmpl/navbar.html
  19. 6
      tmpl/user.html

72
db/collective.go

@ -0,0 +1,72 @@
package db
import (
"encoding/json"
"errors"
"log"
"time"
"go.etcd.io/bbolt"
)
var (
collectiveBucket = []byte("collective")
)
type collective struct {
Name string
CreationDate time.Time
}
// AddCollective stores in the db the collective that was created by host
func (db *DB) AddCollective(name string, host string) error {
var collectives []collective
err := db.get(collectiveBucket, host, &collectives)
if err != nil && !errors.Is(err, notFoundError{}) {
return err
}
collectives = append(collectives, collective{name, time.Now()})
return db.put(collectiveBucket, host, collectives)
}
// CountCollectives returns the nubmer of collectives created by host
func (db *DB) CountCollectives(host string) (int, error) {
var collectives []collective
err := db.get(collectiveBucket, host, &collectives)
if errors.Is(err, notFoundError{}) {
return 0, nil
}
return len(collectives), err
}
// ExpireCollectives older than duration
func (db *DB) ExpireCollectives(duration time.Duration) error {
return db.bolt.Update(func(tx *bbolt.Tx) error {
b := tx.Bucket(collectiveBucket)
return b.ForEach(func(k, v []byte) error {
var collectives []collective
err := json.Unmarshal(v, &collectives)
if err != nil {
log.Printf("Error unmarshalling %s: %v", string(k), err)
return nil
}
newCollectives := []collective{}
for _, c := range collectives {
if c.CreationDate.Add(duration).After(time.Now()) {
newCollectives = append(newCollectives, c)
}
}
if len(newCollectives) == len(collectives) {
return nil
}
encodedValue, err := json.Marshal(newCollectives)
if err != nil {
return err
}
return b.Put(k, encodedValue)
})
})
}

85
db/collective_test.go

@ -0,0 +1,85 @@
package db
import (
"testing"
"time"
)
const (
collectiveName = "collective"
collectiveHost = "host"
)
func TestAddCountCollective(t *testing.T) {
db := initTestDB(t)
defer delTestDB(db)
count, err := db.CountCollectives(collectiveHost)
if err != nil {
t.Fatalf("Got an error counting collectives: %v", err)
}
if count != 0 {
t.Errorf("Got an unexpected number of collectives: %d", count)
}
err = db.AddCollective(collectiveName, collectiveHost)
if err != nil {
t.Fatalf("Got an error adding a collective: %v", err)
}
count, err = db.CountCollectives(collectiveHost)
if err != nil {
t.Fatalf("Got an error counting collectives: %v", err)
}
if count != 1 {
t.Errorf("Got an unexpected number of collectives: %d", count)
}
err = db.AddCollective(collectiveName+"1", collectiveHost)
if err != nil {
t.Fatalf("Got an error adding a collective: %v", err)
}
err = db.AddCollective(collectiveName+"2", collectiveHost)
if err != nil {
t.Fatalf("Got an error adding a collective: %v", err)
}
count, err = db.CountCollectives(collectiveHost)
if err != nil {
t.Fatalf("Got an error counting collectives: %v", err)
}
if count != 3 {
t.Errorf("Got an unexpected number of collectives: %d", count)
}
}
func TestExpireCollectives(t *testing.T) {
db := initTestDB(t)
defer delTestDB(db)
err := db.AddCollective(collectiveName, collectiveHost)
if err != nil {
t.Fatalf("Got an error adding a collective: %v", err)
}
count, err := db.CountCollectives(collectiveHost)
if err != nil {
t.Fatalf("Got an error counting collectives: %v", err)
}
if count != 1 {
t.Errorf("Got an unexpected number of collectives: %d", count)
}
err = db.ExpireCollectives(time.Microsecond)
if err != nil {
t.Fatalf("Got an error expiring invites: %v", err)
}
count, err = db.CountCollectives(collectiveHost)
if err != nil {
t.Fatalf("Got an error counting collectives: %v", err)
}
if count != 0 {
t.Errorf("Got an unexpected number of collectives: %d", count)
}
}

72
db/community.go

@ -1,72 +0,0 @@
package db
import (
"encoding/json"
"errors"
"log"
"time"
"go.etcd.io/bbolt"
)
var (
communityBucket = []byte("community")
)
type community struct {
Name string
CreationDate time.Time
}
// AddCommunity stores in the db the community that was created by host
func (db *DB) AddCommunity(name string, host string) error {
var communities []community
err := db.get(communityBucket, host, &communities)
if err != nil && !errors.Is(err, notFoundError{}) {
return err
}
communities = append(communities, community{name, time.Now()})
return db.put(communityBucket, host, communities)
}
// CountCommunities returns the nubmer of communities created by host
func (db *DB) CountCommunities(host string) (int, error) {
var communities []community
err := db.get(communityBucket, host, &communities)
if errors.Is(err, notFoundError{}) {
return 0, nil
}
return len(communities), err
}
// ExpireCommunities older than duration
func (db *DB) ExpireCommunities(duration time.Duration) error {
return db.bolt.Update(func(tx *bbolt.Tx) error {
b := tx.Bucket(communityBucket)
return b.ForEach(func(k, v []byte) error {
var communities []community
err := json.Unmarshal(v, &communities)
if err != nil {
log.Printf("Error unmarshalling %s: %v", string(k), err)
return nil
}
newCommunities := []community{}
for _, c := range communities {
if c.CreationDate.Add(duration).After(time.Now()) {
newCommunities = append(newCommunities, c)
}
}
if len(newCommunities) == len(communities) {
return nil
}
encodedValue, err := json.Marshal(newCommunities)
if err != nil {
return err
}
return b.Put(k, encodedValue)
})
})
}

85
db/community_test.go

@ -1,85 +0,0 @@
package db
import (
"testing"
"time"
)
const (
communityName = "community"
communityHost = "host"
)
func TestAddCountCommunity(t *testing.T) {
db := initTestDB(t)
defer delTestDB(db)
count, err := db.CountCommunities(communityHost)
if err != nil {
t.Fatalf("Got an error counting communities: %v", err)
}
if count != 0 {
t.Errorf("Got an unexpected number of communities: %d", count)
}
err = db.AddCommunity(communityName, communityHost)
if err != nil {
t.Fatalf("Got an error adding a community: %v", err)
}
count, err = db.CountCommunities(communityHost)
if err != nil {
t.Fatalf("Got an error counting communities: %v", err)
}
if count != 1 {
t.Errorf("Got an unexpected number of communities: %d", count)
}
err = db.AddCommunity(communityName+"1", communityHost)
if err != nil {
t.Fatalf("Got an error adding a community: %v", err)
}
err = db.AddCommunity(communityName+"2", communityHost)
if err != nil {
t.Fatalf("Got an error adding a community: %v", err)
}
count, err = db.CountCommunities(communityHost)
if err != nil {
t.Fatalf("Got an error counting communities: %v", err)
}
if count != 3 {
t.Errorf("Got an unexpected number of communities: %d", count)
}
}
func TestExpireCommunities(t *testing.T) {
db := initTestDB(t)
defer delTestDB(db)
err := db.AddCommunity(communityName, communityHost)
if err != nil {
t.Fatalf("Got an error adding a community: %v", err)
}
count, err := db.CountCommunities(communityHost)
if err != nil {
t.Fatalf("Got an error counting communities: %v", err)
}
if count != 1 {
t.Errorf("Got an unexpected number of communities: %d", count)
}
err = db.ExpireCommunities(time.Microsecond)
if err != nil {
t.Fatalf("Got an error expiring invites: %v", err)
}
count, err = db.CountCommunities(communityHost)
if err != nil {
t.Fatalf("Got an error counting communities: %v", err)
}
if count != 0 {
t.Errorf("Got an unexpected number of communities: %d", count)
}
}

2
db/db.go

@ -21,7 +21,7 @@ func Init(path string) (*DB, error) {
}
err = bolt.Update(func(tx *bbolt.Tx) error {
for _, bucket := range [][]byte{inviteBucket, accountBucket, communityBucket} {
for _, bucket := range [][]byte{inviteBucket, accountBucket, collectiveBucket} {
_, err := tx.CreateBucketIfNotExists(bucket)
if err != nil {

27
ldap/group.go

@ -129,8 +129,29 @@ func (l Ldap) DelGroup(group string) error {
return l.del(l.groupDN(group))
}
// EmptyGroup removes all the members from the group
func (l Ldap) EmptyGroup(group string) error {
filter := fmt.Sprintf("(&(objectClass=posixGroup)(cn=%s))", ldap.EscapeFilter(group))
groups, err := l.searchGroup(filter)
if err != nil {
return err
}
if len(groups) == 0 {
return ErrNotFound
}
return l.delUsersGroup(groups[0].Members, group)
}
// AddUserGroup add user into the group members
func (l Ldap) AddUserGroup(user string, group string) error {
u, err := l.GetUser(user)
if !errors.Is(err, ErrNotFound) || u.Locked != Unlocked {
return ErrNotFound
}
if err != nil {
return err
}
conn, err := l.connect()
if err != nil {
return err
@ -144,6 +165,10 @@ func (l Ldap) AddUserGroup(user string, group string) error {
// DelUserGroup removes the user from the group members
func (l Ldap) DelUserGroup(user string, group string) error {
return l.delUsersGroup([]string{ldap.EscapeFilter(user)}, group)
}
func (l Ldap) delUsersGroup(users []string, group string) error {
conn, err := l.connect()
if err != nil {
return err
@ -151,7 +176,7 @@ func (l Ldap) DelUserGroup(user string, group string) error {
defer conn.Close()
modifyRequest := ldap.NewModifyRequest(l.groupDN(group), nil)
modifyRequest.Delete("memberUid", []string{ldap.EscapeFilter(user)})
modifyRequest.Delete("memberUid", users)
return conn.Modify(modifyRequest)
}

12
main.go

@ -17,11 +17,11 @@ import (
)
var (
inviteExpireDuration = time.Hour * 24 * 30 // 30 days
communityExpireDuration = time.Hour * 24 * 90 // 90 days
accountExpireDuration = time.Hour * 24 * 90 // 90 days
accountBlockDuration = time.Hour * 24 * 6 * 30 // ~ 6 months
accountDeleteDuration = time.Hour * 24 * 365 // ~ 1 year
inviteExpireDuration = time.Hour * 24 * 30 // 30 days
collectiveExpireDuration = time.Hour * 24 * 90 // 90 days
accountExpireDuration = time.Hour * 24 * 90 // 90 days
accountBlockDuration = time.Hour * 24 * 6 * 30 // ~ 6 months
accountDeleteDuration = time.Hour * 24 * 365 // ~ 1 year
)
func main() {
@ -123,7 +123,7 @@ func cleanInvites(ldb *db.DB) {
for {
ldb.ExpireInvites(inviteExpireDuration)
ldb.ExpireAccounts(accountExpireDuration)
ldb.ExpireCommunities(communityExpireDuration)
ldb.ExpireCollectives(collectiveExpireDuration)
time.Sleep(time.Minute * 60)
}
}

2
server/add_user.go

@ -197,7 +197,7 @@ func (s *server) addUserHandler(w http.ResponseWriter, r *http.Request) {
err = s.ldap.AddGroup(name, "")
if err != nil {
if errors.Is(err, ldap.ErrAlreadyExist) {
log.Println("Can't create user ", name, " there is already a community with this name")
log.Println("Can't create user ", name, " there is already a collective with this name")
response.execute("exists")
} else {
log.Println("Error adding group: ", err)

215
server/collective.go

@ -0,0 +1,215 @@
package server
import (
"errors"
"log"
"net/http"
"git.sindominio.net/sindominio/lowry/ldap"
"github.com/gorilla/mux"
)
const (
maxCollectives = 4
)
func (s *server) addCollectiveHandler(w http.ResponseWriter, r *http.Request) {
response := s.newResponse("add_collective", w, r)
ok, err := s.canCreateCollective(response)
if err != nil {
log.Println("An error ocurred checking if can create collective: ", err)
s.errorHandler(w, r)
return
}
status := ""
if !ok {
status = "quota"
}
response.execute(status)
}
func (s *server) postAddCollectiveHandler(w http.ResponseWriter, r *http.Request) {
response := s.newResponse("add_collective", w, r)
ok, err := s.canCreateCollective(response)
if err != nil {
log.Println("An error ocurred checking if can create collective: ", err)
s.errorHandler(w, r)
return
}
if !ok {
response.execute("quota")
return
}
collectiveName := r.FormValue("collective")
if !validUserName(collectiveName) {
log.Println("Can't create collective ", collectiveName, ": invalid name")
response.execute("invalid")
return
}
description := r.FormValue("description")
err = s.ldap.AddGroup(collectiveName, description)
if err != nil {
if errors.Is(err, ldap.ErrAlreadyExist) {
response.execute("exists")
} else {
log.Println("An error ocurred adding collective '", collectiveName, "': ", err)
s.errorHandler(w, r)
}
return
}
err = s.ldap.AddUserGroup(response.User, collectiveName)
if err != nil {
log.Println("An error ocurred adding user ", response.User, " to collective '", collectiveName, "': ", err)
s.errorHandler(w, r)
return
}
http.Redirect(w, r, "/collective/"+collectiveName, http.StatusFound)
}
func (s *server) delCollectiveHandler(w http.ResponseWriter, r *http.Request) {
collectiveName := r.FormValue("collective")
response := s.newResponse("", w, r)
if !response.IsAdmin && !s.ldap.InGroup(response.User, collectiveName) {
log.Println(response.User, "don't have rights to delete", collectiveName, "collective")
s.forbiddenHandler(w, r)
return
}
err := s.ldap.EmptyGroup(collectiveName)
if err != nil {
log.Println("An error ocurred deleting collective '", collectiveName, "': ", err)
s.errorHandler(w, r)
return
}
http.Redirect(w, r, "/collectives/mine/", http.StatusFound)
}
func (s *server) collectivesHandler(w http.ResponseWriter, r *http.Request) {
response := s.newResponse("collectives", w, r)
if !response.IsAdmin {
log.Println("Non admin attemp to list collectives")
s.forbiddenHandler(w, r)
return
}
collectives, err := s.ldap.ListGroups()
if err != nil {
log.Println("An error ocurred retrieving collective list: ", err)
s.errorHandler(w, r)
return
}
response.execute(collectives)
}
func (s *server) userCollectivesHandler(w http.ResponseWriter, r *http.Request) {
response := s.newResponse("collectives", w, r)
if response.User == "" {
log.Println("Attemp to list own collective without being logged")
s.forbiddenHandler(w, r)
return
}
collectives, err := s.ldap.UserGroups(response.User)
if err != nil {
log.Println("An error ocurred retrieving collective list: ", err)
s.errorHandler(w, r)
return
}
response.execute(collectives)
}
func (s *server) collectiveHandler(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
collectiveName := vars["name"]
response := s.newResponse("collective", w, r)
if !response.IsAdmin && !s.ldap.InGroup(response.User, collectiveName) {
log.Println("Attemp to list collective without rights")
s.forbiddenHandler(w, r)
return
}
collective, err := s.ldap.GetGroup(collectiveName)
if err != nil {
log.Println("An error ocurred retrieving collective '", collectiveName, "': ", err)
s.errorHandler(w, r)
return
}
response.execute(collective)
}
func (s *server) addUserCollectiveHandler(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
collectiveName := vars["name"]
response := s.newResponse("", w, r)
if !response.IsAdmin && !s.ldap.InGroup(response.User, collectiveName) {
log.Println("Attemp to add user to collective without rights")
s.forbiddenHandler(w, r)
return
}
user := r.FormValue("user")
err := s.ldap.AddUserGroup(user, collectiveName)
if err != nil {
log.Println("An error ocurred adding user '", user, "' to ", collectiveName, ": ", err)
s.errorHandler(w, r)
return
}
http.Redirect(w, r, "/collective/"+collectiveName, http.StatusFound)
}
func (s *server) delUserCollectiveHandler(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
collectiveName := vars["name"]
response := s.newResponse("", w, r)
if !response.IsAdmin && !s.ldap.InGroup(response.User, collectiveName) {
log.Println("Attemp to del user to collective without rights")
s.forbiddenHandler(w, r)
return
}
user := r.FormValue("user")
err := s.ldap.DelUserGroup(user, collectiveName)
if err != nil {
log.Println("An error ocurred del user '", user, "' to ", collectiveName, ": ", err)
s.errorHandler(w, r)
return
}
http.Redirect(w, r, "/collective/"+collectiveName, http.StatusFound)
}
func (s *server) descriptionCollectiveHandler(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
collectiveName := vars["name"]
response := s.newResponse("", w, r)
if !response.IsAdmin && !s.ldap.InGroup(response.User, collectiveName) {
log.Println("Attemp to edit description without rights of collective", collectiveName)
s.forbiddenHandler(w, r)
return
}
description := r.FormValue("description")
err := s.ldap.UpdateGroupDescription(collectiveName, description)
if err != nil {
log.Println("An error ocurred to set description to ", collectiveName, ": ", err)
s.errorHandler(w, r)
return
}
http.Redirect(w, r, "/collective/"+collectiveName, http.StatusFound)
}
func (s *server) canCreateCollective(r responseT) (bool, error) {
if r.User == "" {
return false, nil
}
if r.Role == ldap.Sindominante {
return true, nil
}
count, err := s.db.CountCollectives(r.User)
return count <= maxCollectives, err
}

215
server/community.go

@ -1,215 +0,0 @@
package server
import (
"errors"
"log"
"net/http"
"git.sindominio.net/sindominio/lowry/ldap"
"github.com/gorilla/mux"
)
const (
maxCommunities = 4
)
func (s *server) addCommunityHandler(w http.ResponseWriter, r *http.Request) {
response := s.newResponse("add_community", w, r)
ok, err := s.canCreateCommunity(response)
if err != nil {
log.Println("An error ocurred checking if can create community: ", err)
s.errorHandler(w, r)
return
}
status := ""
if !ok {
status = "quota"
}
response.execute(status)
}
func (s *server) postAddCommunityHandler(w http.ResponseWriter, r *http.Request) {
response := s.newResponse("add_community", w, r)
ok, err := s.canCreateCommunity(response)
if err != nil {
log.Println("An error ocurred checking if can create community: ", err)
s.errorHandler(w, r)
return
}
if !ok {
response.execute("quota")
return
}
communityName := r.FormValue("community")
if !validUserName(communityName) {
log.Println("Can't create community ", communityName, ": invalid name")
response.execute("invalid")
return
}
description := r.FormValue("description")
err = s.ldap.AddGroup(communityName, description)
if err != nil {
if errors.Is(err, ldap.ErrAlreadyExist) {
response.execute("exists")
} else {
log.Println("An error ocurred adding community '", communityName, "': ", err)
s.errorHandler(w, r)
}
return
}
err = s.ldap.AddUserGroup(response.User, communityName)
if err != nil {
log.Println("An error ocurred adding user ", response.User, " to community '", communityName, "': ", err)
s.errorHandler(w, r)
return
}
http.Redirect(w, r, "/community/"+communityName, http.StatusFound)
}
func (s *server) delCommunityHandler(w http.ResponseWriter, r *http.Request) {
communityName := r.FormValue("community")
response := s.newResponse("", w, r)
if !response.IsAdmin && !s.ldap.InGroup(response.User, communityName) {
log.Println(response.User, "don't have rights to delete", communityName, "community")
s.forbiddenHandler(w, r)
return
}
err := s.ldap.DelGroup(communityName)
if err != nil {
log.Println("An error ocurred deleting community '", communityName, "': ", err)
s.errorHandler(w, r)
return
}
http.Redirect(w, r, "/communities/mine/", http.StatusFound)
}
func (s *server) communitiesHandler(w http.ResponseWriter, r *http.Request) {
response := s.newResponse("communities", w, r)
if !response.IsAdmin {
log.Println("Non admin attemp to list communities")
s.forbiddenHandler(w, r)
return
}
communities, err := s.ldap.ListGroups()
if err != nil {
log.Println("An error ocurred retrieving community list: ", err)
s.errorHandler(w, r)
return
}
response.execute(communities)
}
func (s *server) userCommunitiesHandler(w http.ResponseWriter, r *http.Request) {
response := s.newResponse("communities", w, r)
if response.User == "" {
log.Println("Attemp to list own community without being logged")
s.forbiddenHandler(w, r)
return
}
communities, err := s.ldap.UserGroups(response.User)
if err != nil {
log.Println("An error ocurred retrieving community list: ", err)
s.errorHandler(w, r)
return
}
response.execute(communities)
}
func (s *server) communityHandler(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
communityName := vars["name"]
response := s.newResponse("community", w, r)
if !response.IsAdmin && !s.ldap.InGroup(response.User, communityName) {
log.Println("Attemp to list community without rights")
s.forbiddenHandler(w, r)
return
}
community, err := s.ldap.GetGroup(communityName)
if err != nil {
log.Println("An error ocurred retrieving community '", communityName, "': ", err)
s.errorHandler(w, r)
return
}
response.execute(community)
}
func (s *server) addUserCommunityHandler(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
communityName := vars["name"]
response := s.newResponse("", w, r)
if !response.IsAdmin && !s.ldap.InGroup(response.User, communityName) {
log.Println("Attemp to add user to community without rights")
s.forbiddenHandler(w, r)
return
}
user := r.FormValue("user")
err := s.ldap.AddUserGroup(user, communityName)
if err != nil {
log.Println("An error ocurred adding user '", user, "' to ", communityName, ": ", err)
s.errorHandler(w, r)
return
}
http.Redirect(w, r, "/community/"+communityName, http.StatusFound)
}
func (s *server) delUserCommunityHandler(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
communityName := vars["name"]
response := s.newResponse("", w, r)
if !response.IsAdmin && !s.ldap.InGroup(response.User, communityName) {
log.Println("Attemp to del user to community without rights")
s.forbiddenHandler(w, r)
return
}
user := r.FormValue("user")
err := s.ldap.DelUserGroup(user, communityName)
if err != nil {
log.Println("An error ocurred del user '", user, "' to ", communityName, ": ", err)
s.errorHandler(w, r)
return
}
http.Redirect(w, r, "/community/"+communityName, http.StatusFound)
}
func (s *server) descriptionCommunityHandler(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
communityName := vars["name"]
response := s.newResponse("", w, r)
if !response.IsAdmin && !s.ldap.InGroup(response.User, communityName) {
log.Println("Attemp to edit description without rights of community", communityName)
s.forbiddenHandler(w, r)
return
}
description := r.FormValue("description")
err := s.ldap.UpdateGroupDescription(communityName, description)
if err != nil {
log.Println("An error ocurred to set description to ", communityName, ": ", err)
s.errorHandler(w, r)
return
}
http.Redirect(w, r, "/community/"+communityName, http.StatusFound)
}
func (s *server) canCreateCommunity(r responseT) (bool, error) {
if r.User == "" {
return false, nil
}
if r.Role == ldap.Sindominante {
return true, nil
}
count, err := s.db.CountCommunities(r.User)
return count <= maxCommunities, err
}

18
server/server.go

@ -55,15 +55,15 @@ func Serve(addr string, l *ldap.Ldap, m *mail.Mail, ldb *db.DB, g *gitea.Gitea)
r.HandleFunc("/adduser/", s.createInviteHandler)
r.HandleFunc("/adduser/{invite}", s.addUserHandler)
r.HandleFunc("/communities/", s.communitiesHandler)
r.HandleFunc("/communities/mine/", s.userCommunitiesHandler)
r.HandleFunc("/communities/add/", s.addCommunityHandler).Methods("GET")
r.HandleFunc("/communities/add/", s.postAddCommunityHandler).Methods("POST")
r.HandleFunc("/communities/del/", s.delCommunityHandler).Methods("POST")
r.HandleFunc("/community/{name}", s.communityHandler)
r.HandleFunc("/community/{name}/add/", s.addUserCommunityHandler).Methods("POST")
r.HandleFunc("/community/{name}/del/", s.delUserCommunityHandler).Methods("POST")
r.HandleFunc("/community/{name}/description/", s.descriptionCommunityHandler).Methods("POST")
r.HandleFunc("/collectives/", s.collectivesHandler)
r.HandleFunc("/collectives/mine/", s.userCollectivesHandler)
r.HandleFunc("/collectives/add/", s.addCollectiveHandler).Methods("GET")
r.HandleFunc("/collectives/add/", s.postAddCollectiveHandler).Methods("POST")
r.HandleFunc("/collectives/del/", s.delCollectiveHandler).Methods("POST")
r.HandleFunc("/collective/{name}", s.collectiveHandler)
r.HandleFunc("/collective/{name}/add/", s.addUserCollectiveHandler).Methods("POST")
r.HandleFunc("/collective/{name}/del/", s.delUserCollectiveHandler).Methods("POST")
r.HandleFunc("/collective/{name}/description/", s.descriptionCollectiveHandler).Methods("POST")
r.HandleFunc("/gitea/", s.giteaHandler)

6
server/template.go

@ -41,9 +41,9 @@ func initTemplate() *template.Template {
"tmpl/invites.html",
"tmpl/adduser.html",
"tmpl/adduser_success.html",
"tmpl/community.html",
"tmpl/communities.html",
"tmpl/add_community.html",
"tmpl/collective.html",
"tmpl/collectives.html",
"tmpl/add_collective.html",
"tmpl/gitea.html",
"tmpl/load-password.js",
))

30
tmpl/add_collective.html

@ -0,0 +1,30 @@
{{template "header.html"}}
{{template "header_close.html"}}
{{template "navbar.html" .}}
<div class="container">
<br />
{{if eq .Data "quota"}}
<p>Has excedido el maximo de colectivos que puedes crear. Solo se pueden crear 4 colectivos cada 3 meses. Si tienes alguna razón importante para crear mas contacta con la asamblea de sindominio para ver si pueden hacer algo. O si no esperate unas semanas a ver si vuelves a poder crear colectivos.</p>
{{else}}
<h3>Añade un colectivo</h3>
<form action="/collectives/add/" method="post">
<div class="form-group">
<label for="collective">Nombre:</label>
<input type="text" class="form-control {{if eq .Data "exists" "invalid"}}is-invalid{{end}}" id="collective" name="collective" placeholder="Nombre">
{{if eq .Data "invalid"}}<div class="invalid-feedback">El nombre del colectivo es invalido. Tiene que tener al menos 3 caracteres, empezar por letra o numero y solo puede contener letras minusculas, numeros, '_', '-' o '.'.</div>{{end}}
{{if eq .Data "exists"}}<div class="invalid-feedback">Este nombre ya existe en sindominio como una cuenta o colectivo, elige otro diferente.</div>{{end}}
</div>
<div class="form-group">
<label for="collective">Description:</label>
<textarea class="form-control" id="description" name="description"></textarea>
</div>
<div class="form-group">
<button type="submit" class="btn btn-primary">añadir</button>
</div>
</form>
{{end}}
</div>
{{template "footer.html"}}

30
tmpl/add_community.html

@ -1,30 +0,0 @@
{{template "header.html"}}
{{template "header_close.html"}}
{{template "navbar.html" .}}
<div class="container">
<br />
{{if eq .Data "quota"}}
<p>Has excedido el maximo de colectividades que puedes crear. Solo se pueden crear 4 colectividades cada 3 meses. Si tienes alguna razón importante para crear mas contacta con la asamblea de sindominio para ver si pueden hacer algo. O si no esperate unas semanas a ver si vuelves a poder crear colectividades.</p>
{{else}}
<h3>Añade una colectividad</h3>
<form action="/communities/add/" method="post">
<div class="form-group">
<label for="community">Nombre:</label>
<input type="text" class="form-control {{if eq .Data "exists" "invalid"}}is-invalid{{end}}" id="community" name="community" placeholder="Nombre">
{{if eq .Data "invalid"}}<div class="invalid-feedback">El nombre de la colectividad es invalido. Tiene que tener al menos 3 caracteres, empezar por letra o numero y solo puede contener letras minusculas, numeros, '_', '-' o '.'.</div>{{end}}
{{if eq .Data "exists"}}<div class="invalid-feedback">Este nombre ya existe en sindominio como una cuenta o colectividad, elige otro diferente.</div>{{end}}
</div>
<div class="form-group">
<label for="community">Description:</label>
<textarea class="form-control" id="description" name="description"></textarea>
</div>
<div class="form-group">
<button type="submit" class="btn btn-primary">añadir</button>
</div>
</form>
{{end}}
</div>
{{template "footer.html"}}

12
tmpl/community.html → tmpl/collective.html

@ -18,7 +18,7 @@
<br />
<div class="row justify-content-center">
<form action="/community/{{.Name}}/add/" method="post">
<form action="/collective/{{.Name}}/add/" method="post">
<div class="row">
<div class="col">
<label for="user">Añade cuenta:</label>
@ -33,7 +33,7 @@
</form>
</div>
<div class="row justify-content-center">
<form action="/community/{{.Name}}/del/" method="post">
<form action="/collective/{{.Name}}/del/" method="post">
<div class="row">
<div class="col">
<label for="user">Elimina cuenta:</label>
@ -48,7 +48,7 @@
</form>
</div>
<div class="row justify-content-center">
<form action="/community/{{.Name}}/description/" method="post">
<form action="/collective/{{.Name}}/description/" method="post">
<div class="row">
<div class="col">
<label for="user">Cambia la descripción:</label>
@ -64,10 +64,10 @@
</div>
<br />
<div class="row justify-content-center">
<form action="/communities/del/" method="post" onsubmit="return confirm('¿de verdad quieres borrar la colectividad {{.Name}}?');">
<input type="hidden" class="form-control" id="community" name="community" value="{{.Name}}">
<form action="/collective/del/" method="post" onsubmit="return confirm('¿de verdad quieres borrar la colectivo {{.Name}}?');">
<input type="hidden" class="form-control" id="collective" name="collective" value="{{.Name}}">
<div class="row">
<button type="submit" class="btn btn-lg btn-block btn-danger">Elimina el colectividad {{.Name}}</button>
<button type="submit" class="btn btn-lg btn-block btn-danger">Elimina el colectivo {{.Name}}</button>
</div>
</form>
</div>

4
tmpl/communities.html → tmpl/collectives.html

@ -4,7 +4,7 @@
<br />
<div class="float-right">
<a class="btn btn-primary" href="/communities/add/">Crea una colectividad</a>
<a class="btn btn-primary" href="/collectives/add/">Crea un colectivo</a>
</div>
<br />
<br />
@ -19,7 +19,7 @@
<tbody>
{{range .Data}}
<tr>
<th scope="row"><a href="/community/{{.Name}}">{{.Name}}</a></th>
<th scope="row"><a href="/collective/{{.Name}}">{{.Name}}</a></th>
<td>{{.Description}}</a></th>
<td>
{{range .Members}}

4
tmpl/index.html

@ -44,8 +44,8 @@
<p>Bienvenida a lowry, nuestro burócrata preferido. ¿qué quieres hacer hoy?</p>
<ul class="list-group">
<li class="list-group-item"><a href="/password/">Cambiar la contraseña</a></li>
<li class="list-group-item"><a href="/communities/mine/">Ver mis colectividades</a></li>
<li class="list-group-item"><a href="/communities/add/">Crear una colectividad</a></li>
<li class="list-group-item"><a href="/collectives/mine/">Ver mis colectivos</a></li>
<li class="list-group-item"><a href="/collecties/add/">Crear un colectivo</a></li>
{{if eq (printf "%v" .Role) "sindominante"}}
<li class="list-group-item"><a href="/adduser/">Invitar amiga a SinDominio</a></li>
{{end}}

6
tmpl/navbar.html

@ -13,8 +13,8 @@
<li class="nav-item {{if eq .Section "password"}}active{{end}}">
<a class="nav-link" href="/password/">Contraseña</a>
</li>
<li class="nav-item {{if eq .Section "community" "communities" "add_community"}}active{{end}}">
<a class="nav-link" href="/communities/mine/">Mis colectividades</a>
<li class="nav-item {{if eq .Section "collective" "collectives" "add_collective"}}active{{end}}">
<a class="nav-link" href="/collectives/mine/">Mis colectivos</a>
</li>
</ul>
<hr />
@ -28,7 +28,7 @@
<a class="nav-link" href="/users/">Cuentas</a>
</li>
<li class="nav-item">
<a class="nav-link" href="/communities/">Colectividades</a>
<a class="nav-link" href="/collectives/">Colectivos</a>
</li>
{{end}}
</ul>

6
tmpl/user.html

@ -14,16 +14,16 @@
<dt>Home</dt><dd>{{.User.Home}}</dd>
<dt>Mail</dt><dd>{{.User.Mail}}</dd>
{{if .Groups}}
<dt>Colectividades</dt><dd>
<dt>Colectivos</dt><dd>
{{range .Groups}}
<a href="/community/{{.Name}}">{{.Name}}</a>,
<a href="/collective/{{.Name}}">{{.Name}}</a>,
{{end}}
</dd>
{{end}}
<dt>Último login</dt><dd>{{.User.LastLogin}}</dd>
<dt>UID</dt><dd>{{.User.UID}}</dd>
{{with .MainGroup}}
<dt>GID</dt><dd><a href="/groups/{{.Name}}">{{.Name}} ({{.GID}})</a></dd>
<dt>GID</dt><dd>{{.Name}} ({{.GID}})</dd>
{{end}}
</dl>
</div>

Loading…
Cancel
Save