@@ -182,41 +182,39 @@ func getSessionKey(session *Session) []byte {
182
182
return session .LocalPublicKey .SerializeCompressed ()
183
183
}
184
184
185
- // NewSession creates a new session with the given user-defined parameters.
186
- //
187
- // NOTE: currently this purely a constructor of the Session type and does not
188
- // make any database calls. This will be changed in a future commit.
185
+ // NewSession creates and persists a new session with the given user-defined
186
+ // parameters. The initial state of the session will be Reserved until
187
+ // CreateSession is called.
189
188
//
190
189
// NOTE: this is part of the Store interface.
191
- func (db * BoltStore ) NewSession (id ID , localPrivKey * btcec.PrivateKey ,
192
- label string , typ Type , expiry time.Time , serverAddr string ,
193
- devServer bool , perms []bakery.Op , caveats []macaroon.Caveat ,
194
- featureConfig FeaturesConfig , privacy bool , linkedGroupID * ID ,
195
- flags PrivacyFlags ) (* Session , error ) {
196
-
197
- return buildSession (
198
- id , localPrivKey , label , typ , db .clock .Now (), expiry ,
199
- serverAddr , devServer , perms , caveats , featureConfig , privacy ,
200
- linkedGroupID , flags ,
201
- )
202
- }
190
+ func (db * BoltStore ) NewSession (label string , typ Type , expiry time.Time ,
191
+ serverAddr string , devServer bool , perms []bakery.Op ,
192
+ caveats []macaroon.Caveat , featureConfig FeaturesConfig , privacy bool ,
193
+ linkedGroupID * ID , flags PrivacyFlags ) (* Session , error ) {
203
194
204
- // CreateSession adds a new session to the store. If a session with the same
205
- // local public key already exists an error is returned.
206
- //
207
- // NOTE: this is part of the Store interface.
208
- func (db * BoltStore ) CreateSession (session * Session ) error {
209
- sessionKey := getSessionKey (session )
210
-
211
- return db .Update (func (tx * bbolt.Tx ) error {
195
+ var session * Session
196
+ err := db .Update (func (tx * bbolt.Tx ) error {
212
197
sessionBucket , err := getBucket (tx , sessionBucketKey )
213
198
if err != nil {
214
199
return err
215
200
}
216
201
202
+ id , localPrivKey , err := getUnusedIDAndKeyPair (sessionBucket )
203
+ if err != nil {
204
+ return err
205
+ }
206
+
207
+ session , err = buildSession (
208
+ id , localPrivKey , label , typ , db .clock .Now (), expiry ,
209
+ serverAddr , devServer , perms , caveats , featureConfig ,
210
+ privacy , linkedGroupID , flags ,
211
+ )
212
+
213
+ sessionKey := getSessionKey (session )
214
+
217
215
if len (sessionBucket .Get (sessionKey )) != 0 {
218
- return fmt .Errorf ("session with local public " +
219
- "key(%x) already exists" ,
216
+ return fmt .Errorf ("session with local public key(%x) " +
217
+ "already exists" ,
220
218
session .LocalPublicKey .SerializeCompressed ())
221
219
}
222
220
@@ -275,6 +273,46 @@ func (db *BoltStore) CreateSession(session *Session) error {
275
273
276
274
return putSession (sessionBucket , session )
277
275
})
276
+ if err != nil {
277
+ return nil , err
278
+ }
279
+
280
+ return session , nil
281
+ }
282
+
283
+ // CreateSession moves the session with the given ID from the Reserved state to
284
+ // the Created state.
285
+ //
286
+ // NOTE: this is part of the Store interface.
287
+ func (db * BoltStore ) CreateSession (id ID ) (* Session , error ) {
288
+ var session * Session
289
+ err := db .Update (func (tx * bbolt.Tx ) error {
290
+ sessionBucket , err := getBucket (tx , sessionBucketKey )
291
+ if err != nil {
292
+ return err
293
+ }
294
+
295
+ session , err = getSessionByID (sessionBucket , id )
296
+ if err != nil {
297
+ return err
298
+ }
299
+
300
+ // The session MUST be in the Reserved state.
301
+ if session .State != StateReserved {
302
+ return fmt .Errorf ("session must be in the Reserved " +
303
+ "state for it to move to the Created state" )
304
+ }
305
+
306
+ // Move the session to the CreatedState.
307
+ session .State = StateCreated
308
+
309
+ return putSession (sessionBucket , session )
310
+ })
311
+ if err != nil {
312
+ return nil , err
313
+ }
314
+
315
+ return session , nil
278
316
}
279
317
280
318
// UpdateSessionRemotePubKey can be used to add the given remote pub key
@@ -558,53 +596,35 @@ func (db *BoltStore) GetSessionByID(id ID) (*Session, error) {
558
596
return session , nil
559
597
}
560
598
561
- // GetUnusedIDAndKeyPair can be used to generate a new, unused, local private
599
+ // getUnusedIDAndKeyPair can be used to generate a new, unused, local private
562
600
// key and session ID pair. Care must be taken to ensure that no other thread
563
601
// calls this before the returned ID and key pair from this method are either
564
602
// used or discarded.
565
- //
566
- // NOTE: this is part of the Store interface.
567
- func (db * BoltStore ) GetUnusedIDAndKeyPair () (ID , * btcec.PrivateKey , error ) {
568
- var (
569
- id ID
570
- privKey * btcec.PrivateKey
571
- )
572
- err := db .Update (func (tx * bbolt.Tx ) error {
573
- sessionBucket , err := getBucket (tx , sessionBucketKey )
574
- if err != nil {
575
- return err
576
- }
577
-
578
- idIndexBkt := sessionBucket .Bucket (idIndexKey )
579
- if idIndexBkt == nil {
580
- return ErrDBInitErr
581
- }
603
+ func getUnusedIDAndKeyPair (bucket * bbolt.Bucket ) (ID , * btcec.PrivateKey ,
604
+ error ) {
582
605
583
- // Spin until we find a key with an ID that does not collide
584
- // with any of our existing IDs.
585
- for {
586
- // Generate a new private key and ID pair.
587
- privKey , id , err = NewSessionPrivKeyAndID ()
588
- if err != nil {
589
- return err
590
- }
606
+ idIndexBkt := bucket .Bucket (idIndexKey )
607
+ if idIndexBkt == nil {
608
+ return ID {}, nil , ErrDBInitErr
609
+ }
591
610
592
- // Check that no such ID exits in our id-to-key index.
593
- idBkt := idIndexBkt .Bucket (id [:])
594
- if idBkt != nil {
595
- continue
596
- }
611
+ // Spin until we find a key with an ID that does not collide with any of
612
+ // our existing IDs.
613
+ for {
614
+ // Generate a new private key and ID pair.
615
+ privKey , id , err := NewSessionPrivKeyAndID ()
616
+ if err != nil {
617
+ return ID {}, nil , err
618
+ }
597
619
598
- break
620
+ // Check that no such ID exits in our id-to-key index.
621
+ idBkt := idIndexBkt .Bucket (id [:])
622
+ if idBkt != nil {
623
+ continue
599
624
}
600
625
601
- return nil
602
- })
603
- if err != nil {
604
- return id , nil , err
626
+ return id , privKey , nil
605
627
}
606
-
607
- return id , privKey , nil
608
628
}
609
629
610
630
// GetGroupID will return the group ID for the given session ID.
0 commit comments