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"
2016-04-10 20:03:12 +02:00
"github.com/ansible-semaphore/semaphore/util"
2019-07-09 09:21:49 +02:00
"github.com/ansible-semaphore/semaphore/mulekick"
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"
)
2017-02-22 23:17:36 +01:00
func getUsers ( w http . ResponseWriter , r * http . Request ) {
2017-02-23 06:12:16 +01:00
var users [ ] db . User
if _ , err := db . Mysql . Select ( & users , "select * from user" ) ; err != nil {
2016-04-10 20:03:12 +02:00
panic ( err )
}
2017-02-22 23:21:52 +01:00
mulekick . WriteJSON ( w , http . StatusOK , users )
2016-04-10 20:03:12 +02:00
}
2017-02-22 23:17:36 +01:00
func addUser ( w http . ResponseWriter , r * http . Request ) {
2017-02-23 06:12:16 +01:00
var user db . User
2017-02-22 23:21:52 +01:00
if err := mulekick . Bind ( w , r , & user ) ; err != nil {
2018-04-11 20:05:38 +02:00
w . WriteHeader ( http . StatusBadRequest )
2016-04-10 20:03:12 +02:00
return
}
2017-07-26 07:55:34 +02:00
editor := context . Get ( r , "user" ) . ( * db . User )
2018-03-27 22:12:47 +02:00
if ! editor . Admin {
2018-02-20 01:12:19 +01:00
log . Warn ( editor . Username + " is not permitted to create users" )
2017-07-26 07:55:34 +02:00
w . WriteHeader ( http . StatusUnauthorized )
return
}
2018-04-11 20:05:38 +02:00
user . Created = db . GetParsedTime ( time . Now ( ) )
2016-04-29 09:33:08 +02:00
2017-02-23 06:12:16 +01:00
if err := db . Mysql . Insert ( & user ) ; err != nil {
2016-04-10 20:03:12 +02:00
panic ( err )
}
2017-02-22 23:21:52 +01:00
mulekick . WriteJSON ( w , http . StatusCreated , user )
2016-04-10 20:03:12 +02:00
}
2017-02-22 23:17:36 +01:00
func getUserMiddleware ( w http . ResponseWriter , r * http . Request ) {
2017-02-23 00:21:49 +01:00
userID , err := util . GetIntParam ( "user_id" , w , r )
2016-04-10 20:03:12 +02:00
if err != nil {
return
}
2017-02-23 06:12:16 +01:00
var user db . User
if err := db . Mysql . SelectOne ( & user , "select * from user where id=?" , userID ) ; err != nil {
2016-04-10 20:03:12 +02:00
if err == sql . ErrNoRows {
2017-02-22 23:17:36 +01:00
w . WriteHeader ( http . StatusNotFound )
2016-04-10 20:03:12 +02:00
return
}
panic ( err )
}
2017-07-26 07:55:34 +02:00
editor := context . Get ( r , "user" ) . ( * db . User )
2018-03-27 22:12:47 +02:00
if ! editor . Admin && editor . ID != user . ID {
2018-02-18 23:49:40 +01:00
log . Warn ( editor . Username + " is not permitted to edit users" )
2017-07-26 07:55:34 +02:00
w . WriteHeader ( http . StatusUnauthorized )
return
}
2017-02-22 23:21:52 +01:00
context . Set ( r , "_user" , user )
2016-04-10 20:03:12 +02:00
}
2017-02-22 23:17:36 +01:00
func updateUser ( w http . ResponseWriter , r * http . Request ) {
2017-02-23 06:12:16 +01:00
oldUser := context . Get ( r , "_user" ) . ( db . User )
2017-07-26 07:55:34 +02:00
editor := context . Get ( r , "user" ) . ( * db . User )
2016-04-10 20:03:12 +02:00
2017-04-18 15:58:48 +02:00
var user db . User
if err := mulekick . Bind ( w , r , & user ) ; err != nil {
2016-04-10 20:03:12 +02:00
return
}
2018-03-27 22:12:47 +02:00
if ! editor . Admin && editor . ID != oldUser . ID {
2018-02-20 01:12:19 +01:00
log . Warn ( editor . Username + " is not permitted to edit users" )
2017-07-26 07:55:34 +02:00
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
}
2018-03-27 22:12:47 +02:00
if oldUser . External && oldUser . Username != user . Username {
2017-03-28 03:38:53 +02:00
log . Warn ( "Username is not editable for external LDAP users" )
2017-04-18 15:58:48 +02:00
w . WriteHeader ( http . StatusBadRequest )
2017-07-26 07:55:34 +02:00
return
2017-04-18 15:58:48 +02:00
}
2016-04-10 20:03:12 +02:00
2017-07-26 07:55:34 +02:00
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 {
2016-04-10 20:03:12 +02:00
panic ( err )
}
2017-02-22 23:17:36 +01:00
w . WriteHeader ( http . StatusNoContent )
2016-04-10 20:03:12 +02:00
}
2017-02-22 23:17:36 +01:00
func updateUserPassword ( w http . ResponseWriter , r * http . Request ) {
2017-02-23 06:12:16 +01:00
user := context . Get ( r , "_user" ) . ( db . User )
2017-07-26 07:55:34 +02:00
editor := context . Get ( r , "user" ) . ( * db . User )
2016-04-10 20:03:12 +02:00
var pwd struct {
Pwd string ` json:"password" `
}
2018-03-27 22:12:47 +02:00
if ! editor . Admin && editor . ID != user . ID {
2018-02-20 01:12:19 +01:00
log . Warn ( editor . Username + " is not permitted to edit users" )
2017-07-26 07:55:34 +02:00
w . WriteHeader ( http . StatusUnauthorized )
return
}
2018-03-27 22:12:47 +02:00
if user . External {
2017-03-28 03:38:53 +02:00
log . Warn ( "Password is not editable for external LDAP users" )
2017-04-18 15:58:48 +02:00
w . WriteHeader ( http . StatusBadRequest )
2017-03-28 03:38:53 +02:00
return
}
2017-02-22 23:21:52 +01:00
if err := mulekick . Bind ( w , r , & pwd ) ; err != nil {
2016-04-10 20:03:12 +02:00
return
}
2018-03-27 22:12:47 +02:00
password , err := bcrypt . GenerateFromPassword ( [ ] byte ( pwd . Pwd ) , 11 )
util . LogWarning ( err )
2017-02-23 06:12:16 +01:00
if _ , err := db . Mysql . Exec ( "update user set password=? where id=?" , string ( password ) , user . ID ) ; err != nil {
2016-05-23 21:29:38 +02:00
panic ( err )
}
2017-02-22 23:17:36 +01:00
w . WriteHeader ( http . StatusNoContent )
2016-05-23 21:29:38 +02:00
}
2017-02-22 23:17:36 +01:00
func deleteUser ( w http . ResponseWriter , r * http . Request ) {
2017-02-23 06:12:16 +01:00
user := context . Get ( r , "_user" ) . ( db . User )
2017-07-26 07:55:34 +02:00
editor := context . Get ( r , "user" ) . ( * db . User )
2018-03-27 22:12:47 +02:00
if ! editor . Admin && editor . ID != user . ID {
2018-02-20 01:12:19 +01:00
log . Warn ( editor . Username + " is not permitted to delete users" )
2017-07-26 07:55:34 +02:00
w . WriteHeader ( http . StatusUnauthorized )
return
}
2016-05-23 21:29:38 +02:00
2017-02-23 06:12:16 +01:00
if _ , err := db . Mysql . Exec ( "delete from project__user where user_id=?" , user . ID ) ; err != nil {
2016-05-23 21:29:38 +02:00
panic ( err )
}
2017-02-23 06:12:16 +01:00
if _ , err := db . Mysql . Exec ( "delete from user where id=?" , user . ID ) ; err != nil {
2016-04-10 20:03:12 +02:00
panic ( err )
}
2017-02-22 23:17:36 +01:00
w . WriteHeader ( http . StatusNoContent )
2016-04-10 20:03:12 +02:00
}