2016-05-24 11:55:48 +02:00
package api
2016-04-10 20:03:12 +02:00
import (
"database/sql"
2017-02-22 23:21:52 +01:00
"net/http"
2016-04-29 09:33:08 +02:00
"time"
2016-04-10 20:03:12 +02:00
2017-03-28 03:38:53 +02:00
log "github.com/Sirupsen/logrus"
2017-02-23 06:12:16 +01:00
"github.com/ansible-semaphore/semaphore/db"
2019-07-09 19:45:27 +02:00
2019-07-09 18:14:06 +02:00
"github.com/ansible-semaphore/semaphore/util"
2017-02-22 23:21:52 +01:00
"github.com/gorilla/context"
2016-04-10 20:03:12 +02:00
"golang.org/x/crypto/bcrypt"
)
2019-07-09 18:11:01 +02:00
func getUsers ( w http . ResponseWriter , r * http . Request ) {
var users [ ] db . User
if _ , err := db . Mysql . Select ( & users , "select * from user" ) ; err != nil {
panic ( err )
}
2016-04-29 09:33:08 +02:00
2019-07-09 19:45:27 +02:00
util . WriteJSON ( w , http . StatusOK , users )
2019-07-09 14:56:03 +02:00
}
2016-04-10 20:03:12 +02:00
2019-07-09 18:11:01 +02:00
func addUser ( w http . ResponseWriter , r * http . Request ) {
var user db . User
2019-07-09 19:45:27 +02:00
if err := util . Bind ( w , r , & user ) ; err != nil {
2019-07-09 18:11:01 +02:00
w . WriteHeader ( http . StatusBadRequest )
return
}
2016-04-10 20:03:12 +02:00
2019-07-09 18:11:01 +02:00
editor := context . Get ( r , "user" ) . ( * db . User )
if ! editor . Admin {
log . Warn ( editor . Username + " is not permitted to create users" )
w . WriteHeader ( http . StatusUnauthorized )
return
}
2019-07-09 14:56:03 +02:00
2019-07-09 18:11:01 +02:00
user . Created = db . GetParsedTime ( time . Now ( ) )
2019-07-09 14:56:03 +02:00
2019-07-09 18:11:01 +02:00
if err := db . Mysql . Insert ( & user ) ; err != nil {
panic ( err )
}
2017-07-26 07:55:34 +02:00
2019-07-09 19:45:27 +02:00
util . WriteJSON ( w , http . StatusCreated , user )
2016-04-10 20:03:12 +02:00
}
2019-07-09 18:14:06 +02:00
func getUserMiddleware ( next http . Handler ) http . Handler {
return http . HandlerFunc ( func ( w http . ResponseWriter , r * http . Request ) {
userID , err := util . GetIntParam ( "user_id" , w , r )
if err != nil {
2019-07-09 14:56:03 +02:00
return
}
2019-07-09 18:14:06 +02:00
var user db . User
if err := db . Mysql . SelectOne ( & user , "select * from user where id=?" , userID ) ; err != nil {
if err == sql . ErrNoRows {
w . WriteHeader ( http . StatusNotFound )
return
}
2019-07-09 14:56:03 +02:00
2019-07-09 18:14:06 +02:00
panic ( err )
}
editor := context . Get ( r , "user" ) . ( * db . User )
if ! editor . Admin && editor . ID != user . ID {
log . Warn ( editor . Username + " is not permitted to edit users" )
w . WriteHeader ( http . StatusUnauthorized )
return
}
2019-07-09 14:56:03 +02:00
2019-07-09 18:14:06 +02:00
context . Set ( r , "_user" , user )
next . ServeHTTP ( w , r )
} )
2016-04-10 20:03:12 +02:00
}
2019-07-09 18:11:01 +02:00
func updateUser ( w http . ResponseWriter , r * http . Request ) {
oldUser := context . Get ( r , "_user" ) . ( db . User )
editor := context . Get ( r , "user" ) . ( * db . User )
var user db . User
2019-07-09 19:45:27 +02:00
if err := util . Bind ( w , r , & user ) ; err != nil {
2019-07-09 18:11:01 +02:00
return
}
if ! editor . Admin && editor . ID != oldUser . ID {
log . Warn ( editor . Username + " is not permitted to edit users" )
w . WriteHeader ( http . StatusUnauthorized )
return
}
if editor . ID == oldUser . ID && oldUser . Admin != user . Admin {
log . Warn ( "User can't edit his own role" )
w . WriteHeader ( http . StatusUnauthorized )
return
}
if oldUser . External && oldUser . Username != user . Username {
log . Warn ( "Username is not editable for external LDAP users" )
w . WriteHeader ( http . StatusBadRequest )
return
}
if _ , err := db . Mysql . Exec ( "update user set name=?, username=?, email=?, alert=?, admin=? where id=?" , user . Name , user . Username , user . Email , user . Alert , user . Admin , oldUser . ID ) ; err != nil {
2020-10-02 22:10:41 +02:00
log . Error ( err . Error ( ) )
w . WriteHeader ( http . StatusBadRequest )
return
2019-07-09 18:11:01 +02:00
}
w . WriteHeader ( http . StatusNoContent )
2016-05-23 21:29:38 +02:00
}
2019-07-09 18:11:01 +02:00
func updateUserPassword ( w http . ResponseWriter , r * http . Request ) {
user := context . Get ( r , "_user" ) . ( db . User )
editor := context . Get ( r , "user" ) . ( * db . User )
var pwd struct {
Pwd string ` json:"password" `
}
if ! editor . Admin && editor . ID != user . ID {
log . Warn ( editor . Username + " is not permitted to edit users" )
w . WriteHeader ( http . StatusUnauthorized )
return
}
if user . External {
log . Warn ( "Password is not editable for external LDAP users" )
w . WriteHeader ( http . StatusBadRequest )
return
}
2019-07-09 19:45:27 +02:00
if err := util . Bind ( w , r , & pwd ) ; err != nil {
2019-07-09 18:11:01 +02:00
return
}
password , err := bcrypt . GenerateFromPassword ( [ ] byte ( pwd . Pwd ) , 11 )
util . LogWarning ( err )
if _ , err := db . Mysql . Exec ( "update user set password=? where id=?" , string ( password ) , user . ID ) ; err != nil {
panic ( err )
}
w . WriteHeader ( http . StatusNoContent )
}
2019-07-09 14:56:03 +02:00
2019-07-09 18:11:01 +02:00
func deleteUser ( w http . ResponseWriter , r * http . Request ) {
user := context . Get ( r , "_user" ) . ( db . User )
editor := context . Get ( r , "user" ) . ( * db . User )
2017-07-26 07:55:34 +02:00
2019-07-09 18:11:01 +02:00
if ! editor . Admin && editor . ID != user . ID {
log . Warn ( editor . Username + " is not permitted to delete users" )
w . WriteHeader ( http . StatusUnauthorized )
return
}
2016-05-23 21:29:38 +02:00
2019-07-09 18:11:01 +02:00
if _ , err := db . Mysql . Exec ( "delete from project__user where user_id=?" , user . ID ) ; err != nil {
panic ( err )
}
if _ , err := db . Mysql . Exec ( "delete from user where id=?" , user . ID ) ; err != nil {
panic ( err )
}
2016-04-10 20:03:12 +02:00
2019-07-09 18:11:01 +02:00
w . WriteHeader ( http . StatusNoContent )
2016-04-10 20:03:12 +02:00
}