mirror of
				https://github.com/juanfont/headscale.git
				synced 2025-10-30 23:51:03 +01:00 
			
		
		
		
	do not allow preauth keys to be deleted if assigned to node (#2396)
* do not allow preauth keys to be deleted if assigned to node Signed-off-by: Kristoffer Dalby <kristoffer@tailscale.com> * update changelog Signed-off-by: Kristoffer Dalby <kristoffer@tailscale.com> --------- Signed-off-by: Kristoffer Dalby <kristoffer@tailscale.com>
This commit is contained in:
		
							parent
							
								
									d57a55c024
								
							
						
					
					
						commit
						9bd143852f
					
				| @ -20,6 +20,10 @@ | |||||||
|   [#2350](https://github.com/juanfont/headscale/pull/2350) |   [#2350](https://github.com/juanfont/headscale/pull/2350) | ||||||
| - Print Tailscale version instead of capability versions for outdated nodes | - Print Tailscale version instead of capability versions for outdated nodes | ||||||
|   [#2391](https://github.com/juanfont/headscale/pull/2391) |   [#2391](https://github.com/juanfont/headscale/pull/2391) | ||||||
|  | - Pre auth keys belonging to a user are no longer deleted with the user | ||||||
|  |   [#2396](https://github.com/juanfont/headscale/pull/2396) | ||||||
|  | - Pre auth keys that are used by a node can no longer be deleted | ||||||
|  |   [#2396](https://github.com/juanfont/headscale/pull/2396) | ||||||
| 
 | 
 | ||||||
| ## 0.24.2 (2025-01-30) | ## 0.24.2 (2025-01-30) | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -582,6 +582,24 @@ COMMIT; | |||||||
| 				}, | 				}, | ||||||
| 				Rollback: func(db *gorm.DB) error { return nil }, | 				Rollback: func(db *gorm.DB) error { return nil }, | ||||||
| 			}, | 			}, | ||||||
|  | 			// Add back constraint so you cannot delete preauth keys that | ||||||
|  | 			// is still used by a node. | ||||||
|  | 			{ | ||||||
|  | 				ID: "202501311657", | ||||||
|  | 				Migrate: func(tx *gorm.DB) error { | ||||||
|  | 					err := tx.AutoMigrate(&types.PreAuthKey{}) | ||||||
|  | 					if err != nil { | ||||||
|  | 						return err | ||||||
|  | 					} | ||||||
|  | 					err = tx.AutoMigrate(&types.Node{}) | ||||||
|  | 					if err != nil { | ||||||
|  | 						return err | ||||||
|  | 					} | ||||||
|  | 
 | ||||||
|  | 					return nil | ||||||
|  | 				}, | ||||||
|  | 				Rollback: func(db *gorm.DB) error { return nil }, | ||||||
|  | 			}, | ||||||
| 		}, | 		}, | ||||||
| 	) | 	) | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -2,10 +2,13 @@ package db | |||||||
| 
 | 
 | ||||||
| import ( | import ( | ||||||
| 	"sort" | 	"sort" | ||||||
|  | 	"testing" | ||||||
| 	"time" | 	"time" | ||||||
| 
 | 
 | ||||||
| 	"github.com/juanfont/headscale/hscontrol/types" | 	"github.com/juanfont/headscale/hscontrol/types" | ||||||
| 	"github.com/juanfont/headscale/hscontrol/util" | 	"github.com/juanfont/headscale/hscontrol/util" | ||||||
|  | 	"github.com/stretchr/testify/assert" | ||||||
|  | 	"github.com/stretchr/testify/require" | ||||||
| 	"gopkg.in/check.v1" | 	"gopkg.in/check.v1" | ||||||
| 	"tailscale.com/types/ptr" | 	"tailscale.com/types/ptr" | ||||||
| ) | ) | ||||||
| @ -175,3 +178,25 @@ func (*Suite) TestPreAuthKeyACLTags(c *check.C) { | |||||||
| 	sort.Sort(sort.StringSlice(gotTags)) | 	sort.Sort(sort.StringSlice(gotTags)) | ||||||
| 	c.Assert(gotTags, check.DeepEquals, tags) | 	c.Assert(gotTags, check.DeepEquals, tags) | ||||||
| } | } | ||||||
|  | 
 | ||||||
|  | func TestCannotDeleteAssignedPreAuthKey(t *testing.T) { | ||||||
|  | 	db, err := newSQLiteTestDB() | ||||||
|  | 	require.NoError(t, err) | ||||||
|  | 	user, err := db.CreateUser(types.User{Name: "test8"}) | ||||||
|  | 	assert.NoError(t, err) | ||||||
|  | 
 | ||||||
|  | 	key, err := db.CreatePreAuthKey(types.UserID(user.ID), false, false, nil, []string{"tag:good"}) | ||||||
|  | 	assert.NoError(t, err) | ||||||
|  | 
 | ||||||
|  | 	node := types.Node{ | ||||||
|  | 		ID:             0, | ||||||
|  | 		Hostname:       "testest", | ||||||
|  | 		UserID:         user.ID, | ||||||
|  | 		RegisterMethod: util.RegisterMethodAuthKey, | ||||||
|  | 		AuthKeyID:      ptr.To(key.ID), | ||||||
|  | 	} | ||||||
|  | 	db.DB.Save(&node) | ||||||
|  | 
 | ||||||
|  | 	err = db.DB.Delete(key).Error | ||||||
|  | 	require.ErrorContains(t, err, "constraint failed: FOREIGN KEY constraint failed") | ||||||
|  | } | ||||||
|  | |||||||
| @ -77,9 +77,12 @@ type Node struct { | |||||||
| 
 | 
 | ||||||
| 	ForcedTags []string `gorm:"serializer:json"` | 	ForcedTags []string `gorm:"serializer:json"` | ||||||
| 
 | 
 | ||||||
| 	// TODO(kradalby): This seems like irrelevant information? | 	// When a node has been created with a PreAuthKey, we need to | ||||||
| 	AuthKeyID *uint64     `sql:"DEFAULT:NULL"` | 	// prevent the preauthkey from being deleted before the node. | ||||||
| 	AuthKey   *PreAuthKey `gorm:"constraint:OnDelete:SET NULL;"` | 	// The preauthkey can define "tags" of the node so we need it | ||||||
|  | 	// around. | ||||||
|  | 	AuthKeyID *uint64 `sql:"DEFAULT:NULL"` | ||||||
|  | 	AuthKey   *PreAuthKey | ||||||
| 
 | 
 | ||||||
| 	LastSeen *time.Time | 	LastSeen *time.Time | ||||||
| 	Expiry   *time.Time | 	Expiry   *time.Time | ||||||
|  | |||||||
| @ -14,7 +14,7 @@ type PreAuthKey struct { | |||||||
| 	ID        uint64 `gorm:"primary_key"` | 	ID        uint64 `gorm:"primary_key"` | ||||||
| 	Key       string | 	Key       string | ||||||
| 	UserID    uint | 	UserID    uint | ||||||
| 	User      User `gorm:"constraint:OnDelete:CASCADE;"` | 	User      User `gorm:"constraint:OnDelete:SET NULL;"` | ||||||
| 	Reusable  bool | 	Reusable  bool | ||||||
| 	Ephemeral bool     `gorm:"default:false"` | 	Ephemeral bool     `gorm:"default:false"` | ||||||
| 	Used      bool     `gorm:"default:false"` | 	Used      bool     `gorm:"default:false"` | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user