diff --git a/TODO b/TODO new file mode 100644 index 0000000..af5cfc4 --- /dev/null +++ b/TODO @@ -0,0 +1,2 @@ +x scope registration by URL /users/register=all /users/register/scope=scoped +x rproxy3 scope login by URL diff --git a/oauth2client/client.go b/oauth2client/client.go index 5418591..5df30e6 100644 --- a/oauth2client/client.go +++ b/oauth2client/client.go @@ -11,16 +11,16 @@ import ( "time" ) -func Authenticate(server string, w http.ResponseWriter, r *http.Request) error { +func Authenticate(server, scope string, w http.ResponseWriter, r *http.Request) error { oauth2server, err := url.Parse(server) if err != nil { return err } access, exists := findAccess(w, r) if !exists { - return login(oauth2server, w, r) + return login(oauth2server, scope, w, r) } - return verify(access, oauth2server, w, r) + return verify(access, oauth2server, scope, w, r) } func findAccess(w http.ResponseWriter, r *http.Request) (string, bool) { @@ -58,8 +58,8 @@ func findAccessStable(w http.ResponseWriter, r *http.Request) (string, bool) { return access.Value, true } -func login(oauth2server *url.URL, w http.ResponseWriter, r *http.Request) error { - oauth2server.Path = "/users/log" +func login(oauth2server *url.URL, scope string, w http.ResponseWriter, r *http.Request) error { + oauth2server.Path = "/users/log/" + scope url := *r.URL url.Host = r.Host if url.Scheme == "" { @@ -72,8 +72,8 @@ func login(oauth2server *url.URL, w http.ResponseWriter, r *http.Request) error return errors.New("logging in") } -func verify(access string, oauth2server *url.URL, w http.ResponseWriter, r *http.Request) error { - oauth2server.Path = "/verify" +func verify(access string, oauth2server *url.URL, scope string, w http.ResponseWriter, r *http.Request) error { + oauth2server.Path = "/verify/" + scope data := url.Values{} data.Set("access", access) req, err := http.NewRequest("POST", oauth2server.String(), strings.NewReader(data.Encode())) @@ -94,7 +94,7 @@ func verify(access string, oauth2server *url.URL, w http.ResponseWriter, r *http } defer resp.Body.Close() if resp.StatusCode != http.StatusOK { - return login(oauth2server, w, r) + return login(oauth2server, scope, w, r) } return nil } diff --git a/oauth2server/server/authorize.go b/oauth2server/server/authorize.go index 5eb5b2b..654a453 100644 --- a/oauth2server/server/authorize.go +++ b/oauth2server/server/authorize.go @@ -3,6 +3,7 @@ package server import ( "fmt" "local/oauth2" + "local/router" "local/storage" "net/http" "net/url" @@ -11,18 +12,20 @@ import ( ) func (s *Server) authorize(w http.ResponseWriter, r *http.Request) { + scope := "" + router.Params(r, &scope) s.limiter.Wait(r.Context()) if r.Method != "POST" { http.NotFound(w, r) return } - id := r.FormValue("username") + id := scope + "." + r.FormValue("username") user, ok := s.getUser(id) if !ok { http.Error(w, "unknown user", http.StatusForbidden) return } - access, ok := s.getAccess(user) + access, ok := s.getAccess(scope, user) if !ok { http.Error(w, "no oauth for user", http.StatusForbidden) return @@ -45,23 +48,23 @@ func (s *Server) authorize(w http.ResponseWriter, r *http.Request) { } } -func (s *Server) genAuth(user string) { +func (s *Server) genAuth(scope, user string) { access := uuid.New().String() token := uuid.New().String() s.store.Set(user, []byte(access), ACCESS) - s.store.Set(access, []byte(token), TOKEN) + s.store.Set(scope+"."+access, []byte(token), TOKEN) } -func (s *Server) getAccess(user string) (string, bool) { +func (s *Server) getAccess(scope, user string) (string, bool) { access, err := s.store.Get(user, ACCESS) if err == storage.ErrNotFound { - s.genAuth(user) + s.genAuth(scope, user) access, err = s.store.Get(user, ACCESS) } return string(access), err == nil } -func (s *Server) getToken(access string) (string, bool) { - token, err := s.store.Get(access, TOKEN) +func (s *Server) getToken(scope, access string) (string, bool) { + token, err := s.store.Get(scope+"."+access, TOKEN) return string(token), err == nil } diff --git a/oauth2server/server/routes.go b/oauth2server/server/routes.go index 1727b34..487e6ea 100644 --- a/oauth2server/server/routes.go +++ b/oauth2server/server/routes.go @@ -3,6 +3,7 @@ package server import ( "fmt" "local/oauth2/oauth2server/config" + "local/router" "net/http" ) @@ -13,25 +14,25 @@ func (s *Server) Routes() error { handler http.HandlerFunc }{ { - path: fmt.Sprintf("authorize"), + path: fmt.Sprintf("authorize/%s", router.Wildcard), handler: s.authorize, }, { - path: fmt.Sprintf("verify"), + path: fmt.Sprintf("verify/%s", router.Wildcard), handler: s.verify, }, { - path: fmt.Sprintf("users/log"), + path: fmt.Sprintf("users/log/%s", router.Wildcard), handler: s.usersLog, }, { skip: !config.UserRegistration, - path: fmt.Sprintf("users/register"), + path: fmt.Sprintf("users/register/%s", router.Wildcard), handler: s.usersRegister, }, { skip: !config.UserRegistration, - path: fmt.Sprintf("users/submit"), + path: fmt.Sprintf("users/submit/%s", router.Wildcard), handler: s.usersSubmit, }, } diff --git a/oauth2server/server/users.go b/oauth2server/server/users.go index 1651090..73ef6ff 100644 --- a/oauth2server/server/users.go +++ b/oauth2server/server/users.go @@ -7,18 +7,21 @@ import ( "encoding/hex" "fmt" "local/oauth2/oauth2server/config" + "local/router" "net/http" "github.com/google/uuid" ) func (s *Server) usersLog(w http.ResponseWriter, r *http.Request) { + scope := "" + router.Params(r, &scope) s.limiter.Wait(r.Context()) q := r.URL.Query() fmt.Fprintln(w, ` -
+
@@ -28,11 +31,13 @@ func (s *Server) usersLog(w http.ResponseWriter, r *http.Request) { } func (s *Server) usersRegister(w http.ResponseWriter, r *http.Request) { + scope := "" + router.Params(r, &scope) s.limiter.Wait(r.Context()) fmt.Fprintln(w, ` -
+
@@ -42,12 +47,14 @@ func (s *Server) usersRegister(w http.ResponseWriter, r *http.Request) { } func (s *Server) usersSubmit(w http.ResponseWriter, r *http.Request) { + scope := "" + router.Params(r, &scope) s.limiter.Wait(r.Context()) if r.Method != "POST" { http.NotFound(w, r) return } - id := r.FormValue("username") + id := scope + "." + r.FormValue("username") if _, ok := s.getUser(id); ok { http.Error(w, "user already exists", http.StatusConflict) return diff --git a/oauth2server/server/verify.go b/oauth2server/server/verify.go index 5946a7e..7fa6dbe 100644 --- a/oauth2server/server/verify.go +++ b/oauth2server/server/verify.go @@ -1,16 +1,19 @@ package server import ( + "local/router" "net/http" ) func (s *Server) verify(w http.ResponseWriter, r *http.Request) { + scope := "" + router.Params(r, &scope) if r.Method != "POST" { http.NotFound(w, r) return } access := r.FormValue("access") - token, ok := s.getToken(access) + token, ok := s.getToken(scope, access) if !ok { http.Error(w, "unknown access", http.StatusUnauthorized) return diff --git a/oauth2test/package_test.go b/oauth2test/package_test.go index fbd0673..bdf60d1 100644 --- a/oauth2test/package_test.go +++ b/oauth2test/package_test.go @@ -45,6 +45,7 @@ func TestAll(t *testing.T) { func launchServer() (*httptest.Server, error) { config.Store = "map" + config.UserRegistration = true oauth2server := server.New() err := oauth2server.Routes() @@ -62,7 +63,7 @@ func launchServer() (*httptest.Server, error) { func dummyServer(oauth2server string) *httptest.Server { return httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - err := oauth2client.Authenticate(oauth2server, w, r) + err := oauth2client.Authenticate(oauth2server, "scope", w, r) if err != nil { return } @@ -71,7 +72,7 @@ func dummyServer(oauth2server string) *httptest.Server { } func createUser(oauth2server string) error { - resp, err := http.Post(oauth2server+"/users/submit", "application/x-www-form-urlencoded", strings.NewReader("username=abc")) + resp, err := http.Post(oauth2server+"/users/submit/scope", "application/x-www-form-urlencoded", strings.NewReader("username=abc")) if err != nil { return err } @@ -83,7 +84,7 @@ func createUser(oauth2server string) error { } func logUser(oauth2server string) error { - resp, err := http.Post(oauth2server+"/authorize", "application/x-www-form-urlencoded", strings.NewReader("username=abc")) + resp, err := http.Post(oauth2server+"/authorize/scope", "application/x-www-form-urlencoded", strings.NewReader("username=abc")) if err != nil { return err } @@ -106,7 +107,7 @@ func clientShouldRedir(c *http.Client, dummy string) error { return err } defer resp.Body.Close() - if resp.Request.URL.Path != "/users/log" { + if resp.Request.URL.Path != "/users/log/scope" { return fmt.Errorf("did not need redir without auth: %v", resp.Request.URL) } return nil @@ -119,7 +120,7 @@ func clientShouldNotRedir(c *http.Client, dummy string) error { return err } defer resp.Body.Close() - if resp.Request.URL.Path == "/users/log" { + if resp.Request.URL.Path == "/users/log/scope" { return fmt.Errorf("did redir with auth: %v", resp.Request.URL.Path) } return nil @@ -147,7 +148,7 @@ func testAuth(oauth2server, dummy string) error { } func clientLogin(c *http.Client, oauth2server string) (string, error) { - req, _ := http.NewRequest("POST", oauth2server+"/authorize?"+oauth2.REDIRECT+"="+oauth2server+"/", strings.NewReader("username=abc")) + req, _ := http.NewRequest("POST", oauth2server+"/authorize/scope?"+oauth2.REDIRECT+"="+oauth2server+"/", strings.NewReader("username=abc")) req.Header.Add("Content-Type", "application/x-www-form-urlencoded") resp, err := c.Do(req) if err != nil {