Beispiel #1
0
func cmdResetPassword() {
	if flagCmdResetPassword {
		if len(flagEmail) == 0 {
			fmt.Fprintln(os.Stderr, "flag needs an argument: -email")
			os.Exit(1)
		}

		if len(flagPassword) == 0 {
			fmt.Fprintln(os.Stderr, "flag needs an argument: -password")
			os.Exit(1)
		}

		if len(flagPassword) < 5 {
			fmt.Fprintln(os.Stderr, "flag invalid argument needs to be more than 4 characters: -password")
			os.Exit(1)
		}

		var user *model.User
		if result := <-app.Srv.Store.User().GetByEmail(flagEmail); result.Err != nil {
			l4g.Error("%v", result.Err)
			flushLogAndExit(1)
		} else {
			user = result.Data.(*model.User)
		}

		if result := <-app.Srv.Store.User().UpdatePassword(user.Id, model.HashPassword(flagPassword)); result.Err != nil {
			l4g.Error("%v", result.Err)
			flushLogAndExit(1)
		}

		os.Exit(0)
	}
}
Beispiel #2
0
func signupTeam(c *Context, w http.ResponseWriter, r *http.Request) {

	m := model.MapFromJson(r.Body)
	email := strings.ToLower(strings.TrimSpace(m["email"]))

	if len(email) == 0 {
		c.SetInvalidParam("signupTeam", "email")
		return
	}

	subjectPage := NewServerTemplatePage("signup_team_subject", c.GetSiteURL())
	bodyPage := NewServerTemplatePage("signup_team_body", c.GetSiteURL())
	bodyPage.Props["TourUrl"] = utils.Cfg.TeamSettings.TourLink

	props := make(map[string]string)
	props["email"] = email
	props["time"] = fmt.Sprintf("%v", model.GetMillis())

	data := model.MapToJson(props)
	hash := model.HashPassword(fmt.Sprintf("%v:%v", data, utils.Cfg.ServiceSettings.InviteSalt))

	bodyPage.Props["Link"] = fmt.Sprintf("%s/signup_team_complete/?d=%s&h=%s", c.GetSiteURL(), url.QueryEscape(data), url.QueryEscape(hash))

	if err := utils.SendMail(email, subjectPage.Render(), bodyPage.Render()); err != nil {
		c.Err = err
		return
	}

	if utils.Cfg.ServiceSettings.Mode == utils.MODE_DEV || utils.Cfg.EmailSettings.ByPassEmail {
		m["follow_link"] = bodyPage.Props["Link"]
	}

	w.Header().Set("Access-Control-Allow-Origin", " *")
	w.Write([]byte(model.MapToJson(m)))
}
Beispiel #3
0
func sendPasswordReset(c *Context, w http.ResponseWriter, r *http.Request) {
	props := model.MapFromJson(r.Body)

	email := props["email"]
	if len(email) == 0 {
		c.SetInvalidParam("sendPasswordReset", "email")
		return
	}

	name := props["name"]
	if len(name) == 0 {
		c.SetInvalidParam("sendPasswordReset", "name")
		return
	}

	var team *model.Team
	if result := <-Srv.Store.Team().GetByName(name); result.Err != nil {
		c.Err = result.Err
		return
	} else {
		team = result.Data.(*model.Team)
	}

	var user *model.User
	if result := <-Srv.Store.User().GetByEmail(team.Id, email); result.Err != nil {
		c.Err = model.NewAppError("sendPasswordReset", "We couldn’t find an account with that address.", "email="+email+" team_id="+team.Id)
		return
	} else {
		user = result.Data.(*model.User)
	}

	if len(user.AuthData) != 0 {
		c.Err = model.NewAppError("sendPasswordReset", "Cannot reset password for SSO accounts", "userId="+user.Id+", teamId="+team.Id)
		return
	}

	newProps := make(map[string]string)
	newProps["user_id"] = user.Id
	newProps["time"] = fmt.Sprintf("%v", model.GetMillis())

	data := model.MapToJson(newProps)
	hash := model.HashPassword(fmt.Sprintf("%v:%v", data, utils.Cfg.EmailSettings.PasswordResetSalt))

	link := fmt.Sprintf("%s/reset_password?d=%s&h=%s", c.GetTeamURLFromTeam(team), url.QueryEscape(data), url.QueryEscape(hash))

	subjectPage := NewServerTemplatePage("reset_subject")
	subjectPage.Props["SiteURL"] = c.GetSiteURL()
	bodyPage := NewServerTemplatePage("reset_body")
	bodyPage.Props["SiteURL"] = c.GetSiteURL()
	bodyPage.Props["ResetUrl"] = link

	if err := utils.SendMail(email, subjectPage.Render(), bodyPage.Render()); err != nil {
		c.Err = model.NewAppError("sendPasswordReset", "Failed to send password reset email successfully", "err="+err.Message)
		return
	}

	c.LogAuditWithUserId(user.Id, "sent="+email)

	w.Write([]byte(model.MapToJson(props)))
}
func TestUserStoreUpdatePassword(t *testing.T) {
	Setup()

	teamId := model.NewId()

	u1 := &model.User{}
	u1.Email = model.NewId()
	Must(store.User().Save(u1))
	Must(store.Team().SaveMember(&model.TeamMember{TeamId: teamId, UserId: u1.Id}))

	hashedPassword := model.HashPassword("newpwd")

	if err := (<-store.User().UpdatePassword(u1.Id, hashedPassword)).Err; err != nil {
		t.Fatal(err)
	}

	if r1 := <-store.User().GetByEmail(u1.Email); r1.Err != nil {
		t.Fatal(r1.Err)
	} else {
		user := r1.Data.(*model.User)
		if user.Password != hashedPassword {
			t.Fatal("Password was not updated correctly")
		}
	}
}
Beispiel #5
0
func GetAuthorizationCode(c *Context, w http.ResponseWriter, r *http.Request, teamName, service, redirectUri, loginHint string) {

	sso := utils.Cfg.GetSSOService(service)
	if sso != nil && !sso.Enable {
		c.Err = model.NewAppError("GetAuthorizationCode", "Unsupported OAuth service provider", "service="+service)
		c.Err.StatusCode = http.StatusBadRequest
		return
	}

	clientId := sso.Id
	endpoint := sso.AuthEndpoint
	scope := sso.Scope

	stateProps := map[string]string{"team": teamName, "hash": model.HashPassword(clientId)}
	state := b64.StdEncoding.EncodeToString([]byte(model.MapToJson(stateProps)))

	authUrl := endpoint + "?response_type=code&client_id=" + clientId + "&redirect_uri=" + url.QueryEscape(redirectUri) + "&state=" + url.QueryEscape(state)

	if len(scope) > 0 {
		authUrl += "&scope=" + utils.UrlEncode(scope)
	}

	if len(loginHint) > 0 {
		authUrl += "&login_hint=" + utils.UrlEncode(loginHint)
	}

	http.Redirect(w, r, authUrl, http.StatusFound)
}
Beispiel #6
0
func GetAuthorizationCode(c *Context, service string, props map[string]string, loginHint string) (string, *model.AppError) {

	sso := utils.Cfg.GetSSOService(service)
	if sso != nil && !sso.Enable {
		return "", model.NewLocAppError("GetAuthorizationCode", "api.user.get_authorization_code.unsupported.app_error", nil, "service="+service)
	}

	clientId := sso.Id
	endpoint := sso.AuthEndpoint
	scope := sso.Scope

	props["hash"] = model.HashPassword(clientId)
	state := b64.StdEncoding.EncodeToString([]byte(model.MapToJson(props)))

	redirectUri := c.GetSiteURL() + "/signup/" + service + "/complete"

	authUrl := endpoint + "?response_type=code&client_id=" + clientId + "&redirect_uri=" + url.QueryEscape(redirectUri) + "&state=" + url.QueryEscape(state)

	if len(scope) > 0 {
		authUrl += "&scope=" + utils.UrlEncode(scope)
	}

	if len(loginHint) > 0 {
		authUrl += "&login_hint=" + utils.UrlEncode(loginHint)
	}

	return authUrl, nil
}
Beispiel #7
0
func BenchmarkGetFile(b *testing.B) {
	team, _, channel := SetupBenchmark()

	testPoster := NewAutoPostCreator(Client, channel.Id)
	filenames, err := testPoster.UploadTestFile()
	if err == false {
		b.Fatal("Unable to upload file for benchmark")
	}

	newProps := make(map[string]string)
	newProps["filename"] = filenames[0]
	newProps["time"] = fmt.Sprintf("%v", model.GetMillis())

	data := model.MapToJson(newProps)
	hash := model.HashPassword(fmt.Sprintf("%v:%v", data, utils.Cfg.FileSettings.PublicLinkSalt))

	// wait a bit for files to ready
	time.Sleep(5 * time.Second)

	// Benchmark Start
	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		if _, downErr := Client.GetFile(filenames[0]+"?d="+url.QueryEscape(data)+"&h="+url.QueryEscape(hash)+"&t="+team.Id, true); downErr != nil {
			b.Fatal(downErr)
		}
	}
}
Beispiel #8
0
func InviteMembers(team *model.Team, user *model.User, invites []string) {
	for _, invite := range invites {
		if len(invite) > 0 {
			teamUrl := ""
			if utils.Cfg.ServiceSettings.Mode == utils.MODE_DEV {
				teamUrl = "http://localhost:8065"
			} else if utils.Cfg.ServiceSettings.UseSSL {
				teamUrl = fmt.Sprintf("https://%v.%v", team.Domain, utils.Cfg.ServiceSettings.Domain)
			} else {
				teamUrl = fmt.Sprintf("http://%v.%v", team.Domain, utils.Cfg.ServiceSettings.Domain)
			}

			sender := ""
			if len(strings.TrimSpace(user.FullName)) == 0 {
				sender = user.Username
			} else {
				sender = user.FullName
			}

			senderRole := ""
			if strings.Contains(user.Roles, model.ROLE_ADMIN) || strings.Contains(user.Roles, model.ROLE_SYSTEM_ADMIN) {
				senderRole = "administrator"
			} else {
				senderRole = "member"
			}

			subjectPage := NewServerTemplatePage("invite_subject", teamUrl)
			subjectPage.Props["SenderName"] = sender
			subjectPage.Props["TeamName"] = team.Name
			bodyPage := NewServerTemplatePage("invite_body", teamUrl)
			bodyPage.Props["TeamName"] = team.Name
			bodyPage.Props["SenderName"] = sender
			bodyPage.Props["SenderStatus"] = senderRole

			bodyPage.Props["Email"] = invite

			props := make(map[string]string)
			props["email"] = invite
			props["id"] = team.Id
			props["name"] = team.Name
			props["domain"] = team.Domain
			props["time"] = fmt.Sprintf("%v", model.GetMillis())
			data := model.MapToJson(props)
			hash := model.HashPassword(fmt.Sprintf("%v:%v", data, utils.Cfg.ServiceSettings.InviteSalt))
			bodyPage.Props["Link"] = fmt.Sprintf("%s/signup_user_complete/?d=%s&h=%s", teamUrl, url.QueryEscape(data), url.QueryEscape(hash))

			if utils.Cfg.ServiceSettings.Mode == utils.MODE_DEV {
				l4g.Info("sending invitation to %v %v", invite, bodyPage.Props["Link"])
			}

			if err := utils.SendMail(invite, subjectPage.Render(), bodyPage.Render()); err != nil {
				l4g.Error("Failed to send invite email successfully err=%v", err)
			}
		}
	}
}
Beispiel #9
0
func cmdResetPassword() {
	if flagCmdResetPassword {
		if len(flagTeamName) == 0 {
			fmt.Fprintln(os.Stderr, "flag needs an argument: -team_name")
			flag.Usage()
			os.Exit(1)
		}

		if len(flagEmail) == 0 {
			fmt.Fprintln(os.Stderr, "flag needs an argument: -email")
			flag.Usage()
			os.Exit(1)
		}

		if len(flagPassword) == 0 {
			fmt.Fprintln(os.Stderr, "flag needs an argument: -password")
			flag.Usage()
			os.Exit(1)
		}

		if len(flagPassword) < 5 {
			fmt.Fprintln(os.Stderr, "flag invalid argument needs to be more than 4 characters: -password")
			flag.Usage()
			os.Exit(1)
		}

		c := &api.Context{}
		c.RequestId = model.NewId()
		c.IpAddress = "cmd_line"

		var team *model.Team
		if result := <-api.Srv.Store.Team().GetByName(flagTeamName); result.Err != nil {
			l4g.Error("%v", result.Err)
			flushLogAndExit(1)
		} else {
			team = result.Data.(*model.Team)
		}

		var user *model.User
		if result := <-api.Srv.Store.User().GetByEmail(team.Id, flagEmail); result.Err != nil {
			l4g.Error("%v", result.Err)
			flushLogAndExit(1)
		} else {
			user = result.Data.(*model.User)
		}

		if result := <-api.Srv.Store.User().UpdatePassword(user.Id, model.HashPassword(flagPassword)); result.Err != nil {
			l4g.Error("%v", result.Err)
			flushLogAndExit(1)
		}

		os.Exit(0)
	}
}
Beispiel #10
0
func TestAddUserToTeamFromInvite(t *testing.T) {
	th := Setup().InitBasic()
	th.BasicClient.Logout()
	Client := th.BasicClient

	props := make(map[string]string)
	props["email"] = strings.ToLower(model.NewId()) + "*****@*****.**"
	props["name"] = "Test Company name"
	props["time"] = fmt.Sprintf("%v", model.GetMillis())

	data := model.MapToJson(props)
	hash := model.HashPassword(fmt.Sprintf("%v:%v", data, utils.Cfg.EmailSettings.InviteSalt))

	team := model.Team{DisplayName: "Name", Name: "z-z-" + model.NewId() + "a", Email: props["email"], Type: model.TEAM_OPEN}
	user := model.User{Email: props["email"], Nickname: "Corey Hulen", Password: "******"}

	ts := model.TeamSignup{Team: team, User: user, Invites: []string{"*****@*****.**"}, Data: data, Hash: hash}

	rts, err := Client.CreateTeamFromSignup(&ts)
	if err != nil {
		t.Fatal(err)
	}

	if rts.Data.(*model.TeamSignup).Team.DisplayName != team.DisplayName {
		t.Fatal("full name didn't match")
	}

	ruser := rts.Data.(*model.TeamSignup).User
	rteam := rts.Data.(*model.TeamSignup).Team
	Client.SetTeamId(rteam.Id)

	if result, err := Client.LoginById(ruser.Id, user.Password); err != nil {
		t.Fatal(err)
	} else {
		if result.Data.(*model.User).Email != user.Email {
			t.Fatal("email's didn't match")
		}
	}

	user2 := th.CreateUser(th.BasicClient)
	Client.Must(Client.Logout())
	Client.Must(Client.Login(user2.Email, user2.Password))

	if result, err := th.BasicClient.AddUserToTeamFromInvite("", "", rteam.InviteId); err != nil {
		t.Fatal(err)
	} else {
		rtm := result.Data.(*model.Team)
		if rtm.Id != rteam.Id {
			t.Fatal()
		}
	}
}
Beispiel #11
0
func signupTeam(c *Context, w http.ResponseWriter, r *http.Request) {
	if !utils.Cfg.EmailSettings.EnableSignUpWithEmail {
		c.Err = model.NewLocAppError("signupTeam", "api.team.signup_team.email_disabled.app_error", nil, "")
		c.Err.StatusCode = http.StatusNotImplemented
		return
	}

	m := model.MapFromJson(r.Body)
	email := strings.ToLower(strings.TrimSpace(m["email"]))

	if len(email) == 0 {
		c.SetInvalidParam("signupTeam", "email")
		return
	}

	if !isTeamCreationAllowed(c, email) {
		return
	}

	subjectPage := utils.NewHTMLTemplate("signup_team_subject", c.Locale)
	subjectPage.Props["Subject"] = c.T("api.templates.signup_team_subject",
		map[string]interface{}{"SiteName": utils.ClientCfg["SiteName"]})

	bodyPage := utils.NewHTMLTemplate("signup_team_body", c.Locale)
	bodyPage.Props["SiteURL"] = c.GetSiteURL()
	bodyPage.Props["Title"] = c.T("api.templates.signup_team_body.title")
	bodyPage.Props["Button"] = c.T("api.templates.signup_team_body.button")
	bodyPage.Html["Info"] = template.HTML(c.T("api.templates.signup_team_body.info",
		map[string]interface{}{"SiteName": utils.ClientCfg["SiteName"]}))

	props := make(map[string]string)
	props["email"] = email
	props["time"] = fmt.Sprintf("%v", model.GetMillis())

	data := model.MapToJson(props)
	hash := model.HashPassword(fmt.Sprintf("%v:%v", data, utils.Cfg.EmailSettings.InviteSalt))

	bodyPage.Props["Link"] = fmt.Sprintf("%s/signup_team_complete/?d=%s&h=%s", c.GetSiteURL(), url.QueryEscape(data), url.QueryEscape(hash))

	if err := utils.SendMail(email, subjectPage.Render(), bodyPage.Render()); err != nil {
		c.Err = err
		return
	}

	if !utils.Cfg.EmailSettings.RequireEmailVerification {
		m["follow_link"] = fmt.Sprintf("/signup_team_complete/?d=%s&h=%s", url.QueryEscape(data), url.QueryEscape(hash))
	}

	w.Header().Set("Access-Control-Allow-Origin", " *")
	w.Write([]byte(model.MapToJson(m)))
}
Beispiel #12
0
func getPublicLink(c *Context, w http.ResponseWriter, r *http.Request) {
	if !utils.Cfg.TeamSettings.AllowPublicLink {
		c.Err = model.NewAppError("getPublicLink", "Public links have been disabled", "")
		c.Err.StatusCode = http.StatusForbidden
	}

	if !utils.IsS3Configured() {
		c.Err = model.NewAppError("getPublicLink", "Unable to get link. Amazon S3 not configured. ", "")
		c.Err.StatusCode = http.StatusNotImplemented
		return
	}

	props := model.MapFromJson(r.Body)

	filename := props["filename"]
	if len(filename) == 0 {
		c.SetInvalidParam("getPublicLink", "filename")
		return
	}

	matches := model.PartialUrlRegex.FindAllStringSubmatch(filename, -1)
	if len(matches) == 0 || len(matches[0]) < 5 {
		c.SetInvalidParam("getPublicLink", "filename")
		return
	}

	getType := matches[0][1]
	channelId := matches[0][2]
	userId := matches[0][3]
	filename = matches[0][4]

	cchan := Srv.Store.Channel().CheckPermissionsTo(c.Session.TeamId, channelId, c.Session.UserId)

	newProps := make(map[string]string)
	newProps["filename"] = filename
	newProps["time"] = fmt.Sprintf("%v", model.GetMillis())

	data := model.MapToJson(newProps)
	hash := model.HashPassword(fmt.Sprintf("%v:%v", data, utils.Cfg.ServiceSettings.PublicLinkSalt))

	url := fmt.Sprintf("%s/api/v1/files/%s/%s/%s/%s?d=%s&h=%s&t=%s", c.TeamUrl, getType, channelId, userId, filename, url.QueryEscape(data), url.QueryEscape(hash), c.Session.TeamId)

	if !c.HasPermissionsToChannel(cchan, "getPublicLink") {
		return
	}

	rData := make(map[string]string)
	rData["public_link"] = url

	w.Write([]byte(model.MapToJson(rData)))
}
Beispiel #13
0
func TestCreateFromSignupTeam(t *testing.T) {
	th := Setup().InitBasic()
	th.BasicClient.Logout()
	Client := th.BasicClient

	props := make(map[string]string)
	props["email"] = strings.ToLower(model.NewId()) + "*****@*****.**"
	props["name"] = "Test Company name"
	props["time"] = fmt.Sprintf("%v", model.GetMillis())

	data := model.MapToJson(props)
	hash := model.HashPassword(fmt.Sprintf("%v:%v", data, utils.Cfg.EmailSettings.InviteSalt))

	team := model.Team{DisplayName: "Name", Name: "z-z-" + model.NewId() + "a", Email: "*****@*****.**", Type: model.TEAM_OPEN}
	user := model.User{Email: props["email"], Nickname: "Corey Hulen", Password: "******"}

	ts := model.TeamSignup{Team: team, User: user, Invites: []string{"*****@*****.**"}, Data: data, Hash: hash}

	rts, err := Client.CreateTeamFromSignup(&ts)
	if err != nil {
		t.Fatal(err)
	}

	if rts.Data.(*model.TeamSignup).Team.DisplayName != team.DisplayName {
		t.Fatal("full name didn't match")
	}

	ruser := rts.Data.(*model.TeamSignup).User
	rteam := rts.Data.(*model.TeamSignup).Team
	Client.SetTeamId(rteam.Id)

	if result, err := Client.LoginById(ruser.Id, user.Password); err != nil {
		t.Fatal(err)
	} else {
		if result.Data.(*model.User).Email != user.Email {
			t.Fatal("email's didn't match")
		}
	}

	c1 := Client.Must(Client.GetChannels("")).Data.(*model.ChannelList)
	if len(*c1) != 2 {
		t.Fatal("default channels not created")
	}

	ts.Data = "garbage"
	_, err = Client.CreateTeamFromSignup(&ts)
	if err == nil {
		t.Fatal(err)
	}
}
Beispiel #14
0
func getPublicLink(c *Context, w http.ResponseWriter, r *http.Request) {
	if len(utils.Cfg.FileSettings.DriverName) == 0 {
		c.Err = model.NewLocAppError("uploadFile", "api.file.upload_file.storage.app_error", nil, "")
		c.Err.StatusCode = http.StatusNotImplemented
		return
	}

	if !utils.Cfg.FileSettings.EnablePublicLink {
		c.Err = model.NewLocAppError("getPublicLink", "api.file.get_public_link.disabled.app_error", nil, "")
		c.Err.StatusCode = http.StatusForbidden
	}

	props := model.MapFromJson(r.Body)

	filename := props["filename"]
	if len(filename) == 0 {
		c.SetInvalidParam("getPublicLink", "filename")
		return
	}

	matches := model.PartialUrlRegex.FindAllStringSubmatch(filename, -1)
	if len(matches) == 0 || len(matches[0]) < 4 {
		c.SetInvalidParam("getPublicLink", "filename")
		return
	}

	channelId := matches[0][1]
	userId := matches[0][2]
	filename = matches[0][3]

	cchan := Srv.Store.Channel().CheckPermissionsTo(c.Session.TeamId, channelId, c.Session.UserId)

	newProps := make(map[string]string)
	newProps["filename"] = filename
	newProps["time"] = fmt.Sprintf("%v", model.GetMillis())

	data := model.MapToJson(newProps)
	hash := model.HashPassword(fmt.Sprintf("%v:%v", data, utils.Cfg.FileSettings.PublicLinkSalt))

	url := fmt.Sprintf("%s/api/v1/files/get/%s/%s/%s?d=%s&h=%s&t=%s", c.GetSiteURL(), channelId, userId, filename, url.QueryEscape(data), url.QueryEscape(hash), c.Session.TeamId)

	if !c.HasPermissionsToChannel(cchan, "getPublicLink") {
		return
	}

	rData := make(map[string]string)
	rData["public_link"] = url

	w.Write([]byte(model.MapToJson(rData)))
}
Beispiel #15
0
func GetAuthorizationCode(c *Context, w http.ResponseWriter, r *http.Request, teamName, service, redirectUri string) {

	if s, ok := utils.Cfg.SSOSettings[service]; !ok || !s.Allow {
		c.Err = model.NewAppError("GetAuthorizationCode", "Unsupported OAuth service provider", "service="+service)
		c.Err.StatusCode = http.StatusBadRequest
		return
	}

	clientId := utils.Cfg.SSOSettings[service].Id
	endpoint := utils.Cfg.SSOSettings[service].AuthEndpoint
	state := model.HashPassword(clientId)

	authUrl := endpoint + "?response_type=code&client_id=" + clientId + "&redirect_uri=" + url.QueryEscape(redirectUri+"?team="+teamName) + "&state=" + url.QueryEscape(state)
	http.Redirect(w, r, authUrl, http.StatusFound)
}
Beispiel #16
0
func TestCreateFromSignupTeam(t *testing.T) {
	Setup()

	props := make(map[string]string)
	props["email"] = strings.ToLower(model.NewId()) + "*****@*****.**"
	props["name"] = "Test Company name"
	props["time"] = fmt.Sprintf("%v", model.GetMillis())

	data := model.MapToJson(props)
	hash := model.HashPassword(fmt.Sprintf("%v:%v", data, utils.Cfg.ServiceSettings.InviteSalt))

	team := model.Team{Name: "Name", Domain: "z-z-" + model.NewId() + "a", Email: "*****@*****.**", Type: model.TEAM_OPEN}
	user := model.User{Email: props["email"], FullName: "Corey Hulen", Password: "******"}

	ts := model.TeamSignup{Team: team, User: user, Invites: []string{"*****@*****.**"}, Data: data, Hash: hash}

	rts, err := Client.CreateTeamFromSignup(&ts)
	if err != nil {
		t.Fatal(err)
	}

	if rts.Data.(*model.TeamSignup).Team.Name != team.Name {
		t.Fatal("full name didn't match")
	}

	ruser := rts.Data.(*model.TeamSignup).User

	if result, err := Client.LoginById(ruser.Id, user.Password); err != nil {
		t.Fatal(err)
	} else {
		if result.Data.(*model.User).Email != user.Email {
			t.Fatal("email's didn't match")
		}
	}

	c1 := Client.Must(Client.GetChannels("")).Data.(*model.ChannelList)
	if len(c1.Channels) != 2 {
		t.Fatal("default channels not created")
	}

	ts.Data = "garbage"
	_, err = Client.CreateTeamFromSignup(&ts)
	if err == nil {
		t.Fatal(err)
	}
}
Beispiel #17
0
func FireAndForgetVerifyEmail(userId, name, email, teamName, teamUrl string) {
	go func() {

		link := fmt.Sprintf("%s/verify?uid=%s&hid=%s", teamUrl, userId, model.HashPassword(userId))

		subjectPage := NewServerTemplatePage("verify_subject", teamUrl)
		subjectPage.Props["TeamName"] = teamName
		bodyPage := NewServerTemplatePage("verify_body", teamUrl)
		bodyPage.Props["FullName"] = name
		bodyPage.Props["TeamName"] = teamName
		bodyPage.Props["VerifyUrl"] = link

		if err := utils.SendMail(email, subjectPage.Render(), bodyPage.Render()); err != nil {
			l4g.Error("Failed to send verification email successfully err=%v", err)
		}
	}()
}
Beispiel #18
0
func InviteMembers(c *Context, team *model.Team, user *model.User, invites []string) {
	for _, invite := range invites {
		if len(invite) > 0 {

			sender := user.GetDisplayName()

			senderRole := ""
			if c.IsTeamAdmin() {
				senderRole = c.T("api.team.invite_members.admin")
			} else {
				senderRole = c.T("api.team.invite_members.member")
			}

			subjectPage := utils.NewHTMLTemplate("invite_subject", c.Locale)
			subjectPage.Props["Subject"] = c.T("api.templates.invite_subject",
				map[string]interface{}{"SenderName": sender, "TeamDisplayName": team.DisplayName, "SiteName": utils.ClientCfg["SiteName"]})

			bodyPage := utils.NewHTMLTemplate("invite_body", c.Locale)
			bodyPage.Props["SiteURL"] = c.GetSiteURL()
			bodyPage.Props["Title"] = c.T("api.templates.invite_body.title")
			bodyPage.Html["Info"] = template.HTML(c.T("api.templates.invite_body.info",
				map[string]interface{}{"SenderStatus": senderRole, "SenderName": sender, "TeamDisplayName": team.DisplayName}))
			bodyPage.Props["Button"] = c.T("api.templates.invite_body.button")
			bodyPage.Html["ExtraInfo"] = template.HTML(c.T("api.templates.invite_body.extra_info",
				map[string]interface{}{"TeamDisplayName": team.DisplayName, "TeamURL": c.GetTeamURL()}))

			props := make(map[string]string)
			props["email"] = invite
			props["id"] = team.Id
			props["display_name"] = team.DisplayName
			props["name"] = team.Name
			props["time"] = fmt.Sprintf("%v", model.GetMillis())
			data := model.MapToJson(props)
			hash := model.HashPassword(fmt.Sprintf("%v:%v", data, utils.Cfg.EmailSettings.InviteSalt))
			bodyPage.Props["Link"] = fmt.Sprintf("%s/signup_user_complete/?d=%s&h=%s", c.GetSiteURL(), url.QueryEscape(data), url.QueryEscape(hash))

			if !utils.Cfg.EmailSettings.SendEmailNotifications {
				l4g.Info(utils.T("api.team.invite_members.sending.info"), invite, bodyPage.Props["Link"])
			}

			if err := utils.SendMail(invite, subjectPage.Render(), bodyPage.Render()); err != nil {
				l4g.Error(utils.T("api.team.invite_members.send.error"), err)
			}
		}
	}
}
Beispiel #19
0
func signupTeam(c *Context, w http.ResponseWriter, r *http.Request) {
	if !utils.Cfg.EmailSettings.EnableSignUpWithEmail {
		c.Err = model.NewAppError("signupTeam", "Team sign-up with email is disabled.", "")
		c.Err.StatusCode = http.StatusNotImplemented
		return
	}

	m := model.MapFromJson(r.Body)
	email := strings.ToLower(strings.TrimSpace(m["email"]))

	if len(email) == 0 {
		c.SetInvalidParam("signupTeam", "email")
		return
	}

	if !isTreamCreationAllowed(c, email) {
		return
	}

	subjectPage := NewServerTemplatePage("signup_team_subject")
	subjectPage.Props["SiteURL"] = c.GetSiteURL()
	bodyPage := NewServerTemplatePage("signup_team_body")
	bodyPage.Props["SiteURL"] = c.GetSiteURL()

	props := make(map[string]string)
	props["email"] = email
	props["time"] = fmt.Sprintf("%v", model.GetMillis())

	data := model.MapToJson(props)
	hash := model.HashPassword(fmt.Sprintf("%v:%v", data, utils.Cfg.EmailSettings.InviteSalt))

	bodyPage.Props["Link"] = fmt.Sprintf("%s/signup_team_complete/?d=%s&h=%s", c.GetSiteURL(), url.QueryEscape(data), url.QueryEscape(hash))

	if err := utils.SendMail(email, subjectPage.Render(), bodyPage.Render()); err != nil {
		c.Err = err
		return
	}

	if !utils.Cfg.EmailSettings.RequireEmailVerification {
		m["follow_link"] = bodyPage.Props["Link"]
	}

	w.Header().Set("Access-Control-Allow-Origin", " *")
	w.Write([]byte(model.MapToJson(m)))
}
Beispiel #20
0
func InviteMembers(c *Context, team *model.Team, user *model.User, invites []string) {
	for _, invite := range invites {
		if len(invite) > 0 {
			teamURL := ""
			teamURL = c.GetTeamURLFromTeam(team)

			sender := user.GetDisplayName()

			senderRole := ""
			if strings.Contains(user.Roles, model.ROLE_ADMIN) || strings.Contains(user.Roles, model.ROLE_SYSTEM_ADMIN) {
				senderRole = "administrator"
			} else {
				senderRole = "member"
			}

			subjectPage := NewServerTemplatePage("invite_subject", teamURL)
			subjectPage.Props["SenderName"] = sender
			subjectPage.Props["TeamDisplayName"] = team.DisplayName
			bodyPage := NewServerTemplatePage("invite_body", teamURL)
			bodyPage.Props["TeamDisplayName"] = team.DisplayName
			bodyPage.Props["SenderName"] = sender
			bodyPage.Props["SenderStatus"] = senderRole

			bodyPage.Props["Email"] = invite

			props := make(map[string]string)
			props["email"] = invite
			props["id"] = team.Id
			props["display_name"] = team.DisplayName
			props["name"] = team.Name
			props["time"] = fmt.Sprintf("%v", model.GetMillis())
			data := model.MapToJson(props)
			hash := model.HashPassword(fmt.Sprintf("%v:%v", data, utils.Cfg.ServiceSettings.InviteSalt))
			bodyPage.Props["Link"] = fmt.Sprintf("%s/signup_user_complete/?d=%s&h=%s", c.GetSiteURL(), url.QueryEscape(data), url.QueryEscape(hash))

			if utils.Cfg.ServiceSettings.Mode == utils.MODE_DEV {
				l4g.Info("sending invitation to %v %v", invite, bodyPage.Props["Link"])
			}

			if err := utils.SendMail(invite, subjectPage.Render(), bodyPage.Render()); err != nil {
				l4g.Error("Failed to send invite email successfully err=%v", err)
			}
		}
	}
}
Beispiel #21
0
func resetUserPasswordCmdF(cmd *cobra.Command, args []string) error {
	initDBCommandContextCobra(cmd)
	if len(args) != 2 {
		return errors.New("Incorect number of arguments.")
	}

	user := getUserFromUserArg(args[0])
	if user == nil {
		return errors.New("Unable to find user '" + args[0] + "'")
	}
	password := args[1]

	if result := <-api.Srv.Store.User().UpdatePassword(user.Id, model.HashPassword(password)); result.Err != nil {
		return result.Err
	}

	return nil
}
Beispiel #22
0
func InviteMembers(c *Context, team *model.Team, user *model.User, invites []string) {
	for _, invite := range invites {
		if len(invite) > 0 {

			sender := user.GetDisplayName()

			senderRole := ""
			if c.IsTeamAdmin() {
				senderRole = c.T("api.team.invite_members.admin")
			} else {
				senderRole = c.T("api.team.invite_members.member")
			}

			subjectPage := NewServerTemplatePage("invite_subject")
			subjectPage.Props["SenderName"] = sender
			subjectPage.Props["TeamDisplayName"] = team.DisplayName

			bodyPage := NewServerTemplatePage("invite_body")
			bodyPage.Props["SiteURL"] = c.GetSiteURL()
			bodyPage.Props["TeamURL"] = c.GetTeamURL()
			bodyPage.Props["TeamDisplayName"] = team.DisplayName
			bodyPage.Props["SenderName"] = sender
			bodyPage.Props["SenderStatus"] = senderRole
			props := make(map[string]string)
			props["email"] = invite
			props["id"] = team.Id
			props["display_name"] = team.DisplayName
			props["name"] = team.Name
			props["time"] = fmt.Sprintf("%v", model.GetMillis())
			data := model.MapToJson(props)
			hash := model.HashPassword(fmt.Sprintf("%v:%v", data, utils.Cfg.EmailSettings.InviteSalt))
			bodyPage.Props["Link"] = fmt.Sprintf("%s/signup_user_complete/?d=%s&h=%s", c.GetSiteURL(), url.QueryEscape(data), url.QueryEscape(hash))

			if !utils.Cfg.EmailSettings.SendEmailNotifications {
				l4g.Info(utils.T("api.team.invite_members.sending.info"), invite, bodyPage.Props["Link"])
			}

			if err := utils.SendMail(invite, subjectPage.Render(), bodyPage.Render()); err != nil {
				l4g.Error(utils.T("api.team.invite_members.send.error"), err)
			}
		}
	}
}
Beispiel #23
0
func InviteMembers(team *model.Team, senderName string, invites []string) {
	for _, invite := range invites {
		if len(invite) > 0 {
			senderRole := utils.T("api.team.invite_members.member")

			subject := utils.T("api.templates.invite_subject",
				map[string]interface{}{"SenderName": senderName, "TeamDisplayName": team.DisplayName, "SiteName": utils.ClientCfg["SiteName"]})

			bodyPage := utils.NewHTMLTemplate("invite_body", model.DEFAULT_LOCALE)
			bodyPage.Props["SiteURL"] = *utils.Cfg.ServiceSettings.SiteURL
			bodyPage.Props["Title"] = utils.T("api.templates.invite_body.title")
			bodyPage.Html["Info"] = template.HTML(utils.T("api.templates.invite_body.info",
				map[string]interface{}{"SenderStatus": senderRole, "SenderName": senderName, "TeamDisplayName": team.DisplayName}))
			bodyPage.Props["Button"] = utils.T("api.templates.invite_body.button")
			bodyPage.Html["ExtraInfo"] = template.HTML(utils.T("api.templates.invite_body.extra_info",
				map[string]interface{}{"TeamDisplayName": team.DisplayName, "TeamURL": *utils.Cfg.ServiceSettings.SiteURL + "/" + team.Name}))

			props := make(map[string]string)
			props["email"] = invite
			props["id"] = team.Id
			props["display_name"] = team.DisplayName
			props["name"] = team.Name
			props["time"] = fmt.Sprintf("%v", model.GetMillis())
			data := model.MapToJson(props)
			hash := model.HashPassword(fmt.Sprintf("%v:%v", data, utils.Cfg.EmailSettings.InviteSalt))
			bodyPage.Props["Link"] = fmt.Sprintf("%s/signup_user_complete/?d=%s&h=%s", *utils.Cfg.ServiceSettings.SiteURL, url.QueryEscape(data), url.QueryEscape(hash))

			if !utils.Cfg.EmailSettings.SendEmailNotifications {
				l4g.Info(utils.T("api.team.invite_members.sending.info"), invite, bodyPage.Props["Link"])
			}

			if err := utils.SendMail(invite, subject, bodyPage.Render()); err != nil {
				l4g.Error(utils.T("api.team.invite_members.send.error"), err)
			}
		}
	}
}
Beispiel #24
0
func TestResetPassword(t *testing.T) {
	Setup()

	team := &model.Team{DisplayName: "Name", Name: "z-z-" + model.NewId() + "a", Email: "*****@*****.**", Type: model.TEAM_OPEN}
	team = Client.Must(Client.CreateTeam(team)).Data.(*model.Team)

	user := &model.User{TeamId: team.Id, Email: strings.ToLower(model.NewId()) + "*****@*****.**", Nickname: "Corey Hulen", Password: "******"}
	user = Client.Must(Client.CreateUser(user, "")).Data.(*model.User)
	store.Must(Srv.Store.User().VerifyEmail(user.Id))

	data := make(map[string]string)
	data["new_password"] = "******"
	props := make(map[string]string)
	props["user_id"] = user.Id
	props["time"] = fmt.Sprintf("%v", model.GetMillis())
	data["data"] = model.MapToJson(props)
	data["hash"] = model.HashPassword(fmt.Sprintf("%v:%v", data["data"], utils.Cfg.ServiceSettings.ResetSalt))
	data["name"] = team.Name

	if _, err := Client.ResetPassword(data); err != nil {
		t.Fatal(err)
	}

	data["new_password"] = ""
	if _, err := Client.ResetPassword(data); err == nil {
		t.Fatal("Should have errored - no password")
	}

	data["new_password"] = "******"
	if _, err := Client.ResetPassword(data); err == nil {
		t.Fatal("Should have errored - password too short")
	}

	data["new_password"] = "******"
	data["hash"] = ""
	if _, err := Client.ResetPassword(data); err == nil {
		t.Fatal("Should have errored - no hash")
	}

	data["hash"] = "junk"
	if _, err := Client.ResetPassword(data); err == nil {
		t.Fatal("Should have errored - bad hash")
	}

	props["user_id"] = ""
	data["data"] = model.MapToJson(props)
	if _, err := Client.ResetPassword(data); err == nil {
		t.Fatal("Should have errored - no user id")
	}

	data["user_id"] = "12345678901234567890123456"
	data["data"] = model.MapToJson(props)
	if _, err := Client.ResetPassword(data); err == nil {
		t.Fatal("Should have errored - bad user id")
	}

	props["user_id"] = user.Id
	props["time"] = ""
	data["data"] = model.MapToJson(props)
	if _, err := Client.ResetPassword(data); err == nil {
		t.Fatal("Should have errored - no time")
	}

	props["time"] = fmt.Sprintf("%v", model.GetMillis())
	data["data"] = model.MapToJson(props)
	data["domain"] = ""
	if _, err := Client.ResetPassword(data); err == nil {
		t.Fatal("Should have errored - no domain")
	}

	data["domain"] = "junk"
	if _, err := Client.ResetPassword(data); err == nil {
		t.Fatal("Should have errored - bad domain")
	}

	team2 := &model.Team{DisplayName: "Name", Name: "z-z-" + model.NewId() + "a", Email: "*****@*****.**", Type: model.TEAM_OPEN}
	team2 = Client.Must(Client.CreateTeam(team2)).Data.(*model.Team)

	data["domain"] = team2.Name
	if _, err := Client.ResetPassword(data); err == nil {
		t.Fatal("Should have errored - domain team doesn't match user team")
	}
}
Beispiel #25
0
func TestGetFile(t *testing.T) {
	Setup()

	team := &model.Team{Name: "Name", Domain: "z-z-" + model.NewId() + "a", Email: "*****@*****.**", Type: model.TEAM_OPEN}
	team = Client.Must(Client.CreateTeam(team)).Data.(*model.Team)

	user1 := &model.User{TeamId: team.Id, Email: model.NewId() + "*****@*****.**", FullName: "Corey Hulen", Password: "******"}
	user1 = Client.Must(Client.CreateUser(user1, "")).Data.(*model.User)
	Srv.Store.User().VerifyEmail(user1.Id)

	Client.LoginByEmail(team.Domain, user1.Email, "pwd")

	channel1 := &model.Channel{DisplayName: "Test API Name", Name: "a" + model.NewId() + "a", Type: model.CHANNEL_OPEN, TeamId: team.Id}
	channel1 = Client.Must(Client.CreateChannel(channel1)).Data.(*model.Channel)

	if utils.IsS3Configured() {

		body := &bytes.Buffer{}
		writer := multipart.NewWriter(body)
		part, err := writer.CreateFormFile("files", "test.png")
		if err != nil {
			t.Fatal(err)
		}

		path := utils.FindDir("web/static/images")
		file, err := os.Open(path + "/test.png")
		if err != nil {
			t.Fatal(err)
		}
		defer file.Close()

		_, err = io.Copy(part, file)
		if err != nil {
			t.Fatal(err)
		}

		field, err := writer.CreateFormField("channel_id")
		if err != nil {
			t.Fatal(err)
		}

		_, err = field.Write([]byte(channel1.Id))
		if err != nil {
			t.Fatal(err)
		}

		err = writer.Close()
		if err != nil {
			t.Fatal(err)
		}

		resp, upErr := Client.UploadFile("/files/upload", body.Bytes(), writer.FormDataContentType())
		if upErr != nil {
			t.Fatal(upErr)
		}

		filenames := resp.Data.(*model.FileUploadResponse).Filenames

		// wait a bit for files to ready
		time.Sleep(5 * time.Second)

		if _, downErr := Client.GetFile(filenames[0], true); downErr != nil {
			t.Fatal("file get failed")
		}

		team2 := &model.Team{Name: "Name", Domain: "z-z-" + model.NewId() + "a", Email: "*****@*****.**", Type: model.TEAM_OPEN}
		team2 = Client.Must(Client.CreateTeam(team2)).Data.(*model.Team)

		user2 := &model.User{TeamId: team2.Id, Email: model.NewId() + "*****@*****.**", FullName: "Corey Hulen", Password: "******"}
		user2 = Client.Must(Client.CreateUser(user2, "")).Data.(*model.User)
		Srv.Store.User().VerifyEmail(user2.Id)

		newProps := make(map[string]string)
		newProps["filename"] = filenames[0]
		newProps["time"] = fmt.Sprintf("%v", model.GetMillis())

		data := model.MapToJson(newProps)
		hash := model.HashPassword(fmt.Sprintf("%v:%v", data, utils.Cfg.ServiceSettings.PublicLinkSalt))

		Client.LoginByEmail(team2.Domain, user2.Email, "pwd")

		if _, downErr := Client.GetFile(filenames[0]+"?d="+url.QueryEscape(data)+"&h="+url.QueryEscape(hash)+"&t="+team.Id, true); downErr != nil {
			t.Fatal(downErr)
		}

		if _, downErr := Client.GetFile(filenames[0]+"?d="+url.QueryEscape(data)+"&h="+url.QueryEscape(hash), true); downErr == nil {
			t.Fatal("Should have errored - missing team id")
		}

		if _, downErr := Client.GetFile(filenames[0]+"?d="+url.QueryEscape(data)+"&h="+url.QueryEscape(hash)+"&t=junk", true); downErr == nil {
			t.Fatal("Should have errored - bad team id")
		}

		if _, downErr := Client.GetFile(filenames[0]+"?d="+url.QueryEscape(data)+"&h="+url.QueryEscape(hash)+"&t=12345678901234567890123456", true); downErr == nil {
			t.Fatal("Should have errored - bad team id")
		}

		if _, downErr := Client.GetFile(filenames[0]+"?d="+url.QueryEscape(data)+"&t="+team.Id, true); downErr == nil {
			t.Fatal("Should have errored - missing hash")
		}

		if _, downErr := Client.GetFile(filenames[0]+"?d="+url.QueryEscape(data)+"&h=junk&t="+team.Id, true); downErr == nil {
			t.Fatal("Should have errored - bad hash")
		}

		if _, downErr := Client.GetFile(filenames[0]+"?h="+url.QueryEscape(hash)+"&t="+team.Id, true); downErr == nil {
			t.Fatal("Should have errored - missing data")
		}

		if _, downErr := Client.GetFile(filenames[0]+"?d=junk&h="+url.QueryEscape(hash)+"&t="+team.Id, true); downErr == nil {
			t.Fatal("Should have errored - bad data")
		}

		if _, downErr := Client.GetFile(filenames[0], true); downErr == nil {
			t.Fatal("Should have errored - user not logged in and link not public")
		}

		var auth aws.Auth
		auth.AccessKey = utils.Cfg.AWSSettings.S3AccessKeyId
		auth.SecretKey = utils.Cfg.AWSSettings.S3SecretAccessKey

		s := s3.New(auth, aws.Regions[utils.Cfg.AWSSettings.S3Region])
		bucket := s.Bucket(utils.Cfg.AWSSettings.S3Bucket)

		fileId := strings.Split(filenames[0], ".")[0]

		err = bucket.Del("teams/" + team.Id + "/channels/" + channel1.Id + "/users/" + user1.Id + "/" + filenames[0])
		if err != nil {
			t.Fatal(err)
		}

		err = bucket.Del("teams/" + team.Id + "/channels/" + channel1.Id + "/users/" + user1.Id + "/" + fileId + "_thumb.jpg")
		if err != nil {
			t.Fatal(err)
		}

		err = bucket.Del("teams/" + team.Id + "/channels/" + channel1.Id + "/users/" + user1.Id + "/" + fileId + "_preview.png")
		if err != nil {
			t.Fatal(err)
		}
	} else {
		if _, downErr := Client.GetFile("/files/get/yxebdmbz5pgupx7q6ez88rw11a/n3btzxu9hbnapqk36iwaxkjxhc/junk.jpg", false); downErr.StatusCode != http.StatusNotImplemented {
			t.Fatal("Status code should have been 501 - Not Implemented")
		}
	}
}
Beispiel #26
0
func allowOAuth(c *Context, w http.ResponseWriter, r *http.Request) {
	if !utils.Cfg.ServiceSettings.EnableOAuthServiceProvider {
		c.Err = model.NewLocAppError("allowOAuth", "api.oauth.allow_oauth.turn_off.app_error", nil, "")
		c.Err.StatusCode = http.StatusNotImplemented
		return
	}

	c.LogAudit("attempt")

	responseData := map[string]string{}

	responseType := r.URL.Query().Get("response_type")
	if len(responseType) == 0 {
		c.Err = model.NewLocAppError("allowOAuth", "api.oauth.allow_oauth.bad_response.app_error", nil, "")
		c.Err.StatusCode = http.StatusBadRequest
		return
	}

	clientId := r.URL.Query().Get("client_id")
	if len(clientId) != 26 {
		c.Err = model.NewLocAppError("allowOAuth", "api.oauth.allow_oauth.bad_client.app_error", nil, "")
		c.Err.StatusCode = http.StatusBadRequest
		return
	}

	redirectUri := r.URL.Query().Get("redirect_uri")
	if len(redirectUri) == 0 {
		c.Err = model.NewLocAppError("allowOAuth", "api.oauth.allow_oauth.bad_redirect.app_error", nil, "")
		c.Err.StatusCode = http.StatusBadRequest
		return
	}

	scope := r.URL.Query().Get("scope")
	state := r.URL.Query().Get("state")

	if len(scope) == 0 {
		scope = model.DEFAULT_SCOPE
	}

	var app *model.OAuthApp
	if result := <-Srv.Store.OAuth().GetApp(clientId); result.Err != nil {
		c.Err = model.NewLocAppError("allowOAuth", "api.oauth.allow_oauth.database.app_error", nil, "")
		return
	} else {
		app = result.Data.(*model.OAuthApp)
	}

	if !app.IsValidRedirectURL(redirectUri) {
		c.LogAudit("fail - redirect_uri did not match registered callback")
		c.Err = model.NewLocAppError("allowOAuth", "api.oauth.allow_oauth.redirect_callback.app_error", nil, "")
		c.Err.StatusCode = http.StatusBadRequest
		return
	}

	if responseType != model.AUTHCODE_RESPONSE_TYPE {
		responseData["redirect"] = redirectUri + "?error=unsupported_response_type&state=" + state
		w.Write([]byte(model.MapToJson(responseData)))
		return
	}

	authData := &model.AuthData{UserId: c.Session.UserId, ClientId: clientId, CreateAt: model.GetMillis(), RedirectUri: redirectUri, State: state, Scope: scope}
	authData.Code = model.HashPassword(fmt.Sprintf("%v:%v:%v:%v", clientId, redirectUri, authData.CreateAt, c.Session.UserId))

	// this saves the OAuth2 app as authorized
	authorizedApp := model.Preference{
		UserId:   c.Session.UserId,
		Category: model.PREFERENCE_CATEGORY_AUTHORIZED_OAUTH_APP,
		Name:     clientId,
		Value:    scope,
	}

	if result := <-Srv.Store.Preference().Save(&model.Preferences{authorizedApp}); result.Err != nil {
		responseData["redirect"] = redirectUri + "?error=server_error&state=" + state
		w.Write([]byte(model.MapToJson(responseData)))
		return
	}

	if result := <-Srv.Store.OAuth().SaveAuthData(authData); result.Err != nil {
		responseData["redirect"] = redirectUri + "?error=server_error&state=" + state
		w.Write([]byte(model.MapToJson(responseData)))
		return
	}

	c.LogAudit("success")

	responseData["redirect"] = redirectUri + "?code=" + url.QueryEscape(authData.Code) + "&state=" + url.QueryEscape(authData.State)
	w.Write([]byte(model.MapToJson(responseData)))
}
Beispiel #27
0
func updatePassword(c *Context, w http.ResponseWriter, r *http.Request) {
	c.LogAudit("attempted")

	props := model.MapFromJson(r.Body)
	userId := props["user_id"]
	if len(userId) != 26 {
		c.SetInvalidParam("updatePassword", "user_id")
		return
	}

	currentPassword := props["current_password"]
	if len(currentPassword) <= 0 {
		c.SetInvalidParam("updatePassword", "current_password")
		return
	}

	newPassword := props["new_password"]
	if len(newPassword) < 5 {
		c.SetInvalidParam("updatePassword", "new_password")
		return
	}

	if userId != c.Session.UserId {
		c.Err = model.NewAppError("updatePassword", "Update password failed because context user_id did not match props user_id", "")
		c.Err.StatusCode = http.StatusForbidden
		return
	}

	var result store.StoreResult

	if result = <-Srv.Store.User().Get(userId); result.Err != nil {
		c.Err = result.Err
		return
	}

	if result.Data == nil {
		c.Err = model.NewAppError("updatePassword", "Update password failed because we couldn't find a valid account", "")
		c.Err.StatusCode = http.StatusBadRequest
		return
	}

	user := result.Data.(*model.User)

	tchan := Srv.Store.Team().Get(user.TeamId)

	if user.AuthData != "" {
		c.LogAudit("failed - tried to update user password who was logged in through oauth")
		c.Err = model.NewAppError("updatePassword", "Update password failed because the user is logged in through an OAuth service", "auth_service="+user.AuthService)
		c.Err.StatusCode = http.StatusForbidden
		return
	}

	if !model.ComparePassword(user.Password, currentPassword) {
		c.Err = model.NewAppError("updatePassword", "The \"Current Password\" you entered is incorrect. Please check that Caps Lock is off and try again.", "")
		c.Err.StatusCode = http.StatusForbidden
		return
	}

	if uresult := <-Srv.Store.User().UpdatePassword(c.Session.UserId, model.HashPassword(newPassword)); uresult.Err != nil {
		c.Err = model.NewAppError("updatePassword", "Update password failed", uresult.Err.Error())
		c.Err.StatusCode = http.StatusForbidden
		return
	} else {
		c.LogAudit("completed")

		if tresult := <-tchan; tresult.Err != nil {
			l4g.Error(tresult.Err.Message)
		} else {
			team := tresult.Data.(*model.Team)
			sendPasswordChangeEmailAndForget(user.Email, team.DisplayName, c.GetTeamURLFromTeam(team), c.GetSiteURL(), "using the settings menu")
		}

		data := make(map[string]string)
		data["user_id"] = uresult.Data.(string)
		w.Write([]byte(model.MapToJson(data)))
	}
}
Beispiel #28
0
func SendVerifyEmailAndForget(userId, userEmail, teamName, teamDisplayName, siteURL, teamURL string) {
	go func() {

		link := fmt.Sprintf("%s/verify_email?uid=%s&hid=%s&teamname=%s&email=%s", siteURL, userId, model.HashPassword(userId), teamName, userEmail)

		subjectPage := NewServerTemplatePage("verify_subject")
		subjectPage.Props["SiteURL"] = siteURL
		subjectPage.Props["TeamDisplayName"] = teamDisplayName
		bodyPage := NewServerTemplatePage("verify_body")
		bodyPage.Props["SiteURL"] = siteURL
		bodyPage.Props["TeamDisplayName"] = teamDisplayName
		bodyPage.Props["VerifyUrl"] = link

		if err := utils.SendMail(userEmail, subjectPage.Render(), bodyPage.Render()); err != nil {
			l4g.Error("Failed to send verification email successfully err=%v", err)
		}
	}()
}
Beispiel #29
0
func sendWelcomeEmailAndForget(userId, email, teamName, teamDisplayName, siteURL, teamURL string, verified bool) {
	go func() {

		subjectPage := NewServerTemplatePage("welcome_subject")
		subjectPage.Props["TeamDisplayName"] = teamDisplayName
		bodyPage := NewServerTemplatePage("welcome_body")
		bodyPage.Props["SiteURL"] = siteURL
		bodyPage.Props["TeamURL"] = teamURL

		if !verified {
			link := fmt.Sprintf("%s/verify_email?uid=%s&hid=%s&teamname=%s&email=%s", siteURL, userId, model.HashPassword(userId), teamName, email)
			bodyPage.Props["VerifyUrl"] = link
		}

		if err := utils.SendMail(email, subjectPage.Render(), bodyPage.Render()); err != nil {
			l4g.Error("Failed to send welcome email successfully err=%v", err)
		}
	}()
}
Beispiel #30
0
func resetPassword(c *Context, w http.ResponseWriter, r *http.Request) {
	props := model.MapFromJson(r.Body)

	newPassword := props["new_password"]
	if len(newPassword) < 5 {
		c.SetInvalidParam("resetPassword", "new_password")
		return
	}

	name := props["name"]
	if len(name) == 0 {
		c.SetInvalidParam("resetPassword", "name")
		return
	}

	userId := props["user_id"]
	hash := props["hash"]
	timeStr := ""

	if !c.IsSystemAdmin() {
		if len(hash) == 0 {
			c.SetInvalidParam("resetPassword", "hash")
			return
		}

		data := model.MapFromJson(strings.NewReader(props["data"]))

		userId = data["user_id"]

		timeStr = data["time"]
		if len(timeStr) == 0 {
			c.SetInvalidParam("resetPassword", "data:time")
			return
		}
	}

	if len(userId) != 26 {
		c.SetInvalidParam("resetPassword", "user_id")
		return
	}

	c.LogAuditWithUserId(userId, "attempt")

	var team *model.Team
	if result := <-Srv.Store.Team().GetByName(name); result.Err != nil {
		c.Err = result.Err
		return
	} else {
		team = result.Data.(*model.Team)
	}

	var user *model.User
	if result := <-Srv.Store.User().Get(userId); result.Err != nil {
		c.Err = result.Err
		return
	} else {
		user = result.Data.(*model.User)
	}

	if len(user.AuthData) != 0 {
		c.Err = model.NewAppError("resetPassword", "Cannot reset password for SSO accounts", "userId="+user.Id+", teamId="+team.Id)
		return
	}

	if user.TeamId != team.Id {
		c.Err = model.NewAppError("resetPassword", "Trying to reset password for user on wrong team.", "userId="+user.Id+", teamId="+team.Id)
		c.Err.StatusCode = http.StatusForbidden
		return
	}

	if !c.IsSystemAdmin() {
		if !model.ComparePassword(hash, fmt.Sprintf("%v:%v", props["data"], utils.Cfg.EmailSettings.PasswordResetSalt)) {
			c.Err = model.NewAppError("resetPassword", "The reset password link does not appear to be valid", "")
			return
		}

		t, err := strconv.ParseInt(timeStr, 10, 64)
		if err != nil || model.GetMillis()-t > 1000*60*60 { // one hour
			c.Err = model.NewAppError("resetPassword", "The reset link has expired", "")
			return
		}
	}

	if result := <-Srv.Store.User().UpdatePassword(userId, model.HashPassword(newPassword)); result.Err != nil {
		c.Err = result.Err
		return
	} else {
		c.LogAuditWithUserId(userId, "success")
	}

	sendPasswordChangeEmailAndForget(user.Email, team.DisplayName, c.GetTeamURLFromTeam(team), c.GetSiteURL(), "using a reset password link")

	props["new_password"] = ""
	w.Write([]byte(model.MapToJson(props)))
}