Просмотр исходного кода

upser user at login time; fixes missing away message for users w/o profile

Mike 3 лет назад
Родитель
Сommit
aed9e4b8fb
4 измененных файлов с 39 добавлено и 8 удалено
  1. 3 3
      cmd/main.go
  2. 5 1
      oscar/bucp.go
  3. 17 3
      oscar/feedbag_store.go
  4. 14 1
      oscar/feedbag_store_test.go

+ 3 - 3
cmd/main.go

@@ -39,7 +39,7 @@ func main() {
 		}
 
 		// Handle connection in a separate goroutine
-		go handleAuthConnection(sm, conn)
+		go handleAuthConnection(sm, fm, conn)
 	}
 }
 
@@ -79,7 +79,7 @@ func listenBOS(sm *oscar.SessionManager, fm *oscar.FeedbagStore) {
 	}
 }
 
-func handleAuthConnection(sm *oscar.SessionManager, conn net.Conn) {
+func handleAuthConnection(sm *oscar.SessionManager, fm *oscar.FeedbagStore, conn net.Conn) {
 	defer conn.Close()
 	seq := uint32(100)
 	_, err := oscar.SendAndReceiveSignonFrame(conn, &seq)
@@ -99,7 +99,7 @@ func handleAuthConnection(sm *oscar.SessionManager, conn net.Conn) {
 		return
 	}
 
-	err = oscar.ReceiveAndSendBUCPLoginRequest(sess, conn, conn, &seq)
+	err = oscar.ReceiveAndSendBUCPLoginRequest(sess, fm, conn, conn, &seq)
 	if err != nil {
 		log.Println(err)
 		return

+ 5 - 1
oscar/bucp.go

@@ -124,7 +124,7 @@ func (s *snacBUCPLoginRequest) read(r io.Reader) error {
 	})
 }
 
-func ReceiveAndSendBUCPLoginRequest(sess *Session, r io.Reader, w io.Writer, sequence *uint32) error {
+func ReceiveAndSendBUCPLoginRequest(sess *Session, fm *FeedbagStore, r io.Reader, w io.Writer, sequence *uint32) error {
 	flap := &flapFrame{}
 	if err := flap.read(r); err != nil {
 		return err
@@ -154,6 +154,10 @@ func ReceiveAndSendBUCPLoginRequest(sess *Session, r io.Reader, w io.Writer, seq
 		return errors.New("unable to find screen name")
 	}
 
+	if err := fm.UpsertUser(sess.ScreenName); err != nil {
+		return err
+	}
+
 	snacFrameOut := snacFrame{
 		foodGroup: 0x17,
 		subGroup:  0x03,

+ 17 - 3
oscar/feedbag_store.go

@@ -51,6 +51,16 @@ type FeedbagStore struct {
 	db *sql.DB
 }
 
+func (f *FeedbagStore) UpsertUser(screenName string) error {
+	q := `
+		INSERT INTO user (ScreenName)
+		VALUES (?)
+		ON CONFLICT DO NOTHING
+	`
+	_, err := f.db.Exec(q, screenName)
+	return err
+}
+
 func (f *FeedbagStore) Delete(screenName string, items []*feedbagItem) error {
 	// todo add transaction
 	q := `DELETE FROM feedbag WHERE ScreenName = ? AND itemID = ?`
@@ -222,11 +232,15 @@ func (f *FeedbagStore) Buddies(screenName string) ([]string, error) {
 	return items, nil
 }
 
+// RetrieveProfile fetches a user profile. Return empty string if the user
+// exists but has no profile. Return errUserNotExist if the user does not
+// exist.
 func (f *FeedbagStore) RetrieveProfile(screenName string) (string, error) {
 	q := `
-		SELECT body
-		FROM profile
-		WHERE ScreenName = ?
+		SELECT IFNULL(body, '')
+		FROM user u
+		LEFT JOIN profile p ON p.ScreenName = u.ScreenName
+		WHERE u.ScreenName = ?
 	`
 	var profile string
 	err := f.db.QueryRow(q, screenName).Scan(&profile)

+ 14 - 1
oscar/feedbag_store_test.go

@@ -202,12 +202,25 @@ func TestProfile(t *testing.T) {
 		t.Fatalf("failed to create new feedbag store: %s", err.Error())
 	}
 
+	if err := f.UpsertUser(screenName); err != nil {
+		t.Fatalf("failed to upsert new user: %s", err.Error())
+	}
+
+	profile, err := f.RetrieveProfile(screenName)
+	if err != nil {
+		t.Fatalf("failed to retrieve profile: %s", err.Error())
+	}
+
+	if profile != "" {
+		t.Fatalf("expected empty profile for %s", screenName)
+	}
+
 	newProfile := "here is my profile"
 	if err := f.UpsertProfile(screenName, newProfile); err != nil {
 		t.Fatalf("failed to create new profile: %s", err.Error())
 	}
 
-	profile, err := f.RetrieveProfile(screenName)
+	profile, err = f.RetrieveProfile(screenName)
 	if err != nil {
 		t.Fatalf("failed to retrieve profile: %s", err.Error())
 	}