// Examples of postmark inbound messages // [email protected] // [email protected] func (m *Mail) Persist() error { accountId, err := m.getSocialIdFromEmail() if err != nil { return err } if strings.HasPrefix(m.OriginalRecipient, "post") { err := m.persistPost(accountId) if err != nil && err != errCannotOpen { return err } if err == errCannotOpen { runner.MustGetLogger().Error("possible abuse mail: %+v", m) } return nil } if strings.HasPrefix(m.OriginalRecipient, "reply") { err := m.persistReply(accountId) if err != nil && err != errCannotOpen { return err } return nil } return errInvalidMailPrefix }
// NewBadRequest is creating a new http response with predifined // http response properties func NewBadRequest(err error) (int, http.Header, interface{}, error) { l := runner.MustGetLogger() l = l.New("response") l.SetCallDepth(2) // get previous error line return NewBadRequestWithLogger(l, err) }
// getAccount tries to retrieve account information from incoming request, // should always return a valid account, not nil func getAccount(r *http.Request, groupName string) *models.Account { clientID := getClientID(r) // if cookie doenst exists return empty account if clientID == "" { return models.NewAccount() } session, err := models.Cache.Session.ById(clientID) if err != nil { return models.NewAccount() } // if session doesnt have username, return empty account if session.Username == "" { return models.NewAccount() } acc, err := makeSureAccount(groupName, session.Username) if err != nil { if err != bongo.RecordNotFound && err != mgo.ErrNotFound { runner.MustGetLogger().Error("Err while getting account: %s, err :%s", session.Username, err.Error()) } return models.NewAccount() } groupChannel, err := models.Cache.Channel.ByGroupName(groupName) if err != nil { if err != bongo.RecordNotFound && err != models.ErrGroupNotFound { runner.MustGetLogger().Error("Err while getting group channel: %s, err :%s", groupName, err.Error()) return models.NewAccount() } // for creating the group channel for the first time, we should not return // here with empty account return acc } if err := makeSureMembership(groupChannel, acc.Id); err != nil { runner.MustGetLogger().Error("Err while making sure account: %s, err :%s", groupName, err.Error()) return models.NewAccount() } return acc }
// NewAccessDenied sends access denied response back to client // // here not to leak info about the resource do send NotFound err func NewAccessDenied(err error) (int, http.Header, interface{}, error) { l := runner.MustGetLogger() l = l.New("response") l.SetCallDepth(1) // get previous error line l.Error("Access Denied Err: %s", err.Error()) return NewNotFound() }
func RemoveMulti(u *url.URL, h http.Header, participants []*models.ChannelParticipant, context *models.Context) (int, http.Header, interface{}, error) { query := context.OverrideQuery(request.GetQuery(u)) if err := checkChannelPrerequisites( query.Id, query.AccountId, participants, ); err != nil { return response.NewBadRequest(err) } ch := models.NewChannel() err := ch.ById(query.Id) if err != nil { return response.NewBadRequest(err) } if ch.TypeConstant == models.Channel_TYPE_BOT { return response.NewBadRequest(errors.New("can not remove participants for bot channel")) } isAdmin, err := modelhelper.IsAdmin(context.Client.Account.Nick, context.GroupName) if err != nil { return response.NewBadRequest(err) } for i := range participants { // if the requester is trying to remove some other user than themselves, and they are not the channel owner // return bad request if participants[i].AccountId != query.AccountId && query.AccountId != ch.CreatorId { if !isAdmin { return response.NewBadRequest(fmt.Errorf("User is not allowed to kick other users")) } } participants[i].ChannelId = query.Id if err := participants[i].Delete(); err != nil { return response.NewBadRequest(err) } if err := addLeaveActivity(query.Id, query.AccountId, participants[i]); err != nil { return response.NewBadRequest(err) } } // this could be moved into another worker, but i did not want to create a new worker that will be used // for just a few times go func() { if err := DeleteDesertedChannelMessages(query.Id); err != nil { runner.MustGetLogger().Error("Could not delete channel messages: %s", err.Error()) } }() go notifyParticipants(ch, models.ChannelParticipant_Removed_From_Channel_Event, participants) return response.NewOK(participants) }
func NewController(rmqConn *rabbitmq.RabbitMQ, pubnub *models.PubNub, broker *models.Broker) *Controller { return &Controller{ Pubnub: pubnub, Broker: broker, logger: runner.MustGetLogger(), rmqConn: rmqConn.Conn(), } }
// NewInvalidRequest sends bad request response back to client. // Unlike NewBadRequest method, errors are exposed to users. // For this reason it is used for returning input validation errors func NewInvalidRequest(err error) (int, http.Header, interface{}, error) { if err == nil { err = errors.New("request is not valid") } // make sure errors are outputted runner.MustGetLogger().Error("Invalid Request: %s", err) return http.StatusBadRequest, nil, nil, BadRequest{err} }
func decorateContainers(containers []*models.ChannelMessageContainer, messages []models.ChannelMessage, accountId int64) { log := runner.MustGetLogger() var err error for i, message := range messages { d := models.NewChannelMessage() *d = message containers[i], err = d.BuildEmptyMessageContainer() if err != nil { log.Error("Could not create message container for message %d: %s", containers[i].Message.Id, err) continue } } }
func Parse(u *url.URL, h http.Header, req *models.Mail) (int, http.Header, interface{}, error) { if err := req.Validate(); err != nil { runner.MustGetLogger().Error("mail parse validate err : %S", err.Error()) // faily silently, we dont want mail parser service to retry on // the failed validation return response.NewDefaultOK() } if err := req.Persist(); err != nil { return response.NewBadRequest(err) } return response.NewDefaultOK() }
// HandleResultAndError wraps the function calls and get its reponse, // assuming the second parameter as error checks it if it is null or not // if err nor found, returns OK response func HandleResultAndError(res interface{}, err error) (int, http.Header, interface{}, error) { if err == bongo.RecordNotFound { return NewNotFound() } l := runner.MustGetLogger() l = l.New("response") l.SetCallDepth(2) // get 2 previous call stack if err != nil { return NewBadRequestWithLogger(l, err) } return NewOK(res) }
func parseLocation(c *models.Context) *string { record, err := helper.MustGetGeoIPDB().City(c.Client.IP) if err != nil { runner.MustGetLogger().Error("Err while parsing ip, err :%s", err.Error()) } else { city := record.City.Names["en"] country := record.Country.Names["en"] if city != "" { location := fmt.Sprintf("%s, %s", city, country) return &location } else { location := fmt.Sprintf("%s", country) return &location } } return nil }
func notifyParticipants(channel *models.Channel, event string, participants []*models.ChannelParticipant) { pe := models.NewParticipantEvent() pe.Id = channel.Id pe.Participants = participants pe.ChannelToken = channel.Token logger := runner.MustGetLogger() for _, participant := range participants { acc, err := models.Cache.Account.ById(participant.AccountId) if err != nil { logger.Error("Could not fetch account: %s", err) } pe.Tokens = append(pe.Tokens, acc.Token) } if err := bongo.B.PublishEvent(event, pe); err != nil { logger.Error("Could not notify channel participants: %s", err.Error()) } }
Type string Name string CollectMetrics bool Metrics *kmetrics.Metrics // used for external requests Params map[string]string Cookie string Cookies []*http.Cookie Body interface{} Headers map[string]string Ratelimit *throttled.HTTPRateLimiter } var throttleErrorHandler = func(w http.ResponseWriter, r *http.Request, err error) { runner.MustGetLogger().Error("Throttling error: %s", err) writeJSONError(w, errGeneric) } var throttleDenyHandler = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { writeJSONError(w, response.LimitRateExceededError{}) }) // getAccount tries to retrieve account information from incoming request, // should always return a valid account, not nil func getAccount(r *http.Request, groupName string) *models.Account { clientID := getClientID(r) // if cookie doenst exists return empty account if clientID == "" {