lib9p

Go 9P library.
Log | Files | Refs | LICENSE

auth_test.go (2235B)


      1 package lib9p
      2 
      3 import (
      4 	"context"
      5 	"io"
      6 	"testing"
      7 )
      8 
      9 func TestAuth(t *testing.T) {
     10 	c, rc := setupConn(testfs)
     11 	atc, otc, rtc, wtc := make(chan *request), make(chan *request),
     12 		make(chan *request), make(chan *request)
     13 	ctx, cancel := context.WithCancel(context.Background())
     14 	defer cancel()
     15 	go sAuth(ctx, c, atc)
     16 	go sRead(ctx, c, rtc)
     17 	go sWrite(ctx, c, wtc)
     18 	go sOpen(ctx, c, otc)
     19 	acr, asw := io.Pipe()
     20 	asr, acw := io.Pipe()
     21 	c.s.Auth = func(ctx context.Context, r *request) {
     22 		ifcall := r.ifcall.(*TAuth)
     23 		aqid := Qid{Type: QTAUTH, Vers: 0, Path: ^uint64(0)}
     24 		r.afid.file = &AuthFile{
     25 			Qid:   aqid,
     26 			Uname: ifcall.Uname,
     27 			Aname: ifcall.Aname,
     28 			W:     acw,
     29 			R:     acr,
     30 		}
     31 		runAuth(ctx, t, r.afid.file.(*AuthFile), asr, asw)
     32 		r.ofcall = &RAuth{Tag: ifcall.Tag, Aqid: aqid}
     33 	}
     34 	atc <- &request{ifcall: &TAuth{Afid: 0, Uname: "kenji"}}
     35 	ofcall := (<-rc).ofcall
     36 	if rerror, ok := ofcall.(*RError); ok {
     37 		t.Fatal(rerror)
     38 	}
     39 	otc <- &request{ifcall: &TOpen{Fid: 0, Mode: ORDWR}}
     40 	ofcall = (<-rc).ofcall
     41 	if rerror, ok := ofcall.(*RError); ok {
     42 		t.Fatal(rerror)
     43 	}
     44 	data := []byte("password")
     45 	wtc <- &request{ifcall: &TWrite{Fid: 0, Count: uint32(len(data)), Data: data}}
     46 	ofcall = (<-rc).ofcall
     47 	if rerror, ok := ofcall.(*RError); ok {
     48 		t.Fatal(rerror)
     49 	}
     50 	rtc <- &request{ifcall: &TRead{Fid: 0, Count: 1024}}
     51 	ofcall = (<-rc).ofcall
     52 	if rerror, ok := ofcall.(*RError); ok {
     53 		t.Fatal(rerror)
     54 	}
     55 }
     56 
     57 // Dumb state machine...
     58 // TODO: return when ctx is canceled
     59 func runAuth(ctx context.Context, t *testing.T, afile *AuthFile, r io.Reader, w io.Writer) {
     60 	go func() {
     61 		buf := make([]byte, 10)
     62 		uname := "kenji"
     63 		password := "password"
     64 		state := 0
     65 		for {
     66 			switch state {
     67 			case 0: // start
     68 				if afile.Uname != uname {
     69 					state = 2
     70 					break
     71 				}
     72 				n, err := r.Read(buf)
     73 				if err != nil {
     74 					t.Log(err)
     75 					break
     76 				}
     77 				if string(buf[:n]) == password {
     78 					state = 1
     79 					break
     80 				}
     81 			case 1: // accepted
     82 				afile.AuthOK = true
     83 				go func() {
     84 					for {
     85 						r.Read(buf)
     86 					}
     87 				}()
     88 				for {
     89 					w.Write([]byte("ok"))
     90 				}
     91 			case 2: // unknown user
     92 				go func() {
     93 					for {
     94 						r.Read(buf)
     95 					}
     96 				}()
     97 				for {
     98 					w.Write([]byte("unknown user"))
     99 				}
    100 			}
    101 		}
    102 	}()
    103 }