forked from hailey.at/cocoon
An atproto PDS written in Go

cleanup some error returns

+13
internal/helpers/helpers.go
··· 7 "math/rand" 8 "net/url" 9 10 "github.com/labstack/echo/v4" 11 "github.com/lestrrat-go/jwx/v2/jwk" 12 ) ··· 29 msg += ". " + *suffix 30 } 31 return genericError(e, 400, msg) 32 } 33 34 func genericError(e echo.Context, code int, msg string) error {
··· 7 "math/rand" 8 "net/url" 9 10 + "github.com/Azure/go-autorest/autorest/to" 11 "github.com/labstack/echo/v4" 12 "github.com/lestrrat-go/jwx/v2/jwk" 13 ) ··· 30 msg += ". " + *suffix 31 } 32 return genericError(e, 400, msg) 33 + } 34 + 35 + func InvalidTokenError(e echo.Context) error { 36 + return InputError(e, to.StringPtr("InvalidToken")) 37 + } 38 + 39 + func ExpiredTokenError(e echo.Context) error { 40 + // WARN: See https://github.com/bluesky-social/atproto/discussions/3319 41 + return e.JSON(400, map[string]string{ 42 + "error": "ExpiredToken", 43 + "message": "*", 44 + }) 45 } 46 47 func genericError(e echo.Context, code int, msg string) error {
+2 -2
server/handle_server_confirm_email.go
··· 28 } 29 30 if urepo.EmailVerificationCode == nil || urepo.EmailVerificationCodeExpiresAt == nil { 31 - return helpers.InputError(e, to.StringPtr("ExpiredToken")) 32 } 33 34 if *urepo.EmailVerificationCode != req.Token { ··· 36 } 37 38 if time.Now().UTC().After(*urepo.EmailVerificationCodeExpiresAt) { 39 - return helpers.InputError(e, to.StringPtr("ExpiredToken")) 40 } 41 42 now := time.Now().UTC()
··· 28 } 29 30 if urepo.EmailVerificationCode == nil || urepo.EmailVerificationCodeExpiresAt == nil { 31 + return helpers.ExpiredTokenError(e) 32 } 33 34 if *urepo.EmailVerificationCode != req.Token { ··· 36 } 37 38 if time.Now().UTC().After(*urepo.EmailVerificationCodeExpiresAt) { 39 + return helpers.ExpiredTokenError(e) 40 } 41 42 now := time.Now().UTC()
+2 -2
server/handle_server_reset_password.go
··· 33 } 34 35 if *urepo.PasswordResetCode != req.Token { 36 - return helpers.InputError(e, to.StringPtr("InvalidToken")) 37 } 38 39 if time.Now().UTC().After(*urepo.PasswordResetCodeExpiresAt) { 40 - return helpers.InputError(e, to.StringPtr("ExpiredToken")) 41 } 42 43 hash, err := bcrypt.GenerateFromPassword([]byte(req.Password), 10)
··· 33 } 34 35 if *urepo.PasswordResetCode != req.Token { 36 + return helpers.InvalidTokenError(e) 37 } 38 39 if time.Now().UTC().After(*urepo.PasswordResetCodeExpiresAt) { 40 + return helpers.ExpiredTokenError(e) 41 } 42 43 hash, err := bcrypt.GenerateFromPassword([]byte(req.Password), 10)
+3 -4
server/handle_server_update_email.go
··· 3 import ( 4 "time" 5 6 - "github.com/Azure/go-autorest/autorest/to" 7 "github.com/haileyok/cocoon/internal/helpers" 8 "github.com/haileyok/cocoon/models" 9 "github.com/labstack/echo/v4" ··· 29 } 30 31 if urepo.EmailUpdateCode == nil || urepo.EmailUpdateCodeExpiresAt == nil { 32 - return helpers.InputError(e, to.StringPtr("InvalidToken")) 33 } 34 35 if *urepo.EmailUpdateCode != req.Token { 36 - return helpers.InputError(e, to.StringPtr("InvalidToken")) 37 } 38 39 if time.Now().UTC().After(*urepo.EmailUpdateCodeExpiresAt) { 40 - return helpers.InputError(e, to.StringPtr("ExpiredToken")) 41 } 42 43 if err := s.db.Exec("UPDATE repos SET email_update_code = NULL, email_update_code_expires_at = NULL, email_confirmed_at = NULL, email = ? WHERE did = ?", nil, req.Email, urepo.Repo.Did).Error; err != nil {
··· 3 import ( 4 "time" 5 6 "github.com/haileyok/cocoon/internal/helpers" 7 "github.com/haileyok/cocoon/models" 8 "github.com/labstack/echo/v4" ··· 28 } 29 30 if urepo.EmailUpdateCode == nil || urepo.EmailUpdateCodeExpiresAt == nil { 31 + return helpers.InvalidTokenError(e) 32 } 33 34 if *urepo.EmailUpdateCode != req.Token { 35 + return helpers.InvalidTokenError(e) 36 } 37 38 if time.Now().UTC().After(*urepo.EmailUpdateCodeExpiresAt) { 39 + return helpers.ExpiredTokenError(e) 40 } 41 42 if err := s.db.Exec("UPDATE repos SET email_update_code = NULL, email_update_code_expires_at = NULL, email_confirmed_at = NULL, email = ? WHERE did = ?", nil, req.Email, urepo.Repo.Did).Error; err != nil {
+11 -12
server/middleware.go
··· 54 token, _, err := new(jwt.Parser).ParseUnverified(tokenstr, jwt.MapClaims{}) 55 claims, ok := token.Claims.(jwt.MapClaims) 56 if !ok { 57 - return helpers.InputError(e, to.StringPtr("InvalidToken")) 58 } 59 60 var did string ··· 93 }) 94 if err != nil { 95 s.logger.Error("error parsing jwt", "error", err) 96 - // NOTE: https://github.com/bluesky-social/atproto/discussions/3319 97 - return e.JSON(400, map[string]string{"error": "ExpiredToken", "message": "token has expired"}) 98 } 99 100 if !token.Valid { 101 - return helpers.InputError(e, to.StringPtr("InvalidToken")) 102 } 103 } else { 104 kpts := strings.Split(tokenstr, ".") ··· 143 scope, _ := claims["scope"].(string) 144 145 if isRefresh && scope != "com.atproto.refresh" { 146 - return helpers.InputError(e, to.StringPtr("InvalidToken")) 147 } else if !hasLxm && !isRefresh && scope != "com.atproto.access" { 148 - return helpers.InputError(e, to.StringPtr("InvalidToken")) 149 } 150 151 table := "tokens" ··· 160 var result Result 161 if err := s.db.Raw("SELECT EXISTS(SELECT 1 FROM "+table+" WHERE token = ?) AS found", nil, tokenstr).Scan(&result).Error; err != nil { 162 if err == gorm.ErrRecordNotFound { 163 - return helpers.InputError(e, to.StringPtr("InvalidToken")) 164 } 165 166 s.logger.Error("error getting token from db", "error", err) ··· 168 } 169 170 if !result.Found { 171 - return helpers.InputError(e, to.StringPtr("InvalidToken")) 172 } 173 } 174 ··· 179 } 180 181 if exp < float64(time.Now().UTC().Unix()) { 182 - return helpers.InputError(e, to.StringPtr("ExpiredToken")) 183 } 184 185 if repo == nil { ··· 197 e.Set("token", tokenstr) 198 199 if err := next(e); err != nil { 200 - e.Error(err) 201 } 202 203 return nil ··· 241 } 242 243 if oauthToken.Token == "" { 244 - return helpers.InputError(e, to.StringPtr("InvalidToken")) 245 } 246 247 if *oauthToken.Parameters.DpopJkt != proof.JKT { ··· 250 } 251 252 if time.Now().After(oauthToken.ExpiresAt) { 253 - return e.JSON(400, map[string]string{"error": "ExpiredToken", "message": "token has expired"}) 254 } 255 256 repo, err := s.getRepoActorByDid(oauthToken.Sub)
··· 54 token, _, err := new(jwt.Parser).ParseUnverified(tokenstr, jwt.MapClaims{}) 55 claims, ok := token.Claims.(jwt.MapClaims) 56 if !ok { 57 + return helpers.InvalidTokenError(e) 58 } 59 60 var did string ··· 93 }) 94 if err != nil { 95 s.logger.Error("error parsing jwt", "error", err) 96 + return helpers.ExpiredTokenError(e) 97 } 98 99 if !token.Valid { 100 + return helpers.InvalidTokenError(e) 101 } 102 } else { 103 kpts := strings.Split(tokenstr, ".") ··· 142 scope, _ := claims["scope"].(string) 143 144 if isRefresh && scope != "com.atproto.refresh" { 145 + return helpers.InvalidTokenError(e) 146 } else if !hasLxm && !isRefresh && scope != "com.atproto.access" { 147 + return helpers.InvalidTokenError(e) 148 } 149 150 table := "tokens" ··· 159 var result Result 160 if err := s.db.Raw("SELECT EXISTS(SELECT 1 FROM "+table+" WHERE token = ?) AS found", nil, tokenstr).Scan(&result).Error; err != nil { 161 if err == gorm.ErrRecordNotFound { 162 + return helpers.InvalidTokenError(e) 163 } 164 165 s.logger.Error("error getting token from db", "error", err) ··· 167 } 168 169 if !result.Found { 170 + return helpers.InvalidTokenError(e) 171 } 172 } 173 ··· 178 } 179 180 if exp < float64(time.Now().UTC().Unix()) { 181 + return helpers.ExpiredTokenError(e) 182 } 183 184 if repo == nil { ··· 196 e.Set("token", tokenstr) 197 198 if err := next(e); err != nil { 199 + return helpers.InvalidTokenError(e) 200 } 201 202 return nil ··· 240 } 241 242 if oauthToken.Token == "" { 243 + return helpers.InvalidTokenError(e) 244 } 245 246 if *oauthToken.Parameters.DpopJkt != proof.JKT { ··· 249 } 250 251 if time.Now().After(oauthToken.ExpiresAt) { 252 + return helpers.ExpiredTokenError(e) 253 } 254 255 repo, err := s.getRepoActorByDid(oauthToken.Sub)