User requests or updates a self-subscription to a topic h - hub sess - originating session pktId - originating packet Id want - requested access mode info - explanation info given by the requester private - private value to assign to the subscription Handle these cases: A. User is trying t
(h *Hub, sess *Session, pktId string, want string, info, private interface{})
| 383 | // C. User is already subscribed, changing modeWant |
| 384 | // D. User is accepting ownership transfer (requesting ownership transfer is not permitted) |
| 385 | func (t *Topic) requestSub(h *Hub, sess *Session, pktId string, want string, info, private interface{}) error { |
| 386 | log.Println("requestSub", t.name) |
| 387 | |
| 388 | now := time.Now().UTC().Round(time.Millisecond) |
| 389 | |
| 390 | // Parse the acess mode requested by the user |
| 391 | var modeWant types.AccessMode |
| 392 | if want != "" { |
| 393 | modeWant.UnmarshalText([]byte(want)) |
| 394 | } |
| 395 | |
| 396 | // Vars for saving changes to access mode |
| 397 | var updWant *types.AccessMode |
| 398 | var updGiven *types.AccessMode |
| 399 | |
| 400 | // Check if it's an attempt at a new subscription to the topic. If so, save it to database |
| 401 | userData, ok := t.perUser[sess.uid] |
| 402 | if !ok { |
| 403 | // User requested default access mode. |
| 404 | // modeWant could still be ModeNone if the owner wants to manually approve every request |
| 405 | if modeWant == types.ModeNone { |
| 406 | modeWant = t.accessAuth |
| 407 | } |
| 408 | |
| 409 | userData = perUserData{ |
| 410 | private: private, |
| 411 | modeGiven: t.accessAuth, |
| 412 | modeWant: modeWant, |
| 413 | lastSeenTag: make(map[string]time.Time), |
| 414 | } |
| 415 | |
| 416 | // Add subscription to database |
| 417 | sub := types.Subscription{ |
| 418 | User: sess.uid.String(), |
| 419 | Topic: t.name, |
| 420 | ModeWant: userData.modeWant, |
| 421 | ModeGiven: userData.modeGiven, |
| 422 | LastSeen: userData.lastSeenTag, |
| 423 | Private: userData.private, |
| 424 | } |
| 425 | |
| 426 | if err := store.Subs.Create(t.appid, &sub); err != nil { |
| 427 | log.Println(err.Error()) |
| 428 | simpleByteSender(sess.send, ErrUnknown(pktId, t.original, now)) |
| 429 | return err |
| 430 | } |
| 431 | |
| 432 | } else { |
| 433 | // If user did not request a new access mode, copy one from cache |
| 434 | if modeWant == types.ModeNone { |
| 435 | modeWant = userData.modeWant |
| 436 | } |
| 437 | |
| 438 | // Make sure the owner cannot unset the owner flag |
| 439 | if t.owner == sess.uid && (modeWant&types.ModeOwner == 0 || modeWant.IsBanned()) { |
| 440 | log.Println("requestSub: owner attempts to unset the owner flag") |
| 441 | simpleByteSender(sess.send, ErrMalformed(pktId, t.original, now)) |
| 442 | return errors.New("cannot unset ownership or ban the owner") |
no test coverage detected