<commit_before>package v1

import (
	"database/sql"
	"encoding/base64"
	"encoding/json"
	"github.com/fritzpay/paymentd/pkg/paymentd/config"
	"github.com/fritzpay/paymentd/pkg/service"
	"github.com/fritzpay/paymentd/pkg/testutil"
	. "github.com/smartystreets/goconvey/convey"
	"gopkg.in/inconshreveable/log15.v2"
	"net/http"
	"testing"
)

func WithSystemPassword(db *sql.DB, f func()) func() {
	return func() {
		cfg := config.NewConfig()
		pw := config.SetPassword([]byte("password"))
		err := pw(cfg)
		So(err, ShouldBeNil)

		tx, err := db.Begin()
		So(err, ShouldBeNil)
		err = config.InsertConfigIfNotPresentTx(tx, cfg)
		So(err, ShouldBeNil)

		Reset(func() {
			err = tx.Rollback()
			So(err, ShouldBeNil)
		})

		f()
	}
}

func TestGetCredentialsWithBasicAuth(t *testing.T) {
	Convey("Given a new context", t, testutil.WithContext(func(ctx *service.Context, logChan <-chan *log15.Record) {
		ctx.Config().API.ServeAdmin = true
		So(ctx.Config().API.ServeAdmin, ShouldBeTrue)

		Convey("Given a new API service", WithService(ctx, logChan, func(s *Service, mux *http.ServeMux) {

			Convey("Given a new get credentials request", func() {
				r, err := http.NewRequest("GET", ServicePath+"/authorization", nil)
				So(err, ShouldBeNil)

				Convey("When the request method is PUT", func() {
					r.Method = "PUT"

					Convey("When the handler is called", func() {
						w := testutil.NewResponseWriter()
						mux.ServeHTTP(w, r)
						Convey("The handler should respond with method not allowed", func() {
							So(w.HeaderWritten, ShouldBeTrue)
							So(w.StatusCode, ShouldEqual, http.StatusMethodNotAllowed)
						})
					})
				})

				Convey("When the request method is DELETE", func() {
					r.Method = "DELETE"

					Convey("When the handler is called", func() {
						w := testutil.NewResponseWriter()
						mux.ServeHTTP(w, r)
						Convey("The handler should respond with method not allowed", func() {
							So(w.HeaderWritten, ShouldBeTrue)
							So(w.StatusCode, ShouldEqual, http.StatusMethodNotAllowed)
						})
					})
				})

				Convey("When the authentication method is unknown", func() {
					r.URL.Path += "/unknown"

					Convey("When the handler is called", func() {
						w := testutil.NewResponseWriter()
						mux.ServeHTTP(w, r)
						Convey("The handler should respond with a 404 (not found)", func() {
							So(w.HeaderWritten, ShouldBeTrue)
							So(w.StatusCode, ShouldEqual, http.StatusNotFound)
						})
					})
				})

				Convey("Given a payment DB", testutil.WithPaymentDB(t, func(db *sql.DB) {
					ctx.SetPaymentDB(db, nil)

					Reset(func() {
						db.Close()
					})

					Convey("Given a set system password", WithSystemPassword(db, func() {
						Convey("When retrieving a basic authorization", func() {
							r.Method = "GET"
							r.URL.Path += "/basic"

							Convey("When using the correct password", func() {
								r.Header.Set("Authorization", "Basic "+base64.StdEncoding.EncodeToString([]byte("root:password")))

								Convey("When the handler is called", func() {
									w := testutil.NewResponseWriter()
									mux.ServeHTTP(w, r)
									Convey("The handler should respond with OK", func() {
										So(w.HeaderWritten, ShouldBeTrue)
										So(w.StatusCode, ShouldEqual, http.StatusOK)
										Convey("The body should contain the authorization container", func() {
											m := make(map[string]string)
											dec := json.NewDecoder(&w.Buf)
											err := dec.Decode(&m)
											So(err, ShouldBeNil)
											So(m["Authorization"], ShouldNotBeEmpty)
										})
									})

									Convey("Given the returned authorization container", func() {
										m := make(map[string]string)
										dec := json.NewDecoder(&w.Buf)
										err := dec.Decode(&m)
										So(err, ShouldBeNil)
										So(m["Authorization"], ShouldNotBeEmpty)

										Convey("Given a service request context", func() {
											service.SetRequestContext(r, ctx)

											Convey("Given a get user request", func() {
												r.Method = "GET"
												r.URL.Path = ServicePath + "/user"
												r.Header.Set("Authorization", m["Authorization"])

												Convey("When the handler is called", func() {
													w := testutil.NewResponseWriter()
													mux.ServeHTTP(w, r)
													Convey("The handler should respond with OK", func() {
														So(w.HeaderWritten, ShouldBeTrue)
														So(w.StatusCode, ShouldEqual, http.StatusOK)
													})
												})
											})
										})
									})
								})
							})

							Convey("When using a wrong password", func() {
								r.Header.Set("Authorization", "Basic dede")

								Convey("When the handler is called", func() {
									w := testutil.NewResponseWriter()
									mux.ServeHTTP(w, r)
									Convey("The handler should respond with Unauthorized", func() {
										So(w.HeaderWritten, ShouldBeTrue)
										So(w.StatusCode, ShouldEqual, http.StatusUnauthorized)
									})
								})
							})

							Convey("When using a bad authorization header", func() {
								r.Header.Set("Authorization", "Basic")

								Convey("When the handler is called", func() {
									w := testutil.NewResponseWriter()
									mux.ServeHTTP(w, r)
									Convey("The handler should request an authorization", func() {
										So(w.HeaderWritten, ShouldBeTrue)
										So(w.StatusCode, ShouldEqual, http.StatusUnauthorized)
										So(w.Header().Get("WWW-Authenticate"), ShouldNotBeEmpty)
									})
								})
							})
						})
					}))
				}))
			})
		}))<commit_msg>fixed auth_test for mux router<commit_after>package v1

import (
	"database/sql"
	"encoding/base64"
	"encoding/json"
	"github.com/fritzpay/paymentd/pkg/paymentd/config"
	"github.com/fritzpay/paymentd/pkg/service"
	"github.com/fritzpay/paymentd/pkg/testutil"
	"github.com/gorilla/mux"
	. "github.com/smartystreets/goconvey/convey"
	"gopkg.in/inconshreveable/log15.v2"
	"net/http"
	"testing"
)

func WithSystemPassword(db *sql.DB, f func()) func() {
	return func() {
		cfg := config.NewConfig()
		pw := config.SetPassword([]byte("password"))
		err := pw(cfg)
		So(err, ShouldBeNil)

		tx, err := db.Begin()
		So(err, ShouldBeNil)
		err = config.InsertConfigIfNotPresentTx(tx, cfg)
		So(err, ShouldBeNil)

		Reset(func() {
			err = tx.Rollback()
			So(err, ShouldBeNil)
		})

		f()
	}
}

func TestGetCredentialsWithBasicAuth(t *testing.T) {
	Convey("Given a new context", t, testutil.WithContext(func(ctx *service.Context, logChan <-chan *log15.Record) {
		ctx.Config().API.ServeAdmin = true
		So(ctx.Config().API.ServeAdmin, ShouldBeTrue)

		Convey("Given a new API service", WithService(ctx, logChan, func(s *Service, mx *mux.Router) {

			Convey("Given a new get credentials request", func() {
				r, err := http.NewRequest("GET", ServicePath+"/authorization", nil)
				So(err, ShouldBeNil)

				Convey("When the request method is PUT", func() {
					r.Method = "PUT"

					Convey("When the handler is called", func() {
						w := testutil.NewResponseWriter()
						mx.ServeHTTP(w, r)
						Convey("The handler should respond with method not allowed", func() {
							So(w.HeaderWritten, ShouldBeTrue)
							So(w.StatusCode, ShouldEqual, http.StatusMethodNotAllowed)
						})
					})
				})

				Convey("When the request method is DELETE", func() {
					r.Method = "DELETE"

					Convey("When the handler is called", func() {
						w := testutil.NewResponseWriter()
						mx.ServeHTTP(w, r)
						Convey("The handler should respond with method not allowed", func() {
							So(w.HeaderWritten, ShouldBeTrue)
							So(w.StatusCode, ShouldEqual, http.StatusMethodNotAllowed)
						})
					})
				})

				Convey("When the authentication method is unknown", func() {
					r.URL.Path += "/unknown"

					Convey("When the handler is called", func() {
						w := testutil.NewResponseWriter()
						mx.ServeHTTP(w, r)
						Convey("The handler should respond with a 404 (not found)", func() {
							So(w.HeaderWritten, ShouldBeTrue)
							So(w.StatusCode, ShouldEqual, http.StatusNotFound)
						})
					})
				})

				Convey("Given a payment DB", testutil.WithPaymentDB(t, func(db *sql.DB) {
					ctx.SetPaymentDB(db, nil)

					Reset(func() {
						db.Close()
					})

					Convey("Given a set system password", WithSystemPassword(db, func() {
						Convey("When retrieving a basic authorization", func() {
							r.Method = "GET"
							r.URL.Path += "/basic"

							Convey("When using the correct password", func() {
								r.Header.Set("Authorization", "Basic "+base64.StdEncoding.EncodeToString([]byte("root:password")))

								Convey("When the handler is called", func() {
									w := testutil.NewResponseWriter()
									mx.ServeHTTP(w, r)
									Convey("The handler should respond with OK", func() {
										So(w.HeaderWritten, ShouldBeTrue)
										So(w.StatusCode, ShouldEqual, http.StatusOK)
										Convey("The body should contain the authorization container", func() {
											m := make(map[string]string)
											dec := json.NewDecoder(&w.Buf)
											err := dec.Decode(&m)
											So(err, ShouldBeNil)
											So(m["Authorization"], ShouldNotBeEmpty)
										})
									})

									Convey("Given the returned authorization container", func() {
										m := make(map[string]string)
										dec := json.NewDecoder(&w.Buf)
										err := dec.Decode(&m)
										So(err, ShouldBeNil)
										So(m["Authorization"], ShouldNotBeEmpty)

										Convey("Given a service request context", func() {
											service.SetRequestContext(r, ctx)

											Convey("Given a get user request", func() {
												r.Method = "GET"
												r.URL.Path = ServicePath + "/user"
												r.Header.Set("Authorization", m["Authorization"])

												Convey("When the handler is called", func() {
													w := testutil.NewResponseWriter()
													mx.ServeHTTP(w, r)
													Convey("The handler should respond with OK", func() {
														So(w.HeaderWritten, ShouldBeTrue)
														So(w.StatusCode, ShouldEqual, http.StatusOK)
													})
												})
											})
										})
									})
								})
							})

							Convey("When using a wrong password", func() {
								r.Header.Set("Authorization", "Basic dede")

								Convey("When the handler is called", func() {
									w := testutil.NewResponseWriter()
									mx.ServeHTTP(w, r)
									Convey("The handler should respond with Unauthorized", func() {
										So(w.HeaderWritten, ShouldBeTrue)
										So(w.StatusCode, ShouldEqual, http.StatusUnauthorized)
									})
								})
							})

							Convey("When using a bad authorization header", func() {
								r.Header.Set("Authorization", "Basic")

								Convey("When the handler is called", func() {
									w := testutil.NewResponseWriter()
									mx.ServeHTTP(w, r)
									Convey("The handler should request an authorization", func() {
										So(w.HeaderWritten, ShouldBeTrue)
										So(w.StatusCode, ShouldEqual, http.StatusUnauthorized)
										So(w.Header().Get("WWW-Authenticate"), ShouldNotBeEmpty)
									})
								})
							})
						})
					}))
				}))
			})
		}))
{'fraction_non_alphanumeric': 0.1374641319942611, 'fraction_numerical': 0.0023314203730272595, 'mean_word_length': 2.5339036755386566, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '340055', 'n_tokens_mistral': 5058, 'n_tokens_neox': 3446, 'n_words': 779}