Ask from a list if they want to be sindinante

merge-requests/4/head
meskio 4 years ago
parent 56866c5c85
commit 6e1fafaf97
Signed by: meskio
GPG Key ID: 52B8F5AC97A2DA86
  1. 17
      ldap/user.go
  2. 41
      main.go
  3. 11
      server/server.go
  4. 6
      server/template.go
  5. 40
      server/user.go
  6. 33
      tmpl/index.html
  7. 2
      tmpl/navbar.html
  8. 2
      tmpl/password.html

@ -86,6 +86,23 @@ func (l Ldap) changePass(conn *ldap.Conn, user, oldpass, newpass string) error {
return err
}
// GetUserRole returns the role of the user
func (l Ldap) GetUserRole(user string) Role {
conn, err := l.connect()
if err != nil {
log.Printf("Error connecting to ldap: %v", err)
return Undefined
}
defer conn.Close()
entry, err := l.searchUser(user, conn)
if err != nil {
log.Printf("Error searching for user in ldap: %v", err)
return Undefined
}
return RoleFromString(entry.GetAttributeValue("sdRole"))
}
//GetUser returns the user data
func (l Ldap) GetUser(name string) (User, error) {
conn, err := l.connect()

@ -1,7 +1,11 @@
package main
import (
"bufio"
"log"
"os"
"sort"
"strings"
"0xacab.org/sindominio/lowry/ldap"
"0xacab.org/sindominio/lowry/server"
@ -10,12 +14,13 @@ import (
func main() {
var (
ldapaddr = flag.String("ldapaddr", "localhost:389", "LDAP server address and port")
domain = flag.String("domain", "", "LDAP domain components")
ldappass = flag.String("ldappass", "", "Password of the LDAP `admin' user")
homepath = flag.String("homepath", "/home/", "Path to the user homes")
httpaddr = flag.String("httpaddr", ":8080", "Web server address and port")
ro = flag.Bool("ro", false, "Read-Only mode")
ldapaddr = flag.String("ldapaddr", "localhost:389", "LDAP server address and port")
domain = flag.String("domain", "", "LDAP domain components")
ldappass = flag.String("ldappass", "", "Password of the LDAP `admin' user")
homepath = flag.String("homepath", "/home/", "Path to the user homes")
httpaddr = flag.String("httpaddr", ":8080", "Web server address and port")
ro = flag.Bool("ro", false, "Read-Only mode")
askRolePath = flag.String("ask-role-list", "", "List of usernames to ask if want to be sindominantes")
)
flag.String(flag.DefaultConfigFlagname, "/etc/lowry.conf", "Path to configuration file")
flag.Parse()
@ -32,5 +37,27 @@ func main() {
log.Fatal(err)
}
log.Fatal(server.Serve(*httpaddr, &l))
usersAskRole := []string{}
if *askRolePath != "" {
usersAskRole = readUserList(*askRolePath)
}
log.Fatal(server.Serve(*httpaddr, &l, usersAskRole))
}
func readUserList(listPath string) []string {
f, err := os.Open(listPath)
if err != nil {
log.Fatal(err)
}
defer f.Close()
list := []string{}
scanner := bufio.NewScanner(f)
for scanner.Scan() {
user := strings.TrimSpace(scanner.Text())
list = append(list, user)
}
sort.Strings(list)
return list
}

@ -9,17 +9,19 @@ import (
)
type server struct {
ldap *ldap.Ldap
sess *sessionStore
tmpl *template.Template
ldap *ldap.Ldap
sess *sessionStore
tmpl *template.Template
usersAskRole []string
}
// Serve lowry web site
func Serve(addr string, l *ldap.Ldap) error {
func Serve(addr string, l *ldap.Ldap, usersAskRole []string) error {
var s server
s.ldap = l
s.sess = initSessionStore()
s.tmpl = initTemplate()
s.usersAskRole = usersAskRole
r := mux.NewRouter()
var notFoundFunc http.HandlerFunc
@ -39,6 +41,7 @@ func Serve(addr string, l *ldap.Ldap) error {
r.HandleFunc("/groups/{name}", s.groupHandler)
r.HandleFunc("/groups/{name}/add/", s.addUserGroupHandler).Methods("POST")
r.HandleFunc("/groups/{name}/del/", s.delUserGroupHandler).Methods("POST")
r.HandleFunc("/ask-sindominante/", s.askSindominante).Methods("POST")
r.HandleFunc("/bundle.js", func(w http.ResponseWriter, r *http.Request) { http.ServeFile(w, r, "dist/bundle.js") })
r.HandleFunc("/style.css", func(w http.ResponseWriter, r *http.Request) { http.ServeFile(w, r, "dist/style.css") })

@ -4,11 +4,14 @@ import (
"html/template"
"log"
"net/http"
"0xacab.org/sindominio/lowry/ldap"
)
type responseT struct {
User string
IsAdmin bool
Role ldap.Role
Section string
Data interface{}
w http.ResponseWriter
@ -38,14 +41,17 @@ func initTemplate() *template.Template {
func (s *server) newResponse(template string, w http.ResponseWriter, r *http.Request) responseT {
session := s.sess.get(w, r)
user := ""
role := ldap.Undefined
admin := false
if session != nil {
user = session.user
admin = s.isAdmin(user)
role = s.ldap.GetUserRole(user)
}
return responseT{
User: user,
IsAdmin: admin,
Role: role,
Section: template,
Data: nil,
w: w,

@ -1,15 +1,29 @@
package server
import (
"log"
"net/http"
"sort"
"0xacab.org/sindominio/lowry/ldap"
)
func (s *server) homeHandler(w http.ResponseWriter, r *http.Request) {
response := s.newResponse("index", w, r)
if response.User == "" {
response = s.newResponse("login", w, r)
response.execute(false)
return
}
response.execute(false)
askSindominante := (response.Role != ldap.Sindominante &&
s.userInAskList(response.User))
needPasswordChange := !s.ldap.IsUserPassUptodate(response.User)
data := struct {
AskSindominante bool
NeedPasswordChange bool
}{askSindominante, needPasswordChange}
response.execute(data)
}
func (s *server) loginHandler(w http.ResponseWriter, r *http.Request) {
@ -60,3 +74,27 @@ func (s *server) passwordHandler(w http.ResponseWriter, r *http.Request) {
response.execute("PassChanged")
}
}
func (s *server) askSindominante(w http.ResponseWriter, r *http.Request) {
role := r.FormValue("role")
response := s.newResponse("", w, r)
if !s.userInAskList(response.User) {
log.Printf("An attempt to set role without being in the list: %s - %s", response.User, role)
s.forbiddenHandler(w, r)
return
}
err := s.ldap.ChangeRole(response.User, ldap.RoleFromString(role))
if err != nil {
log.Printf("An error has ocurred setting the role: %v", err)
} else {
idx := sort.SearchStrings(s.usersAskRole, response.User)
s.usersAskRole = append(s.usersAskRole[:idx], s.usersAskRole[idx+1:]...)
}
http.Redirect(w, r, "/", http.StatusFound)
}
func (s *server) userInAskList(user string) bool {
return sort.SearchStrings(s.usersAskRole, user) != len(s.usersAskRole)
}

@ -2,16 +2,37 @@
{{template "navbar.html" .}}
<div class="container">
{{if .Data.AskSindominante}}
<br />
<div class="row justify-content-center">
<h1 class="col-4">Hola {{.User}}!!</h1>
<div class="row col-md">
<p>Como habras visto sindominio esta en <a href="https://trastienda.sindominio.net/Grandes_Planes">proceso de cambios</a>. ¿Cual va a ser tu pertenencia en sindominio?</p>
<form action="/ask-sindominante/" method="post">
<div class="form-check">
<label class="form-check-label">
<input class="form-check-input" type="radio" name="role" id="sindominante" value="sindominante" checked>
<dt>Sindominante</dt><dd>Seguir formando parte de las decisiones del día a día en la asamblea, manteniendo sindominio funcionando y tener acceso a todos los servicios de sindominio.</dd>
</label>
</div>
<div class="form-check">
<label class="form-check-label">
<input class="form-check-input" type="radio" name="role" id="amiga" value="amiga">
<dt>Amiga</dt><dd>Pasando a ser una cuenta reducida de sindominio sin acceso a la toma de decisiones del proyecto.</dd>
</label>
</div>
<div class="col">
<button type="submit" class="btn btn-primary">Enviar</button>
</div>
</form>
</div>
{{if .IsAdmin}}
{{else}}
<br />
<div class="row justify-content-center">
<p>Parece que eres una admin.<br />
<br />
<em>Un gran poder conlleva una gran responsabilidad</em></p>
<ul class="col-md-4 list-group">
<li class="list-group-item"><a href="/password/">Cambiar la contraseña</a></li>
</ul>
</div>
{{end}}
</div>

@ -8,7 +8,7 @@
<div class="collapse navbar-collapse" id="navbarSupportedContent">
<ul class="navbar-nav mr-auto">
<li class="nav-item">
<a class="nav-link" href="/users/{{.User}}">{{.User}}</a>
<a class="nav-link" href="/">{{.User}} ({{.Role}})</a>
</li>
<li class="nav-item {{if eq .Section "password"}}active{{end}}">
<a class="nav-link" href="/password/">Contraseña</a>

@ -11,7 +11,7 @@
<br />
<div class="row justify-content-center">
<form class="col-4" id="needs-validation" action="/password/" method="post" novalidate>
<form class="col-sm-4" id="needs-validation" action="/password/" method="post" novalidate>
<div class="form-group">
<label for="oldpass">Contraseña actual:</label>
<input type="password" class="form-control {{if eq .Data "WrongOldpass"}}is-invalid{{end}}" id="oldpass" name="oldpass" placeholder="Contraseña">

Loading…
Cancel
Save