Browse Source

prototyped auth pipeline with dummy auth

master
Stefan Naumann 2 weeks ago
parent
commit
27b22c1793
  1. 8
      auth/base.go
  2. 41
      auth/dummy.go
  3. 2
      core/config.go
  4. 7
      main.go
  5. 13
      views/login_dummy.html
  6. 2
      web/auth.go
  7. 21
      web/index.go

8
auth/base.go

@ -276,14 +276,17 @@ func EnsureEnabled ( db *gorm.DB, u core.User, name string, module string, extra
// fin -> finished, login successful
// fail -> failed auth, probably wrong configuration
func FollowUp ( user core.User, step string ) string {
core.Console.Log ( "FollowUp", user.AuthExtra, step )
extra := authDecode ( user );
if extra.Enable == false {
return "fin";
}
core.Console.Log ("extra", extra)
order := strings.Split ( extra.Order, "," )
core.Console.Log ("order", order)
if len(order) >= 0 {
if step == "main" {
if step == "main" || step == "native" || step == "" {
return order[0]
}
for k, o := range order {
@ -302,6 +305,7 @@ func FollowUp ( user core.User, step string ) string {
// API for the login-handler
// verify against extra steps, outlined in user.AuthExtra
func VerifyExtra ( db *gorm.DB, user core.User, step string, stepExtra string, given string, e string ) error {
core.Console.Log ( "VerifyExtra ", user.Name, step, stepExtra, given, e )
extra := authDecode ( user );
if extra.Enable == false {
return errors.New("Invalid auth operation");
@ -322,6 +326,7 @@ func VerifyExtra ( db *gorm.DB, user core.User, step string, stepExtra string, g
err := AuthVerify ( &user, step, stepExtra, given, e )
if err == nil {
// check the username here to mitigate timing attacks
if len(user.Name) > 1 {
return nil
}
@ -334,6 +339,7 @@ func VerifyExtra ( db *gorm.DB, user core.User, step string, stepExtra string, g
// API for login-handler
// verifies against main auth on the user-object
func VerifyMain ( db *gorm.DB, user core.User, given string, name string ) error {
core.Console.Log ( "VerifyMain ", user.Name, given, name )
authname := user.AuthProvider
authextra := user.AuthProviderExtra

41
auth/dummy.go

@ -0,0 +1,41 @@
package auth
import (
"math/rand"
"errors"
"strconv"
"git.snaums.de/snaums/mvoCI/core"
)
var dummyProvider = Provider {
Name : "dummy",
HumanName : "Built-In Authentification",
Description : "Built-In Authentification based on passwords",
LoginView : "logindummy",
Verify : dummyVerify,
Seed : dummySeed,
Cap : ProviderCap{
Seed: true,
},
}
func init () {
__init ( &dummyProvider )
}
func dummyVerify (user *core.User, stepExtra string, given string, extra string ) error {
core.Console.Log ("dummyVerify", stepExtra, given, extra )
if given == stepExtra {
return nil;
} else {
return errors.New ("Incorrect login");
}
}
func dummySeed () string {
return strconv.FormatInt ( rand.Int63()%10, 10 )
}

2
core/config.go

@ -70,6 +70,7 @@ type Config struct {
LogFileEnable bool
LogMode string
LoginTokenDuration int
LoginTokenInvalidate bool
ParallelBuilds int
CompressionMethod string
RepoSecretShow bool
@ -97,6 +98,7 @@ func ConfigDefault () Config {
HttpPort: 4042,
HttpHost: "localhost",
LoginTokenDuration: 300,
LoginTokenInvalidate: true,
CompressionMethod: "gz",
ParallelBuilds: 2,
LogFile: "log/mvoCI.log",

7
main.go

@ -6,6 +6,7 @@ import (
"os"
"fmt"
"flag"
"time"
"bytes"
"errors"
"strconv"
@ -159,6 +160,12 @@ func main() {
build.SetupWorkerThreads ( &cfg, db );
}
if cfg.LoginTokenInvalidate == true {
db.Where("type = ?", "login").Delete ( &core.LoginToken{} )
} else {
db.Where ( "type = ? AND (step = ? OR expires_at < ?)", "login", "fin", time.Now() ).Delete( &core.LoginToken{} );
}
Console.Log ( "Starting", cfg.AppTitle )
// start eh web server and hand everything over to it

13
views/login_dummy.html

@ -0,0 +1,13 @@
{{ define "content" }}
<div class="login-form">
<span class="login-header">Dummy Login Module</span>
<form method="post">
Please input: {{ .authExtra }}.
<div class="form-field">
<input type="password" name="auth_secret" placeholder="Password" />
</div>
<button class="btn-primary">Submit</button>
</form>
</div>
{{ end }}
{{ define "toolbar" }}{{ end }}

2
web/auth.go

@ -173,7 +173,7 @@ func ChangeLoginToken ( ctx echo.Context, u core.User, nextStep string, stepExtr
var l core.LoginToken
var count int64
s.db.Where("secret = ? AND expires_at > ? AND type = 'login'", hash, time.Now() ).Count(&count).First( &l );
s.db.Model( &core.LoginToken{} ).Where("secret = ? AND expires_at > ? AND type = 'login'", hash, time.Now() ).Count(&count).First( &l );
if count != 1 {
return false
}

21
web/index.go

@ -73,17 +73,12 @@ func doLogoutHandler ( ctx echo.Context ) error {
// check the Credentials of a user and create a LoginToken for her if they are
// correct.
func doLoginHandler ( ctx echo.Context ) error {
var cnt int64;
var cnt int64
var err error
var u core.User;
var l core.LoginToken
step, stepExtra := loginStepFromToken ( ctx );
if cnt != 1 {
u = core.User{}
step = ""
stepExtra = ""
}
extra := ctx.FormValue ( "auth_extra" );
given := ctx.FormValue ( "auth_secret" );
@ -98,10 +93,12 @@ func doLoginHandler ( ctx echo.Context ) error {
s.db.Model(&core.User{}).Where("name = ?", extra).Count( &cnt ).First( &u );
err = auth.VerifyMain ( s.db, u, given, extra )
NextStep := auth.FollowUp ( u, step );
NextExtra := auth.SeedStep ( step );
NextExtra := auth.SeedStep ( NextStep );
if err == nil {
// we check the count of users with this name here to mitigate timing attacks
if cnt == 1 {
core.Console.Log ( "Step:", NextStep, NextExtra )
if NewLoginToken ( &l, ctx, u, NextStep, NextExtra ) {
ctx.Redirect ( http.StatusFound, "/login" )
}
@ -117,10 +114,12 @@ func doLoginHandler ( ctx echo.Context ) error {
}
err = auth.VerifyExtra ( s.db, u, step, stepExtra, given, extra )
NextStep := auth.FollowUp ( u, step );
NextExtra := auth.SeedStep ( step );
NextExtra := auth.SeedStep ( NextStep );
core.Console.Log ( "StepExtra:", NextStep, NextExtra, err, u.Name )
if err == nil {
if u.Name != "" {
core.Console.Log ( "StepExtra:", NextStep, NextExtra )
if ChangeLoginToken ( ctx, u, NextStep, NextExtra ) == true {
ctx.Redirect ( http.StatusFound, "/login" )
}
@ -128,6 +127,12 @@ func doLoginHandler ( ctx echo.Context ) error {
err = errors.New ("Invalid Auth Operation")
}
if u.Name != "" {
newSeed := auth.SeedStep ( step );
if ChangeLoginToken ( ctx, u, step, newSeed ) == true {
err = errors.New ("Invalid Auth Operation")
}
}
return ctx.Redirect ( http.StatusFound, "/login?error="+err.Error() )
}

Loading…
Cancel
Save