sum7/warehost
sum7
/
warehost
Archived
1
0
Fork 0

improve invite (with all function)

This commit is contained in:
Martin Geno 2016-08-24 23:02:25 +02:00
parent cd8bff38ab
commit 1cf3dfd47a
5 changed files with 144 additions and 52 deletions

View File

@ -2,13 +2,14 @@ package libPassword
import "fmt"
func main(){
func main() {
password_str := "root"
x,err :=Validate("pbkdf2_sha1$10000$a5viM+Paz3o=$orD4shu1Ss+1wPAhAt8hkZ/fH7Y=",password_str); if x {
x, err := Validate("pbkdf2_sha1$10000$a5viM+Paz3o=$orD4shu1Ss+1wPAhAt8hkZ/fH7Y=", password_str)
if x {
fmt.Println("Valide")
if err {
fmt.Print("Deprecated,replace with: ")
fmt.Println(NewHesh(password_str))
fmt.Println(NewHash(password_str))
}
}
}

View File

@ -13,31 +13,32 @@ import "strings"
const (
salt_length = 8
hesh_length = 20
hash_length = 20
interations = 10000
hashfunc string = "sha256"
)
var hashlib = map[string] func()hash.Hash{
"sha1":sha1.New,
"sha256":sha256.New,
"sha512":sha512.New,
}
func Validate(hash,password string)(output,replace bool){
parts := strings.Split(hash,"$")
var hashlib = map[string]func() hash.Hash{
"sha1": sha1.New,
"sha256": sha256.New,
"sha512": sha512.New,
}
func Validate(hash, password string) (output, replace bool) {
parts := strings.Split(hash, "$")
if len(parts) == 3 {
return false,false
return false, false
}
cur_iter,err := strconv.Atoi(parts[1])
cur_iter, err := strconv.Atoi(parts[1])
if err != nil {
return false,false
return false, false
}
hashfunc_c := strings.Split(parts[0],"_")[1]
replace = (hashfunc_c!=hashfunc)
hashfunc_c := strings.Split(parts[0], "_")[1]
replace = (hashfunc_c != hashfunc)
dk := pbkdf2.Key([]byte(password), []byte(parts[2]), cur_iter, len(parts[3])-8, hashlib[hashfunc_c])
x := fmt.Sprintf("pbkdf2_%s$%s$%s$%s",hashfunc_c,parts[1],parts[2],base64.StdEncoding.EncodeToString(dk))
output = (x==hash)
x := fmt.Sprintf("pbkdf2_%s$%s$%s$%s", hashfunc_c, parts[1], parts[2], base64.StdEncoding.EncodeToString(dk))
output = (x == hash)
return
}
func GenerateRandomString(n int) (string, error) {
@ -48,8 +49,8 @@ func GenerateRandomString(n int) (string, error) {
}
return base64.URLEncoding.EncodeToString(b), nil
}
func NewHesh(password string)string{
salt,_ := GenerateRandomString(salt_length)
dk := pbkdf2.Key([]byte(password), []byte(salt), interations, hesh_length, hashlib[hashfunc])
return fmt.Sprintf("pbkdf2_%s$%d$%s$%s",hashfunc,interations,salt,base64.StdEncoding.EncodeToString(dk))
func NewHash(password string) string {
salt, _ := GenerateRandomString(salt_length)
dk := pbkdf2.Key([]byte(password), []byte(salt), interations, hash_length, hashlib[hashfunc])
return fmt.Sprintf("pbkdf2_%s$%d$%s$%s", hashfunc, interations, salt, base64.StdEncoding.EncodeToString(dk))
}

View File

@ -62,6 +62,7 @@ func main() {
c := cors.New(cors.Options{
AllowedOrigins: []string{config.API.AllowedOrigins},
AllowCredentials: true,
AllowedMethods: []string{"GET", "POST", "PUT", "DELETE"},
})
handler := c.Handler(router)
// Start server

View File

@ -3,7 +3,9 @@ package system
import (
"encoding/json"
"net/http"
"strconv"
"strings"
"time"
"github.com/astaxie/session"
"github.com/jinzhu/gorm"
@ -41,8 +43,10 @@ func NewAPI(config *libconfig.Config, sessions *session.Manager, dbconnection *g
router.GET(prefix+"/delete", LoginHandler(api.Delete, sessions))
router.GET(prefix+"/invite", LoginHandler(api.InviteList, sessions))
router.POST(prefix+"/invite", LoginHandler(api.InviteAdd, sessions))
router.PUT(prefix+"/invite", LoginHandler(api.InviteEdit, sessions))
router.DELETE(prefix+"/invite", LoginHandler(api.InviteDelete, sessions))
router.PUT(prefix+"/invite/:id", LoginHandler(api.LoginEdit, sessions))
router.DELETE(prefix+"/invite/:id", LoginHandler(api.LoginDelete, sessions))
router.GET(prefix+"/invitor", LoginHandler(api.Invitor, sessions))
router.PUT(prefix+"/invitor", LoginHandler(api.InvitorAdminToggle, sessions))
}
// Status to get Login and Server status
@ -74,6 +78,7 @@ func (api *API) Logout(w http.ResponseWriter, r *http.Request, _ httprouter.Para
// Login of system
func (api *API) Login(w http.ResponseWriter, r *http.Request, _ httprouter.Params, sess session.Session) (returndata interface{}, returnerr *libapi.ErrorResult) {
returndata = false
logger := api.log.GetLog(r, "login")
var requestlogin RequestLogin
err := json.NewDecoder(r.Body).Decode(&requestlogin)
@ -83,7 +88,6 @@ func (api *API) Login(w http.ResponseWriter, r *http.Request, _ httprouter.Param
returnerr = &libapi.ErrorResult{
Message: "Internal Request Error",
}
returndata = false
return
}
logger = logger.WithField("user", requestlogin.Username)
@ -92,14 +96,14 @@ func (api *API) Login(w http.ResponseWriter, r *http.Request, _ httprouter.Param
if login.ID <= 0 {
logger.Warn("user not found")
returnerr = &libapi.ErrorResult{Fields: []string{"username"}, Message: "User not Found"}
returndata = false
return
}
returndata = false
if login.Active {
output, _ := libpassword.Validate(login.Password, requestlogin.Password)
if output {
returndata = true
login.LastLoginAt = time.Now()
api.dbconnection.Save(&login)
sess.Set("login", login)
logger.Info("logged in")
} else {
@ -116,8 +120,8 @@ func (api *API) Login(w http.ResponseWriter, r *http.Request, _ httprouter.Param
//Password to change the password
func (api *API) Password(w http.ResponseWriter, r *http.Request, _ httprouter.Params, sess session.Session, login *Login) (returndata interface{}, returnerr *libapi.ErrorResult) {
logger := api.log.GetLog(r, "password")
returndata = false
logger := api.log.GetLog(r, "password")
var changePasswordRequest ChangePasswordRequest
err := json.NewDecoder(r.Body).Decode(&changePasswordRequest)
@ -139,28 +143,27 @@ func (api *API) Password(w http.ResponseWriter, r *http.Request, _ httprouter.Pa
returnerr = &libapi.ErrorResult{Fields: []string{"newpassword"}, Message: "Wrong NewPassword"}
return
}
login.Password = libpassword.NewHesh(changePasswordRequest.NewPassword)
login.Password = libpassword.NewHash(changePasswordRequest.NewPassword)
if err := api.dbconnection.Save(login).Error; err != nil {
logger.Warn("error save new password to database")
returnerr = &libapi.ErrorResult{Message: "Error save new password"}
returndata = false
return
}
sess.Set("login", *login)
returndata = true
logger.Info("works")
returndata = true
return
}
//Delete of login on warehost
func (api *API) Delete(w http.ResponseWriter, r *http.Request, _ httprouter.Params, sess session.Session, login *Login) (returndata interface{}, returnerr *libapi.ErrorResult) {
returndata = false
logger := api.log.GetLog(r, "delete")
logger.Warn("login delete")
sess.Delete("login")
if err := api.dbconnection.Unscoped().Delete(login).Error; err != nil {
logger.Warn("error detete login")
returnerr = &libapi.ErrorResult{Message: "Error delete login"}
returndata = false
return
}
returndata = true
@ -169,12 +172,12 @@ func (api *API) Delete(w http.ResponseWriter, r *http.Request, _ httprouter.Para
// InviteList list all of your invites
func (api *API) InviteList(w http.ResponseWriter, r *http.Request, _ httprouter.Params, sess session.Session, login *Login) (returndata interface{}, returnerr *libapi.ErrorResult) {
returndata = false
logger := api.log.GetLog(r, "invitelist")
logger.Info("list invites")
if err := api.dbconnection.Model(login).Preload("Invites.Invited").First(login).Error; err != nil {
logger.Warn("error load own invites")
returnerr = &libapi.ErrorResult{Message: "Could not load invites!"}
returndata = false
return
}
returndata = login.Invites
@ -183,8 +186,8 @@ func (api *API) InviteList(w http.ResponseWriter, r *http.Request, _ httprouter.
// InviteAdd invite a new user to warehost
func (api *API) InviteAdd(w http.ResponseWriter, r *http.Request, _ httprouter.Params, sess session.Session, login *Login) (returndata interface{}, returnerr *libapi.ErrorResult) {
logger := api.log.GetLog(r, "inviteadd")
returndata = false
logger := api.log.GetLog(r, "inviteadd")
var newLogin RequestLogin
err := json.NewDecoder(r.Body).Decode(&newLogin)
if err != nil {
@ -197,14 +200,13 @@ func (api *API) InviteAdd(w http.ResponseWriter, r *http.Request, _ httprouter.P
Login: *login,
Invited: Login{
Username: strings.ToLower(newLogin.Username),
Password: libpassword.NewHesh(newLogin.Password),
Password: libpassword.NewHash(newLogin.Password),
Active: true,
},
}
if err := api.dbconnection.Create(invite).Error; err != nil {
logger.Warn("error create invite")
returnerr = &libapi.ErrorResult{Message: "Username exists already"}
returndata = false
return
}
logger.Info("invite")
@ -212,18 +214,99 @@ func (api *API) InviteAdd(w http.ResponseWriter, r *http.Request, _ httprouter.P
return
}
// InviteEdit edit a invite
func (api *API) InviteEdit(w http.ResponseWriter, r *http.Request, _ httprouter.Params, sess session.Session, login *Login) (returndata interface{}, returnerr *libapi.ErrorResult) {
logger := api.log.GetLog(r, "inviteedit")
logger.Warn("not implemented")
// LoginEdit edit a login by invite or superadmin
func (api *API) LoginEdit(w http.ResponseWriter, r *http.Request, ps httprouter.Params, sess session.Session, login *Login) (returndata interface{}, returnerr *libapi.ErrorResult) {
returndata = false
logger := api.log.GetLog(r, "loginedit")
tmpID64, err := strconv.ParseUint(ps.ByName("id"), 10, 32)
id := uint(tmpID64)
if err != nil {
returnerr = &libapi.ErrorResult{Message: "Error invalid input"}
logger.Warn("invalid userinput, no integer")
return
}
logger = logger.WithField("id", id)
var invitedLogin = Login{ID: id}
var changeLogin RequestLogin
err = json.NewDecoder(r.Body).Decode(&changeLogin)
if err != nil {
logger.Error("fetch request")
http.Error(w, err.Error(), http.StatusInternalServerError)
returnerr = &libapi.ErrorResult{Message: "Internal Request Error"}
return
}
api.dbconnection.Where("id = ?", invitedLogin.ID).First(&invitedLogin)
invite := login.GetInvitedby(api.dbconnection)
if !login.Superadmin && !invite.Admin && invitedLogin.CreateAt.Before(invitedLogin.LastLoginAt) {
logger.Warn("no permission")
returnerr = &libapi.ErrorResult{Message: "Error no permission to edit this invite"}
return
}
if len(changeLogin.Password) > 0 {
invitedLogin.Password = libpassword.NewHash(changeLogin.Password)
}
if login.Superadmin {
invitedLogin.Username = changeLogin.Username
}
if err := api.dbconnection.Save(invitedLogin).Error; err != nil {
logger.Warn("sql edit login")
returnerr = &libapi.ErrorResult{Message: "Error during edit login"}
return
}
logger.Info("login edit")
returndata = true
return
}
// InviteDelete delete a invite
func (api *API) InviteDelete(w http.ResponseWriter, r *http.Request, _ httprouter.Params, sess session.Session, login *Login) (returndata interface{}, returnerr *libapi.ErrorResult) {
logger := api.log.GetLog(r, "invitedelete")
logger.Warn("not implemented")
// LoginDelete delete a login by invite or superadmin
func (api *API) LoginDelete(w http.ResponseWriter, r *http.Request, ps httprouter.Params, sess session.Session, login *Login) (returndata interface{}, returnerr *libapi.ErrorResult) {
returndata = false
logger := api.log.GetLog(r, "logindelete")
tmpID64, err := strconv.ParseUint(ps.ByName("id"), 10, 32)
id := uint(tmpID64)
if err != nil {
returnerr = &libapi.ErrorResult{Message: "Error invalid input"}
logger.Warn("invalid userinput, no integer")
return
}
logger = logger.WithField("id", id)
var invitedLogin = Login{ID: id}
api.dbconnection.Where("id = ?", invitedLogin.ID).First(&invitedLogin)
invite := login.GetInvitedby(api.dbconnection)
if !login.Superadmin && !invite.Admin && invitedLogin.CreateAt.Before(invitedLogin.LastLoginAt) {
logger.Warn("no permission")
returnerr = &libapi.ErrorResult{Message: "Error no permission to delete this invite"}
return
}
if err := api.dbconnection.Unscoped().Delete(invitedLogin).Error; err != nil {
logger.Warn("sql detete login")
returnerr = &libapi.ErrorResult{Message: "Error during delete login"}
return
}
logger.Info("login deleted")
returndata = true
return
}
// Invitor get Invite of current login
func (api *API) Invitor(w http.ResponseWriter, r *http.Request, ps httprouter.Params, sess session.Session, login *Login) (returndata interface{}, returnerr *libapi.ErrorResult) {
returndata = false
logger := api.log.GetLog(r, "invitor")
invite := login.GetInvitedby(api.dbconnection)
logger.Info("show invitor")
returndata = invite
return
}
// InvitorAdmin toggle admin of current login
func (api *API) InvitorAdminToggle(w http.ResponseWriter, r *http.Request, ps httprouter.Params, sess session.Session, login *Login) (returndata interface{}, returnerr *libapi.ErrorResult) {
returndata = false
logger := api.log.GetLog(r, "invitoradmintoggle")
invite := login.GetInvitedby(api.dbconnection)
invite.Admin = !invite.Admin
api.dbconnection.Model(invite).Save(&invite)
logger.Info("toggle saved")
returndata = true
return
}

View File

@ -42,18 +42,24 @@ type Login struct {
Superadmin bool `gorm:"default:'false';column:superadmin" json:"superadmin"`
CreateAt time.Time `sql:"default:current_timestamp" gorm:"column:createat" json:"createat"`
LastLoginAt time.Time `gorm:"column:lastloginat" json:"lastloginat"`
Invites []Invite `gorm:"foreignkey:Login"`
Invites []Invite `gorm:"foreignkey:Login" json:"invites"`
}
// Login found
type Invite struct {
LoginID uint `sql:"type:bigint REFERENCES login(id) ON UPDATE CASCADE ON DELETE CASCADE;column:login"`
LoginID uint `sql:"type:bigint REFERENCES login(id) ON UPDATE CASCADE ON DELETE CASCADE;column:login;primary_key"`
Login Login `gorm:"column:login" json:"login"`
InvitedID uint `sql:"type:bigint REFERENCES login(id) ON UPDATE CASCADE ON DELETE CASCADE;column:invited"`
InvitedID uint `sql:"type:bigint REFERENCES login(id) ON UPDATE CASCADE ON DELETE CASCADE;column:invited;primary_key"`
Invited Login `gorm:"column:invited" json:"invited"`
Admin bool `sql:"default:'false'" json:"admin"`
}
func (l *Login) GetInvitedby(dbconnection *gorm.DB) (invited Invite) {
invited = Invite{InvitedID: l.ID}
dbconnection.Where("invited = ?", invited.InvitedID).First(&invited)
return
}
// SyncModels to verify the database schema
func SyncModels(dbconnection *gorm.DB) {
dbconnection.AutoMigrate(&Login{}, &Invite{})
@ -65,12 +71,12 @@ func SyncModels(dbconnection *gorm.DB) {
Username: "root",
Active: true,
Superadmin: true,
Password: libpassword.NewHesh("root"),
Password: libpassword.NewHash("root"),
}
dbconnection.Create(login)
log.Log.Error("have to create \"login\"")
} else {
log.Log.Info("Conection to \"login\" works")
log.Log.Info("Connection to \"login\" works")
}
}