// https://github.com/gogs/go-gogs-client/wiki/Users-Emails#add-email-addresses
507944
func AddEmail(c *context.APIContext, form api.CreateEmailOption) {
	if len(form.Emails) == 0 {
		c.Status(422)
		return
	}

	emails := make([]*models.EmailAddress, len(form.Emails))
	for i := range form.Emails {
		emails[i] = &models.EmailAddress{
			UID:         c.User.ID,
			Email:       form.Emails[i],
			IsActivated: !setting.Service.RegisterEmailConfirm,
		}
	}

	if err := models.AddEmailAddresses(emails); err != nil {
		if models.IsErrEmailAlreadyUsed(err) {
			c.Error(422, "", "Email address has been used: "+err.(models.ErrEmailAlreadyUsed).Email)
		} else {
			c.Error(500, "AddEmailAddresses", err)
		}
		return
	}

	apiEmails := make([]*api.Email, len(emails))
	for i := range emails {
		apiEmails[i] = convert.ToEmail(emails[i])
	}
	c.JSON(201, &apiEmails)
}
438988
func (p *peerGroupChanges) updateAddresses() error {
	var err error
	if p.info.haSpace == "" {
		err = p.updateAddressesFromInternal()
	} else {
		err = p.updateAddressesFromSpace()
	}
	return errors.Annotate(err, "updating member addresses")
}
1365518
func (h *SMTPAPIHeader) AddSubstitutions(key string, subs []string) {
	for i := 0; i < len(subs); i++ {
		h.AddSubstitution(key, subs[i])
	}
}
217726
func (c *Client) AddKeys(user string, keys ...string) ([]params.ErrorResult, error) {
	p := params.ModifyUserSSHKeys{User: user, Keys: keys}
	results := new(params.ErrorResults)
	err := c.facade.FacadeCall("AddKeys", p, results)
	return results.Results, err
}
1233576
func (internet Internet) Email(v reflect.Value) (interface{}, error) {
	return internet.email(), nil
}
1218049
func (e *Email) AddRecipients(Recipients ...string) {
	e.To = append(e.To, Recipients...)
}
426177
func (api *Client) GetUserByEmail(email string) (*User, error) {
	return api.GetUserByEmailContext(context.Background(), email)
}
776411
func (api UsersAPI) GetUserAddresses(w http.ResponseWriter, r *http.Request) {
	username := mux.Vars(r)["username"]
	userMgr := user.NewManager(r)

	usr, err := userMgr.GetByName(username)
	if err != nil {
		http.Error(w, http.StatusText(http.StatusNotFound), http.StatusNotFound)
		return
	}

	w.Header().Set("Content-Type", "application/json")
	json.NewEncoder(w).Encode(usr.Addresses)
}
389262
func (a *AddrManager) AddAddresses(addrs []*wire.NetAddress, srcAddr *wire.NetAddress) {
	a.mtx.Lock()
	defer a.mtx.Unlock()

	for _, na := range addrs {
		a.updateAddress(na, srcAddr)
	}
}
618655
func (p *provider) getUserEmail(token string) (string, error) {
	var email string
	err := p.page(p.githubUserEmailURL, token,
		func() interface{} {
			return &[]githubUserEmail{}
		},
		func(obj interface{}) error {
			for _, userEmail := range *(obj.(*[]githubUserEmail)) {
				// store the email regardless of if it the primary in case we somehow never get a primary one
				email = userEmail.Email
				if userEmail.Primary {
					return errStopEmail
				}
			}
			return nil
		},
	)
	// this error just stops iteration early on the first primary email (there should only ever be one primary)
	if err == errStopEmail {
		return email, nil
	}
	return email, err
}
428002
func (u *User) Emails() (interface{}, error) {
	urlStr := GetApiBaseURL() + "/user/emails"
	return u.c.execute("GET", urlStr, "")
}
353555
func EmailsCreate(c web.C, w http.ResponseWriter, r *http.Request) {
	// Decode the request
	var input EmailsCreateRequest
	err := utils.ParseRequest(r, &input)
	if err != nil {
		env.Log.WithFields(logrus.Fields{
			"error": err.Error(),
		}).Warn("Unable to decode a request")

		utils.JSONResponse(w, 400, &EmailsCreateResponse{
			Success: false,
			Message: "Invalid input format",
		})
		return
	}

	// Fetch the current session from the middleware
	session := c.Env["token"].(*models.Token)

	// Ensure that the kind is valid
	if input.Kind != "raw" && input.Kind != "manifest" && input.Kind != "pgpmime" {
		utils.JSONResponse(w, 400, &EmailsCreateResponse{
			Success: false,
			Message: "Invalid email encryption kind",
		})
		return
	}

	// Ensure that there's at least one recipient and that there's body
	if len(input.To) == 0 || input.Body == "" {
		utils.JSONResponse(w, 400, &EmailsCreateResponse{
			Success: false,
			Message: "Invalid email",
		})
		return
	}

	if input.Files != nil && len(input.Files) > 0 {
		// Check rights to files
		files, err := env.Files.GetFiles(input.Files...)
		if err != nil {
			utils.JSONResponse(w, 500, &EmailsCreateResponse{
				Success: false,
				Message: "Unable to fetch emails",
			})
			return
		}
		for _, file := range files {
			if file.Owner != session.Owner {
				utils.JSONResponse(w, 403, &EmailsCreateResponse{
					Success: false,
					Message: "You are not the owner of file " + file.ID,
				})
				return
			}
		}
	}

	// Create an email resource
	resource := models.MakeResource(session.Owner, input.Subject)

	// Generate metadata for manifests
	if input.Kind == "manifest" {
		resource.Name = "Encrypted message (" + resource.ID + ")"
	}

	// Fetch the user object from the database
	account, err := env.Accounts.GetTokenOwner(c.Env["token"].(*models.Token))
	if err != nil {
		// The session refers to a non-existing user
		env.Log.WithFields(logrus.Fields{
			"id":    session.ID,
			"error": err.Error(),
		}).Warn("Valid session referred to a removed account")

		utils.JSONResponse(w, 410, &EmailsCreateResponse{
			Success: false,
			Message: "Account disabled",
		})
		return
	}

	// Get the "Sent" label's ID
	var label *models.Label
	err = env.Labels.WhereAndFetchOne(map[string]interface{}{
		"name":    "Sent",
		"builtin": true,
		"owner":   account.ID,
	}, &label)
	if err != nil {
		env.Log.WithFields(logrus.Fields{
			"id":    account.ID,
			"error": err.Error(),
		}).Warn("Account has no sent label")

		utils.JSONResponse(w, 410, &EmailsCreateResponse{
			Success: false,
			Message: "Misconfigured account",
		})
		return
	}

	if input.From != "" {
		// Parse the from field
		from, err := mail.ParseAddress(input.From)
		if err != nil {
			utils.JSONResponse(w, 400, &EmailsCreateResponse{
				Success: false,
				Message: "Invalid email.From",
			})
			return
		}

		// We have a specified address
		if from.Address != "" {
			parts := strings.SplitN(from.Address, "@", 2)

			if parts[1] != env.Config.EmailDomain {
				utils.JSONResponse(w, 400, &EmailsCreateResponse{
					Success: false,
					Message: "Invalid email.From (invalid domain)",
				})
				return
			}

			address, err := env.Addresses.GetAddress(parts[0])
			if err != nil {
				utils.JSONResponse(w, 400, &EmailsCreateResponse{
					Success: false,
					Message: "Invalid email.From (invalid username)",
				})
				return
			}

			if address.Owner != account.ID {
				utils.JSONResponse(w, 400, &EmailsCreateResponse{
					Success: false,
					Message: "Invalid email.From (address not owned)",
				})
				return
			}
		}
	} else {
		displayName := ""

		if x, ok := account.Settings.(map[string]interface{}); ok {
			if y, ok := x["displayName"]; ok {
				if z, ok := y.(string); ok {
					displayName = z
				}
			}
		}

		addr := &mail.Address{
			Name:    displayName,
			Address: account.StyledName + "@" + env.Config.EmailDomain,
		}

		input.From = addr.String()
	}

	// Check if Thread is set
	if input.Thread != "" {
		// todo: make it an actual exists check to reduce lan bandwidth
		thread, err := env.Threads.GetThread(input.Thread)
		if err != nil {
			env.Log.WithFields(logrus.Fields{
				"id":    input.Thread,
				"error": err.Error(),
			}).Warn("Cannot retrieve a thread")

			utils.JSONResponse(w, 400, &EmailsCreateResponse{
				Success: false,
				Message: "Invalid thread",
			})
			return
		}

		// update thread.secure depending on email's kind
		if (input.Kind == "raw" && thread.Secure == "all") ||
			(input.Kind == "manifest" && thread.Secure == "none") ||
			(input.Kind == "pgpmime" && thread.Secure == "none") {
			if err := env.Threads.UpdateID(thread.ID, map[string]interface{}{
				"secure": "some",
			}); err != nil {
				env.Log.WithFields(logrus.Fields{
					"id":    input.Thread,
					"error": err.Error(),
				}).Warn("Cannot update a thread")

				utils.JSONResponse(w, 400, &EmailsCreateResponse{
					Success: false,
					Message: "Unable to update the thread",
				})
				return
			}
		}
	} else {
		secure := "all"
		if input.Kind == "raw" {
			secure = "none"
		}

		thread := &models.Thread{
			Resource:    models.MakeResource(account.ID, "Encrypted thread"),
			Emails:      []string{resource.ID},
			Labels:      []string{label.ID},
			Members:     append(append(input.To, input.CC...), input.BCC...),
			IsRead:      true,
			SubjectHash: input.SubjectHash,
			Secure:      secure,
		}

		err := env.Threads.Insert(thread)
		if err != nil {
			utils.JSONResponse(w, 500, &EmailsCreateResponse{
				Success: false,
				Message: "Unable to create a new thread",
			})

			env.Log.WithFields(logrus.Fields{
				"error": err.Error(),
			}).Error("Unable to create a new thread")
			return
		}

		input.Thread = thread.ID
	}

	// Calculate the message ID
	idHash := sha256.Sum256([]byte(resource.ID))
	messageID := hex.EncodeToString(idHash[:]) + "@" + env.Config.EmailDomain

	// Create a new email struct
	email := &models.Email{
		Resource:  resource,
		MessageID: messageID,

		Kind:   input.Kind,
		Thread: input.Thread,

		From: input.From,
		To:   input.To,
		CC:   input.CC,
		BCC:  input.BCC,

		PGPFingerprints: input.PGPFingerprints,
		Manifest:        input.Manifest,
		Body:            input.Body,
		Files:           input.Files,

		ContentType: input.ContentType,
		ReplyTo:     input.ReplyTo,

		Status: "queued",
	}

	// Insert the email into the database
	if err := env.Emails.Insert(email); err != nil {
		utils.JSONResponse(w, 500, &EmailsCreateResponse{
			Success: false,
			Message: "internal server error - EM/CR/01",
		})

		env.Log.WithFields(logrus.Fields{
			"error": err.Error(),
		}).Error("Could not insert an email into the database")
		return
	}

	// I'm going to whine at this part, as we are doubling the email sending code

	// Check if To contains lavaboom emails
	/*for _, address := range email.To {
		parts := strings.SplitN(address, "@", 2)
		if parts[1] == env.Config.EmailDomain {
			go sendEmail(parts[0], email)
		}
	}

	// Check if CC contains lavaboom emails
	for _, address := range email.CC {
		parts := strings.SplitN(address, "@", 2)
		if parts[1] == env.Config.EmailDomain {
			go sendEmail(parts[0], email)
		}
	}

	// Check if BCC contains lavaboom emails
	for _, address := range email.BCC {
		parts := strings.SplitN(address, "@", 2)
		if parts[1] == env.Config.EmailDomain {
			go sendEmail(parts[0], email)
		}
	}*/

	// Add a send request to the queue
	err = env.Producer.Publish("send_email", []byte(`"`+email.ID+`"`))
	if err != nil {
		utils.JSONResponse(w, 500, &EmailsCreateResponse{
			Success: false,
			Message: "internal server error - EM/CR/03",
		})

		env.Log.WithFields(logrus.Fields{
			"error": err.Error(),
		}).Error("Could not publish an email send request")
		return
	}

	utils.JSONResponse(w, 201, &EmailsCreateResponse{
		Success: true,
		Created: []string{email.ID},
	})
}
539654
func (c *githubConnector) userOrgs(ctx context.Context, client *http.Client) ([]string, error) {
	groups := make([]string, 0)
	apiURL := c.apiURL + "/user/orgs"
	for {
		// https://developer.github.com/v3/orgs/#list-your-organizations
		var (
			orgs []org
			err  error
		)
		if apiURL, err = get(ctx, client, apiURL, &orgs); err != nil {
			return nil, fmt.Errorf("github: get orgs: %v", err)
		}

		for _, o := range orgs {
			groups = append(groups, o.Login)
		}

		if apiURL == "" {
			break
		}
	}

	return groups, nil
}
428624
func (o *SMTPOptions) AddRecipients(addresses ...string) error {
	if len(addresses) == 0 {
		return errors.New("AddRecipients requires one or more strings that contain comma " +
			"separated email addresses")
	}

	o.mutex.Lock()
	defer o.mutex.Unlock()

	addrs, err := mail.ParseAddressList(strings.Join(addresses, ","))
	if err != nil {
		return err
	}

	o.toAddrs = append(o.toAddrs, addrs...)

	return nil
}
1369332
func (s *FileStorage) MostRecentUserEmail() string {
	userDirs, err := ioutil.ReadDir(s.users())
	if err != nil {
		return ""
	}
	var mostRecent os.FileInfo
	for _, dir := range userDirs {
		if !dir.IsDir() {
			continue
		}
		if mostRecent == nil || dir.ModTime().After(mostRecent.ModTime()) {
			mostRecent = dir
		}
	}
	if mostRecent != nil {
		return mostRecent.Name()
	}
	return ""
}
199145
func (s *UsersService) ListEmails(ctx context.Context, opt *ListOptions) ([]*UserEmail, *Response, error) {
	u := "user/emails"
	u, err := addOptions(u, opt)
	if err != nil {
		return nil, nil, err
	}

	req, err := s.client.NewRequest("GET", u, nil)
	if err != nil {
		return nil, nil, err
	}

	var emails []*UserEmail
	resp, err := s.client.Do(ctx, req, &emails)
	if err != nil {
		return nil, resp, err
	}

	return emails, resp, nil
}
829680
func (r *rest) PutEmail(c *gin.Context) {
	var reqDTO RequestDTOPutEmail
	if err := c.BindJSON(&reqDTO); err != nil {
		c.JSON(apihelper.BuildRequestError(err))
	} else {
		if resDTO, err := r.service.EditEmail(reqDTO); err != nil {
			c.JSON(apihelper.BuildResponseError(err))
		} else {
			c.JSON(http.StatusOK, resDTO)
		}
	}
}