Skip to content

Add Aurum as authentication service #32

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 3 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 10 additions & 10 deletions .run/Control server.run.xml
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="Control server" type="GoApplicationRunConfiguration" factoryName="Go Application">
<module name="AAAAA" />
<working_directory value="$PROJECT_DIR$/" />
<go_parameters value="-i" />
<kind value="PACKAGE" />
<filePath value="$PROJECT_DIR$/services/control_server" />
<package value="github.com/finitum/AAAAA/services/control_server" />
<directory value="$PROJECT_DIR$/" />
<method v="2" />
</configuration>
<configuration default="false" name="Control server" type="GoApplicationRunConfiguration" factoryName="Go Application">
<module name="AAAAA" />
<working_directory value="$PROJECT_DIR$/" />
<go_parameters value="-i" />
<kind value="PACKAGE" />
<filePath value="$PROJECT_DIR$/services/control_server" />
<package value="github.com/finitum/AAAAA/services/control_server" />
<directory value="$PROJECT_DIR$/" />
<method v="2" />
</configuration>
</component>
5 changes: 3 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ require (
github.com/docker/docker v17.12.0-ce-rc1.0.20200916142827-bd33bbf0497b+incompatible
github.com/docker/go-connections v0.4.0 // indirect
github.com/docker/go-units v0.4.0 // indirect
github.com/finitum/aurum v0.0.0-20201110134241-2af7867ae837
github.com/go-chi/chi v4.1.2+incompatible
github.com/go-chi/jwtauth v4.0.4+incompatible
github.com/go-chi/render v1.0.1
Expand All @@ -26,9 +27,9 @@ require (
github.com/pkg/errors v0.9.1
github.com/sirupsen/logrus v1.7.0
github.com/stretchr/testify v1.6.1
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9
golang.org/x/crypto v0.0.0-20201016220609-9e8e0b390897
golang.org/x/net v0.0.0-20201031054903-ff519b6c9102 // indirect
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f
golang.org/x/sys v0.0.0-20201020230747-6e5568b54d1a
golang.org/x/time v0.0.0-20200630173020-3af7569d3a1e // indirect
google.golang.org/grpc v1.33.1 // indirect
gotest.tools v2.2.0+incompatible // indirect
Expand Down
38 changes: 38 additions & 0 deletions go.sum

Large diffs are not rendered by default.

59 changes: 59 additions & 0 deletions pkg/auth/aurum.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
package auth

import (
"github.com/finitum/aurum/clients/go"
"github.com/pkg/errors"
log "github.com/sirupsen/logrus"
)

type Aurum struct {
au *aurum.Aurum
}

func NewAurum(url string) (*Aurum, error) {
au, err := aurum.Connect(url)
if err != nil {
return nil, errors.Wrap(err, "connecting to aurum failed")
}

return &Aurum{ au }, nil
}

func (a *Aurum) Login(user string, pass string) (string, error) {
tp, err := a.au.Login(user, pass)
if err != nil {
return "", err
}

return tp.LoginToken, nil
}

func (a *Aurum) Register(user FullUser) error {
if user.Email == "" {
user.Email = "no-email"
}

err := a.au.Register(user.Username, user.Password, user.Email)
return errors.Wrap(err, "aurum signup failed")
}

func (a *Aurum) Update(user FullUser, token string) error {
log.Error("updating user unsupported")
return errors.New("unsupported")
}

func (a *Aurum) Verify(token string) (ret Claims, _ bool) {
claims, err := a.au.Verify(token)
if err != nil {
return Claims{}, false
}

if err := claims.Valid(); err != nil {
return Claims{}, false
}


ret.Username = claims.Username
ret.RawToken = token
return ret, !claims.Refresh
}
127 changes: 123 additions & 4 deletions pkg/auth/auth.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,128 @@
package auth

import "github.com/finitum/AAAAA/pkg/models"
import (
"context"
"github.com/finitum/AAAAA/pkg/models"
"github.com/finitum/AAAAA/pkg/store"
"github.com/pkg/errors"
"net/http"
"strings"
)

const VerifierContextKey = "AAAAA jwt verification key"

type FullUser struct {
models.User
Password string
Email string `json:"-,omitempty"`
}

func (u *FullUser) Bind(*http.Request) error {
if u.Username == "" || u.Password == "" {
return errors.New("invalid user")
}

return nil
}

type Claims struct {
models.User
RawToken string
}

type AuthenticationService interface {
Login(user *models.User) (string, error)
Register(user *models.User) error
Update(user *models.User) error
// Login should login a user and return a token
Login(user string, pass string) (string, error)
// Register should create a user in the service
Register(user FullUser) error
// Update should update the email and password on the service
Update(user FullUser, token string) error

// Verify verifies a jwt token returns claims, true if success nil, false otherwise
Verify(token string) (Claims, bool)
}

// FromContext retrieves the Claims from a request context, returns Claims, true on success nil, false otherwise
func FromContext(ctx context.Context) (Claims, bool) {
claims, ok := ctx.Value(VerifierContextKey).(Claims)
if !ok {
return Claims{}, false
}
return claims, true
}

/* Authenticator */

type Authenticator struct {
as AuthenticationService
us store.UserStore
}

func NewAuthenticator(as AuthenticationService, us store.UserStore) *Authenticator {
return &Authenticator{as, us}
}

func (a Authenticator) Login(username, password string) (string, error) {
if _, err := a.us.GetUser(username); err != nil {
return "", err
}

return a.as.Login(username, password)
}

func (a Authenticator) Register(user FullUser) error {
if err := a.as.Register(user); err != nil {
return err
}

if err := a.us.AddUser(&user.User); err != nil {
return err
}

return nil
}

func (a Authenticator) Update(user FullUser, token string) error {
if _, err := a.us.GetUser(user.Username); err != nil {
return err
}

return a.as.Update(user, token)
}

func (a Authenticator) GetUsers() ([]*models.User, error) {
return a.us.AllUsers()
}

func (a Authenticator) GetUserNames() ([]string, error) {
return a.us.AllUserNames()
}

func (a Authenticator) DeleteUser(username string) error {
return a.us.DelUser(username)
}

// VerificationMiddleware calls AuthenticationService.Verify, 401s on failure and puts the claims in the request context
// on success, these can be retrieved with FromContext
func (a Authenticator)VerificationMiddleware(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
auth := r.Header.Get("Authorization")
if !strings.HasPrefix(auth, "Bearer ") {
http.Error(w, http.StatusText(http.StatusUnauthorized), http.StatusUnauthorized)
return
}
auth = strings.TrimPrefix(auth, "Bearer ")

claims, valid := a.as.Verify(auth)
if !valid {
http.Error(w, http.StatusText(http.StatusUnauthorized), http.StatusUnauthorized)
return
}

claims.RawToken = auth

ctx := context.WithValue(r.Context(), VerifierContextKey, claims)

next.ServeHTTP(w, r.WithContext(ctx))
})
}
77 changes: 0 additions & 77 deletions pkg/auth/store.go

This file was deleted.

2 changes: 1 addition & 1 deletion pkg/dependency/dep_resolver.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ type Dependency struct {
}

/*
Resolver represents an a resolver, which is able to resolve all dependencies of a given package with the given name.
Resolver represents a resolver, which is able to resolve all dependencies of a given package with the given name.

Most use cases can be solved by using a custom InfoResolveFunction in combination with a custom URL, but it is possible
to provide an alternative implementation of the default resolver by implementing this interface.
Expand Down
5 changes: 1 addition & 4 deletions pkg/models/models.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,17 +53,14 @@ func (p *Pkg) Bind(*http.Request) error {

type User struct {
Username string
Password string
}

func (u *User) Render(w http.ResponseWriter, r *http.Request) error {
u.Password = ""

return nil
}

func (u *User) Bind(*http.Request) error {
if u.Username == "" || u.Password == "" {
if u.Username == "" {
return errors.New("invalid user")
}

Expand Down
3 changes: 0 additions & 3 deletions pkg/store/badger_store_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,6 @@ func TestBadger_AllPackages(t *testing.T) {
func TestBadger_AddGetDelUser(t *testing.T) {
tstUser := models.User{
Username: "testkees",
Password: "encryptedyes?",
}

storePath := os.TempDir() + "/TestBadger_AddUser"
Expand All @@ -103,11 +102,9 @@ func TestBadger_AddGetDelUser(t *testing.T) {
func TestBadger_AllUserNames(t *testing.T) {
tstUser := models.User{
Username: "yoink",
Password: "rot26bestencryption",
}
tstUser2 := models.User{
Username: "; DROP TABLE 'USERS';--",
Password: "2xrot13bestencryption",
}

storePath := os.TempDir() + "/TestBadger_AllUserNames"
Expand Down
Loading