@@ -182,41 +182,42 @@ 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.
189
- //
190
- // 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
- }
203
-
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.
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.
206
188
//
207
189
// NOTE: this is part of the Store interface.
208
- func (db * BoltStore ) CreateSession (session * Session ) error {
209
- sessionKey := getSessionKey (session )
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 ) {
210
194
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
+ if err != nil {
213
+ return err
214
+ }
215
+
216
+ sessionKey := getSessionKey (session )
217
+
217
218
if len (sessionBucket .Get (sessionKey )) != 0 {
218
- return fmt .Errorf ("session with local public " +
219
- "key(%x) already exists" ,
219
+ return fmt .Errorf ("session with local public key(%x) " +
220
+ "already exists" ,
220
221
session .LocalPublicKey .SerializeCompressed ())
221
222
}
222
223
@@ -275,6 +276,46 @@ func (db *BoltStore) CreateSession(session *Session) error {
275
276
276
277
return putSession (sessionBucket , session )
277
278
})
279
+ if err != nil {
280
+ return nil , err
281
+ }
282
+
283
+ return session , nil
284
+ }
285
+
286
+ // CreateSession moves the session with the given ID from the Reserved state to
287
+ // the Created state.
288
+ //
289
+ // NOTE: this is part of the Store interface.
290
+ func (db * BoltStore ) CreateSession (id ID ) (* Session , error ) {
291
+ var session * Session
292
+ err := db .Update (func (tx * bbolt.Tx ) error {
293
+ sessionBucket , err := getBucket (tx , sessionBucketKey )
294
+ if err != nil {
295
+ return err
296
+ }
297
+
298
+ session , err = getSessionByID (sessionBucket , id )
299
+ if err != nil {
300
+ return err
301
+ }
302
+
303
+ // The session MUST be in the Reserved state.
304
+ if session .State != StateReserved {
305
+ return fmt .Errorf ("session must be in the Reserved " +
306
+ "state for it to move to the Created state" )
307
+ }
308
+
309
+ // Move the session to the CreatedState.
310
+ session .State = StateCreated
311
+
312
+ return putSession (sessionBucket , session )
313
+ })
314
+ if err != nil {
315
+ return nil , err
316
+ }
317
+
318
+ return session , nil
278
319
}
279
320
280
321
// UpdateSessionRemotePubKey can be used to add the given remote pub key
@@ -565,53 +606,35 @@ func (db *BoltStore) GetSessionByID(id ID) (*Session, error) {
565
606
return session , nil
566
607
}
567
608
568
- // GetUnusedIDAndKeyPair can be used to generate a new, unused, local private
609
+ // getUnusedIDAndKeyPair can be used to generate a new, unused, local private
569
610
// key and session ID pair. Care must be taken to ensure that no other thread
570
611
// calls this before the returned ID and key pair from this method are either
571
612
// used or discarded.
572
- //
573
- // NOTE: this is part of the Store interface.
574
- func (db * BoltStore ) GetUnusedIDAndKeyPair () (ID , * btcec.PrivateKey , error ) {
575
- var (
576
- id ID
577
- privKey * btcec.PrivateKey
578
- )
579
- err := db .Update (func (tx * bbolt.Tx ) error {
580
- sessionBucket , err := getBucket (tx , sessionBucketKey )
581
- if err != nil {
582
- return err
583
- }
584
-
585
- idIndexBkt := sessionBucket .Bucket (idIndexKey )
586
- if idIndexBkt == nil {
587
- return ErrDBInitErr
588
- }
613
+ func getUnusedIDAndKeyPair (bucket * bbolt.Bucket ) (ID , * btcec.PrivateKey ,
614
+ error ) {
589
615
590
- // Spin until we find a key with an ID that does not collide
591
- // with any of our existing IDs.
592
- for {
593
- // Generate a new private key and ID pair.
594
- privKey , id , err = NewSessionPrivKeyAndID ()
595
- if err != nil {
596
- return err
597
- }
616
+ idIndexBkt := bucket .Bucket (idIndexKey )
617
+ if idIndexBkt == nil {
618
+ return ID {}, nil , ErrDBInitErr
619
+ }
598
620
599
- // Check that no such ID exits in our id-to-key index.
600
- idBkt := idIndexBkt .Bucket (id [:])
601
- if idBkt != nil {
602
- continue
603
- }
621
+ // Spin until we find a key with an ID that does not collide with any of
622
+ // our existing IDs.
623
+ for {
624
+ // Generate a new private key and ID pair.
625
+ privKey , id , err := NewSessionPrivKeyAndID ()
626
+ if err != nil {
627
+ return ID {}, nil , err
628
+ }
604
629
605
- break
630
+ // Check that no such ID exits in our id-to-key index.
631
+ idBkt := idIndexBkt .Bucket (id [:])
632
+ if idBkt != nil {
633
+ continue
606
634
}
607
635
608
- return nil
609
- })
610
- if err != nil {
611
- return id , nil , err
636
+ return id , privKey , nil
612
637
}
613
-
614
- return id , privKey , nil
615
638
}
616
639
617
640
// GetGroupID will return the group ID for the given session ID.
0 commit comments