func register(ctx context.Context, req interface{}) (interface{}, *ErrorResponse) { input := req.(*registerRequest) dbMap := ctx.Value("db").(*gorp.DbMap) if input.Username == "" { return nil, &ErrorResponse{http.StatusBadRequest, "username is empty"} } if input.Password == "" { return nil, &ErrorResponse{http.StatusBadRequest, "password is empty"} } count, err := dbMap.SelectInt("select count(id) from users where username = ?", input.Username) if err != nil { return nil, &ErrorResponse{http.StatusInternalServerError, err.Error()} } if count > 0 { return nil, &ErrorResponse{http.StatusBadRequest, "user exists"} } user := model.User{ 0, input.Username, auth.HashPassword(input.Username, input.Password), input.Email, time.Now().UnixNano(), time.Now().UnixNano(), } if err := dbMap.Insert(&user); err != nil { return nil, &ErrorResponse{http.StatusInternalServerError, err.Error()} } return map[string]string{"message": "user created"}, nil }
func login(ctx context.Context, req interface{}) (interface{}, *ErrorResponse) { input := req.(*loginRequest) dbMap := ctx.Value("db").(*gorp.DbMap) authCtx := ctx.Value("auth").(*auth.AuthContext) if authCtx.IsLoggedIn { return nil, &ErrorResponse{http.StatusBadRequest, "already logged in"} } if input.Username == "" { return nil, &ErrorResponse{http.StatusBadRequest, "username is empty"} } if input.Password == "" { return nil, &ErrorResponse{http.StatusBadRequest, "password is empty"} } var user model.User passwordHash := auth.HashPassword(input.Username, input.Password) err := dbMap.SelectOne(&user, "select * from users where username = ? and password_hash = ?", input.Username, passwordHash) if err != nil { return nil, &ErrorResponse{http.StatusBadRequest, "username or password is wrong"} } session := model.Session{ 0, auth.NewToken(), user.Id, time.Now().UnixNano(), time.Now().UnixNano(), } if err := dbMap.Insert(&session); err != nil { return nil, &ErrorResponse{http.StatusInternalServerError, err.Error()} } return map[string]string{"token": session.Token}, nil }
func TestLogin(t *testing.T) { assert := assert.New(t) dbMap := initDb() defer dbMap.Db.Close() authCtx := &auth.AuthContext{false, &model.User{}, &model.Session{}} ctx := context.Background() ctx = context.WithValue(ctx, "db", dbMap) ctx = context.WithValue(ctx, "auth", authCtx) handlerFunc := http.HandlerFunc( func(w http.ResponseWriter, r *http.Request) { Login(ctx, w, r) }, ) server := httptest.NewServer(handlerFunc) defer server.Close() resp := request(t, server.URL, http.StatusBadRequest, map[string]string{ "username": "", "password": "******", }, ) assert.Equal(map[string]interface{}{"message": "username is empty"}, resp) resp = request(t, server.URL, http.StatusBadRequest, map[string]string{ "username": "******", "password": "", }, ) assert.Equal(map[string]interface{}{"message": "password is empty"}, resp) authCtx.IsLoggedIn = true resp = request(t, server.URL, http.StatusBadRequest, map[string]string{ "username": "******", "password": "******", }, ) assert.Equal(map[string]interface{}{"message": "already logged in"}, resp) authCtx.IsLoggedIn = false user := model.User{ 0, "testuser", auth.HashPassword("testuser", "testpassword"), "*****@*****.**", 1441872075622000, 1441872075622000, } err := dbMap.Insert(&user) assert.Nil(err, "Failed to insert test user") resp = request(t, server.URL, http.StatusBadRequest, map[string]string{ "username": "******", "password": "******", }, ) assert.Equal(map[string]interface{}{"message": "username or password is wrong"}, resp) resp = request(t, server.URL, http.StatusOK, map[string]string{ "username": "******", "password": "******", }, ) token := resp.(map[string]interface{})["token"] assert.True(token != "", "Session token must not be empty") }