示例#1
0
func StoreCredWithAuthor(cred *credence.Cred, author models.User) (bool, string) {
	credBytes, _ := proto.Marshal(cred)

	db := models.DB()
	var credRecord models.CredRecord
	credHash := CredHash(cred)

	db.FirstOrInit(&credRecord, models.CredRecord{CredHash: credHash})
	newCred := db.NewRecord(credRecord)

	if newCred {
		credRecord.Author = author
		credRecord.StatementHash = StatementHash(cred)
		credRecord.CredBytes = credBytes
		credRecord.SourceUri = cred.SourceUri
		credRecord.ReceivedAt = time.Now()

		credRecord.NoComment = cred.Assertion == credence.Cred_NO_COMMENT
		credRecord.IsTrue = cred.Assertion == credence.Cred_IS_TRUE
		credRecord.IsFalse = cred.Assertion == credence.Cred_IS_FALSE
		credRecord.IsAmbiguous = cred.Assertion == credence.Cred_IS_AMBIGUOUS

		db.Save(&credRecord)
	}

	return newCred, credHash
}
示例#2
0
func StatementAlreadyMade(cred *credence.Cred, user models.User) bool {
	db := models.DB()
	var credRecord models.CredRecord
	db.First(&credRecord, models.CredRecord{
		StatementHash: StatementHash(cred),
		AuthorID:      user.ID,
	})
	return !db.NewRecord(credRecord)
}
示例#3
0
func StartBroadcaster(wg sync.WaitGroup) {
	defer wg.Done()

	db := models.DB()

	msgBytes := make([]byte, 524288) // 0.5 Mb

	for {
		_, err := receiver.Read(msgBytes)
		if err != nil {
			log.Print(err)
			continue
		}

		hash, err := openssl.SHA1(msgBytes)
		if err != nil {
			panic(err)
		}

		messageHash := hex.EncodeToString(hash[:])
		log.Println("Checking message", messageHash)

		var previouslySent models.SentMessage
		db.Where("message_hash = ? AND sent_at > ?", messageHash, time.Now().Add(-5*time.Minute)).First(&previouslySent)

		if db.NewRecord(previouslySent.MessageHash) {
			log.Println("Broadcasting message", messageHash)

			_, err = broadcaster.Write(msgBytes)
			if err != nil {
				panic(err)
			}

			log.Println("Pitching message", messageHash)

			_, err = pitcher.Write(msgBytes)
			if err != nil {
				panic(err)
			}

			previouslySent.SentAt = time.Now()
			previouslySent.MessageHash = messageHash
			db.Save(&previouslySent)
		} else {
			log.Println("Message already sent recently", messageHash)
		}
	}
}
示例#4
0
func ConnectToPeers(broadcatchers bool, callback func(string) error) {
	db := models.DB()
	peers, _ := db.Model(models.Peer{}).Rows()

	for peers.Next() {
		var (
			peerUri        string
			isBroadcatcher bool
		)
		peers.Scan(&peerUri, &isBroadcatcher)
		if broadcatchers == isBroadcatcher {
			// TODO: Catch error
			_ = callback(peerUri)
		}
	}
}
示例#5
0
func SavePublicKeyToDB(privateKey openssl.PrivateKey) {
	publicDerBlock, err := privateKey.MarshalPKIXPublicKeyDER()
	if err != nil {
		panic(err)
	}

	fingerprint, err := openssl.SHA256(publicDerBlock)
	if err != nil {
		panic(err)
	}

	me := models.Me()
	me.PublicKey = publicDerBlock
	me.Fingerprint = fingerprint[:]
	db := models.DB()
	db.Save(&me)
	log.Print("Stored self public key in user DB")
}
示例#6
0
// TODO: Allow addition of broadcatchers too
func ConnectHandler(w http.ResponseWriter, r *http.Request) {
	switch r.Method {
	case "POST":
		uris := r.URL.Query()["uri"]

		for _, uri := range uris {
			err := receive.ConnectToBroadcaster(uri)
			if err == nil {
				db := models.DB()
				db.FirstOrCreate(new(models.Peer), models.Peer{Server: uri, IsBroadcatcher: false})
			} else {
				w.WriteHeader(http.StatusBadRequest)
				return
			}
		}

		w.WriteHeader(http.StatusOK)
	default:
		w.WriteHeader(http.StatusMethodNotAllowed)
	}
}
示例#7
0
func UserDetailHandler(w http.ResponseWriter, r *http.Request) {
	// TODO: This is a hack, need proper routing
	userParam := r.URL.Path[7:]

	userId, err := strconv.ParseUint(userParam, 10, 64)
	if err != nil {
		w.WriteHeader(http.StatusBadRequest)
		return
	}
	db := models.DB()

	user := &models.User{}
	db.Where(&models.User{ID: uint(userId)}).First(user)
	if db.NewRecord(user) {
		w.WriteHeader(http.StatusNotFound)
		return
	}

	identityAssertion := helpers.AssertIdentity(user)
	helpers.ModelNegotiator().Negotiate(w, r, identityAssertion)
}
示例#8
0
// Returns the author of the cred, if it can be determined.
// Will return an error if the public key for the author_fingerprint
// doesn't match the signature.
func DetectAuthor(cred *credence.Cred) (models.User, error) {
	author := models.User{}
	db := models.DB()

	if cred.AuthorFingerprint == nil {
		users := []models.User{}
		db.Where("public_key IS NOT NULL").Find(&users)

		sigCredByte := SignableCredBytes(cred)

		for _, user := range users {
			publicKey, err := openssl.LoadPublicKeyFromPEM(user.PublicKey)
			if err == nil {
				verifyErr := publicKey.VerifyPKCS1v15(openssl.SHA256_Method, sigCredByte, cred.Signature)
				if verifyErr == nil {
					author = user
					break
				}
			}
		}
	} else {
		db.Where("fingerprint = ?", hex.EncodeToString(cred.AuthorFingerprint)).First(&author)

		if !db.NewRecord(author) {
			sigCredByte := SignableCredBytes(cred)
			publicKey, err := openssl.LoadPublicKeyFromPEM(author.PublicKey)
			if err == nil {
				verifyErr := publicKey.VerifyPKCS1v15(openssl.SHA256_Method, sigCredByte, cred.Signature)
				if verifyErr != nil {
					return models.User{}, verifyErr
				}
			}
			// TODO: What if we can't load the public key?
		}
	}

	return author, nil
}
示例#9
0
func CredRecordFromCredHash(credHash string) (models.CredRecord, bool) {
	db := models.DB()
	credRecord := &models.CredRecord{}
	db.Where("cred_hash = ?", credHash).Preload("Author").First(credRecord)
	return *credRecord, !db.NewRecord(credRecord)
}