func (d dirGroups) Subentity(name string, req he.Request) he.Entity { db := req.Things["db"].(*periwinkle.Tx) sess := req.Things["session"].(*backend.Session) grp := backend.GetGroupByID(db, name) if grp.ReadPublic == 1 { subscribed := backend.IsSubscribed(db, sess.UserID, *grp) if (grp.ReadConfirmed == 1 && subscribed == 1) || subscribed == 0 { return nil } } return (*group)(grp) }
func HandleEmail(r io.Reader, name string, db *periwinkle.Tx, cfg *periwinkle.Cfg) postfixpipe.ExitStatus { mdWriter := cfg.Mailstore.NewMail() if mdWriter == nil { periwinkle.Logf("Could not open maildir for writing: %q\n", cfg.Mailstore) return postfixpipe.EX_IOERR } // As we read the message, also write it to the maildir defer func() { if mdWriter != nil { mdWriter.Cancel() } }() r = io.TeeReader(r, mdWriter) // Read the message msg, err := mail.ReadMessage(r) if err != nil { return postfixpipe.EX_NOINPUT } // Figure out which group it was to group := backend.GetGroupByID(db, name) if group == nil { return postfixpipe.EX_NOUSER } // Figure out who sent it //user_email := msg.Header.Get("From") //user := backend.GetUserByAddress(db, "email", user_email) // check permissions //if user == nil || !CanPost(db, group, user.ID) { // return postfixpipe.EX_NOPERM //} // Add it to the database backend.NewMessage( db, msg.Header.Get("Message-Id"), *group, mdWriter.Unique()) mdWriter.Close() mdWriter = nil // Generate the list of who we're sending it to var forwardAry []string { // collect IDs of addresses subscribed to the group addressIDs := make([]int64, len(group.Subscriptions)) for i := range group.Subscriptions { addressIDs[i] = group.Subscriptions[i].AddressID } // fetch all of those addresses var addressList []backend.UserAddress if len(addressIDs) > 0 { db.Where("id IN (?)", addressIDs).Find(&addressList) } else { addressList = make([]backend.UserAddress, 0) } // convert that list into a set forwardSet := make(map[string]bool, len(addressList)) for _, addr := range addressList { if addr.Medium != "noop" && addr.Medium != "admin" { forwardSet[addr.AsEmailAddress()] = true } } // prune addresses that (should) already have the message for _, header := range []string{"To", "From", "Cc"} { addresses, err := msg.Header.AddressList(header) if err != nil { periwinkle.Logf("Parsing %q Header: %v\n", header, err) } for _, addr := range addresses { delete(forwardSet, addr.Address) } } // TODO: also prune addresses that belong to user. // convert the set into an array forwardAry = make([]string, len(forwardSet)) i := uint(0) for addr := range forwardSet { forwardAry[i] = addr i++ } } periwinkle.Logf("Forwarding message to group %q to user addresses %#v", group.ID, forwardAry) // format the message msg822 := []byte{} for k := range msg.Header { msg822 = append(msg822, []byte(fmt.Sprintf("%s: %s\r\n", k, msg.Header.Get(k)))...) } msg822 = append(msg822, []byte("\r\n")...) body, _ := ioutil.ReadAll(msg.Body) // TODO: error handling msg822 = append(msg822, body...) if len(forwardAry) > 0 { // send the message out err = smtp.SendMail("localhost:25", smtp.PlainAuth("", "", "", ""), msg.Header.Get("From"), forwardAry, msg822) if err != nil { periwinkle.Logf("Error sending: %v", err) return postfixpipe.EX_UNAVAILABLE } } return postfixpipe.EX_OK }