WIP: Begin OAuth2 implementation #598
62
pkg/models/oauth2_blocked_jti.go
Normal file
62
pkg/models/oauth2_blocked_jti.go
Normal file
|
@ -0,0 +1,62 @@
|
|||
// Vikunja is a to-do list application to facilitate your life.
|
||||
// Copyright 2018-2020 Vikunja and contributors. All rights reserved.
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
package models
|
||||
|
||||
import (
|
||||
"crypto"
|
||||
"encoding/base64"
|
||||
"time"
|
||||
)
|
||||
|
||||
// OAuth2JTIBlocklist contains all JTI signatures for already assinged JWT tokens
|
||||
type OAuth2BlockedJTI struct {
|
||||
Signature string `xorm:"pk not null"`
|
||||
ExpiresAt *time.Time
|
||||
}
|
||||
|
||||
func calculateSignatureOfJTI(jti string) string {
|
||||
hasher := crypto.SHA256.New()
|
||||
hasher.Write([]byte(jti))
|
||||
return base64.URLEncoding.EncodeToString(hasher.Sum(nil))
|
||||
}
|
||||
|
||||
// BlockOAuth2JTI blocks the given JTI from reassigning until it expires
|
||||
func BlockOAuth2JTI(jti string, expiresAt *time.Time) error {
|
||||
_, err := x.Insert(&OAuth2BlockedJTI{
|
||||
Signature: calculateSignatureOfJTI(jti),
|
||||
ExpiresAt: expiresAt,
|
||||
})
|
||||
return err
|
||||
}
|
||||
|
||||
// DeleteExpiredJTIs deletes all expired JTIs from the database
|
||||
func DeleteExpiredJTIs() error {
|
||||
_, err := x.Where("expires_at < now()").Delete(&OAuth2BlockedJTI{})
|
||||
return err
|
||||
}
|
||||
|
||||
// IsJTIBlocked checks if a given JTI is already present in the block list and if present checks if the present
|
||||
// JTI is expired. True is the default value if an error occurs.
|
||||
func IsJTIBlocked(jti string) (bool, error) {
|
||||
blockedJTI := new(OAuth2BlockedJTI)
|
||||
if has, err := x.ID(calculateSignatureOfJTI(jti)).Get(&blockedJTI); err != nil {
|
||||
return true, err
|
||||
} else if !has {
|
||||
return false, nil
|
||||
}
|
||||
return blockedJTI.ExpiresAt.Before(time.Now()), nil
|
||||
}
|
|
@ -1,3 +1,19 @@
|
|||
// Vikunja is a to-do list application to facilitate your life.
|
||||
// Copyright 2018-2020 Vikunja and contributors. All rights reserved.
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
package models
|
||||
|
||||
import (
|
||||
|
|
|
@ -2,6 +2,7 @@ package oauth
|
|||
|
||||
import (
|
||||
"context"
|
||||
"github.com/pkg/errors"
|
||||
"time"
|
||||
|
||||
"github.com/ory/fosite"
|
||||
|
@ -20,11 +21,20 @@ func (s *Storage) GetClient(ctx context.Context, id string) (fosite.Client, erro
|
|||
}
|
||||
|
||||
func (s *Storage) ClientAssertionJWTValid(ctx context.Context, jti string) error {
|
||||
panic("implement me")
|
||||
if isBlocked, err := models.IsJTIBlocked(jti); err != nil {
|
||||
return err
|
||||
} else if isBlocked {
|
||||
return errors.WithStack(fosite.ErrJTIKnown)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *Storage) SetClientAssertionJWT(ctx context.Context, jti string, exp time.Time) error {
|
||||
panic("implement me")
|
||||
// Clean up the database
|
||||
if err := models.DeleteExpiredJTIs(); err != nil {
|
||||
return err
|
||||
}
|
||||
return models.BlockOAuth2JTI(jti, &exp)
|
||||
}
|
||||
|
||||
func (s *Storage) CreateAuthorizeCodeSession(ctx context.Context, code string, request fosite.Requester) (err error) {
|
||||
|
|
Loading…
Reference in New Issue
Block a user
Will xorm make this a text or varchar? It should be a varchar since it's used as primary key.