Skip to content
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

IsSession on auth token and validate admin creds on setup #861

Merged
merged 7 commits into from
Jan 19, 2023
Merged
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
2 changes: 1 addition & 1 deletion .github/workflows/postman-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ jobs:
npm install

- name: Setup
run: echo "APIKEY=$(./estuary setup --username admin --password password | sed -e's/.*EST/EST/g' | tail -n1)" >> $GITHUB_ENV
run: echo "APIKEY=$(./estuary setup --username admin --password password1 | sed -e's/.*EST/EST/g' | tail -n1)" >> $GITHUB_ENV
neelvirdy marked this conversation as resolved.
Show resolved Hide resolved

- name: Run Estuary
run: |
Expand Down
3 changes: 1 addition & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,7 @@ To run locally in a 'dev' environment, first run:
./estuary setup --username=<uname> --password=<pword>
```

Save the auth token that this outputs, you will need it for interacting with
and controlling the node. This username and password won't work to log in using the front end (estuary-www), but the auth token will.
Save the credentials you use here, you will need them to login to the estuary-www frontend.

NOTE: if you want to use a different database than a sqlite instance stored in your local directory, you will need to configure that with the `--database` flag, like so: `./estuary setup --username=<uname> --password=<pword> --database=XXXXX`

Expand Down
12 changes: 8 additions & 4 deletions api/v1/handlers.go
Original file line number Diff line number Diff line change
Expand Up @@ -2673,7 +2673,7 @@ func (s *apiV1) handleRegisterUser(c echo.Context) error {
}
}

authToken, err := s.newAuthTokenForUser(newUser, time.Now().Add(constants.TokenExpiryDurationRegister), nil, TOKEN_LABEL_ON_REGISTER)
authToken, err := s.newAuthTokenForUser(newUser, time.Now().Add(constants.TokenExpiryDurationRegister), nil, TOKEN_LABEL_ON_REGISTER, true)
if err != nil {
return err
}
Expand Down Expand Up @@ -2740,7 +2740,7 @@ func (s *apiV1) handleLoginUser(c echo.Context) error {
}
}

authToken, err := s.newAuthTokenForUser(&user, time.Now().Add(constants.TokenExpiryDurationLogin), nil, TOKEN_LABEL_ON_LOGIN)
authToken, err := s.newAuthTokenForUser(&user, time.Now().Add(constants.TokenExpiryDurationLogin), nil, TOKEN_LABEL_ON_LOGIN, true)
if err != nil {
return err
}
Expand Down Expand Up @@ -2828,7 +2828,7 @@ func (s *apiV1) handleGetUserStats(c echo.Context, u *util.User) error {
return c.JSON(http.StatusOK, stats)
}

func (s *apiV1) newAuthTokenForUser(user *util.User, expiry time.Time, perms []string, label string) (*util.AuthToken, error) {
func (s *apiV1) newAuthTokenForUser(user *util.User, expiry time.Time, perms []string, label string, isSession bool) (*util.AuthToken, error) {
if len(perms) > 1 {
return nil, fmt.Errorf("invalid perms")
}
Expand All @@ -2853,6 +2853,7 @@ func (s *apiV1) newAuthTokenForUser(user *util.User, expiry time.Time, perms []s
User: user.ID,
Expiry: expiry,
UploadOnly: uploadOnly,
IsSession: isSession,
}
if err := s.DB.Create(authToken).Error; err != nil {
return nil, err
Expand Down Expand Up @@ -2930,6 +2931,7 @@ type getApiKeysResp struct {
TokenHash string `json:"tokenHash"`
Label string `json:"label"`
Expiry time.Time `json:"expiry"`
IsSession bool `json:"isSession"`
}

// handleUserRevokeApiKey godoc
Expand Down Expand Up @@ -2986,7 +2988,7 @@ func (s *apiV1) handleUserCreateApiKey(c echo.Context, u *util.User) error {

label := c.QueryParam("label")

authToken, err := s.newAuthTokenForUser(u, expiry, perms, label)
authToken, err := s.newAuthTokenForUser(u, expiry, perms, label, false)
if err != nil {
return err
}
Expand All @@ -2996,6 +2998,7 @@ func (s *apiV1) handleUserCreateApiKey(c echo.Context, u *util.User) error {
TokenHash: authToken.TokenHash,
Label: authToken.Label,
Expiry: authToken.Expiry,
IsSession: authToken.IsSession,
})
}

Expand All @@ -3022,6 +3025,7 @@ func (s *apiV1) handleUserGetApiKeys(c echo.Context, u *util.User) error {
TokenHash: k.TokenHash,
Label: k.Label,
Expiry: k.Expiry,
IsSession: k.IsSession,
})
}

Expand Down
27 changes: 27 additions & 0 deletions constants/constants.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package constants

import (
"regexp"
"time"

"github.com/filecoin-project/go-state-types/abi"
Expand Down Expand Up @@ -40,6 +41,32 @@ const TokenExpiryDurationLogin = time.Hour * 24 * 30 // 30 days
const TokenExpiryDurationDefault = time.Hour * 24 * 30 // 30 days
const TokenExpiryDurationPermanent = time.Hour * 24 * 365 * 100 // 100 years

var AdminUsernameAlphanumericRegex = regexp.MustCompile(`^[A-Za-z\d]{1,32}$`)

func IsAdminUsernameValid(username string) bool {
return AdminUsernameAlphanumericRegex.MatchString(username)
}

var AdminPasswordLengthAndAlphanumericRegex = regexp.MustCompile(`^[A-Za-z\d]{8,}$`)
var AdminPasswordContainsAlphaRegex = regexp.MustCompile(`[A-Za-z]`)
var AdminPasswordContainsNumericRegex = regexp.MustCompile(`\d`)

var AdminPasswordRegexes = []*regexp.Regexp{
AdminPasswordLengthAndAlphanumericRegex,
AdminPasswordContainsAlphaRegex,
AdminPasswordContainsNumericRegex,
}

func IsAdminPasswordValid(password string) bool {
for _, regex := range AdminPasswordRegexes {
ok := regex.MatchString(password)
if !ok {
return false
}
}
return true
}

var DealMaxPrice abi.TokenAmount
var VerifiedDealMaxPrice = abi.NewTokenAmount(0)

Expand Down
3 changes: 3 additions & 0 deletions docs/docs.go
Original file line number Diff line number Diff line change
Expand Up @@ -3403,6 +3403,9 @@ const docTemplate = `{
"expiry": {
"type": "string"
},
"isSession": {
"type": "boolean"
},
"label": {
"type": "string"
},
Expand Down
3 changes: 3 additions & 0 deletions docs/swagger.json
Original file line number Diff line number Diff line change
Expand Up @@ -3396,6 +3396,9 @@
"expiry": {
"type": "string"
},
"isSession": {
"type": "boolean"
},
"label": {
"type": "string"
},
Expand Down
2 changes: 2 additions & 0 deletions docs/swagger.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,8 @@ definitions:
properties:
expiry:
type: string
isSession:
type: boolean
label:
type: string
token:
Expand Down
10 changes: 10 additions & 0 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -523,11 +523,21 @@ func main() {
return errors.New("setup username cannot be empty")
}

ok := constants.IsAdminUsernameValid(username)
if !ok {
return errors.New("username must be alphanumeric and 1-32 characters")
}

password := cctx.String("password")
if password == "" {
return errors.New("setup password cannot be empty")
}

ok = constants.IsAdminPasswordValid(password)
if !ok {
return errors.New("password must be at least eight characters and contain at least one letter and one number")
}

db, err := setupDatabase(cfg.DatabaseConnString)
if err != nil {
return err
Expand Down
1 change: 1 addition & 0 deletions util/users.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ type AuthToken struct {
User uint
UploadOnly bool
Expiry time.Time
IsSession bool
}

type InviteCode struct {
Expand Down