PLT-1830 Adding ability to create team with ldap

This commit is contained in:
=Corey Hulen
2016-03-07 14:59:15 -08:00
parent 0387ac7997
commit 777012eee4
8 changed files with 380 additions and 0 deletions
+76
View File
@@ -8,6 +8,7 @@ import (
"fmt"
l4g "github.com/alecthomas/log4go"
"github.com/gorilla/mux"
"github.com/mattermost/platform/einterfaces"
"github.com/mattermost/platform/model"
"github.com/mattermost/platform/store"
"github.com/mattermost/platform/utils"
@@ -25,6 +26,7 @@ func InitTeam(r *mux.Router) {
sr := r.PathPrefix("/teams").Subrouter()
sr.Handle("/create", ApiAppHandler(createTeam)).Methods("POST")
sr.Handle("/create_from_signup", ApiAppHandler(createTeamFromSignup)).Methods("POST")
sr.Handle("/create_with_ldap", ApiAppHandler(createTeamWithLdap)).Methods("POST")
sr.Handle("/create_with_sso/{service:[A-Za-z]+}", ApiAppHandler(createTeamFromSSO)).Methods("POST")
sr.Handle("/signup", ApiAppHandler(signupTeam)).Methods("POST")
sr.Handle("/all", ApiUserRequired(getAll)).Methods("GET")
@@ -244,6 +246,80 @@ func createTeamFromSignup(c *Context, w http.ResponseWriter, r *http.Request) {
}
}
func createTeamWithLdap(c *Context, w http.ResponseWriter, r *http.Request) {
ldap := einterfaces.GetLdapInterface()
if ldap == nil {
c.Err = model.NewLocAppError("createTeamWithLdap", "ent.ldap.do_login.licence_disable.app_error", nil, "")
return
}
teamSignup := model.TeamSignupFromJson(r.Body)
if teamSignup == nil {
c.SetInvalidParam("createTeam", "teamSignup")
return
}
teamSignup.Team.PreSave()
if err := teamSignup.Team.IsValid(*utils.Cfg.TeamSettings.RestrictTeamNames); err != nil {
c.Err = err
return
}
if !isTeamCreationAllowed(c, teamSignup.Team.Email) {
return
}
teamSignup.Team.Id = ""
found := FindTeamByName(c, teamSignup.Team.Name, "true")
if c.Err != nil {
return
}
if found {
c.Err = model.NewLocAppError("createTeamFromSignup", "api.team.create_team_from_signup.unavailable.app_error", nil, "d="+teamSignup.Team.Name)
return
}
user, err := ldap.GetUser(teamSignup.User.Username)
if err != nil {
c.Err = err
return
}
err = ldap.CheckPassword(teamSignup.User.Username, teamSignup.User.Password)
if err != nil {
c.Err = err
return
}
if result := <-Srv.Store.Team().Save(&teamSignup.Team); result.Err != nil {
c.Err = result.Err
return
} else {
rteam := result.Data.(*model.Team)
if _, err := CreateDefaultChannels(c, rteam.Id); err != nil {
c.Err = nil
return
}
user.TeamId = rteam.Id
ruser, err := CreateUser(rteam, user)
if err != nil {
c.Err = err
return
}
teamSignup.Team = *rteam
teamSignup.User = *ruser
w.Write([]byte(teamSignup.ToJson()))
}
}
func createTeam(c *Context, w http.ResponseWriter, r *http.Request) {
team := model.TeamFromJson(r.Body)
rteam := CreateTeam(c, team)
+2
View File
@@ -9,6 +9,8 @@ import (
type LdapInterface interface {
DoLogin(team *model.Team, id string, password string) (*model.User, *model.AppError)
GetUser(id string) (*model.User, *model.AppError)
CheckPassword(id string, password string) *model.AppError
}
var theLdapInterface LdapInterface
+14
View File
@@ -4,6 +4,7 @@
import ChoosePage from './team_signup_choose_auth.jsx';
import EmailSignUpPage from './team_signup_with_email.jsx';
import SSOSignupPage from './team_signup_with_sso.jsx';
import LdapSignUpPage from './team_signup_with_ldap.jsx';
import Constants from '../utils/constants.jsx';
import {FormattedMessage} from 'mm-intl';
@@ -24,12 +25,18 @@ export default class TeamSignUp extends React.Component {
count = count + 1;
}
if (global.window.mm_config.EnableLdap === 'true') {
count = count + 1;
}
if (count > 1) {
this.state = {page: 'choose'};
} else if (global.window.mm_config.EnableSignUpWithEmail === 'true') {
this.state = {page: 'email'};
} else if (global.window.mm_config.EnableSignUpWithGitLab === 'true') {
this.state = {page: 'gitlab'};
} else if (global.window.mm_config.EnableLdap === 'true') {
this.state = {page: 'ldap'};
} else {
this.state = {page: 'none'};
}
@@ -133,6 +140,13 @@ export default class TeamSignUp extends React.Component {
<EmailSignUpPage/>
</div>
);
} else if (this.state.page === 'ldap') {
return (
<div>
{teamListing}
<LdapSignUpPage/>
</div>
);
} else if (this.state.page === 'gitlab') {
return (
<div>
@@ -58,6 +58,30 @@ export default class ChooseAuthPage extends React.Component {
);
}
if (global.window.mm_config.EnableLdap === 'true') {
buttons.push(
<a
className='btn btn-custom-login ldap btn-full'
key='ldap'
href='#'
onClick={
(e) => {
e.preventDefault();
this.props.updatePage('ldap');
}
}
>
<span className='icon'/>
<span>
<FormattedMessage
id='choose_auth_page.ldapCreate'
defaultMessage='Create new team with LDAP Account'
/>
</span>
</a>
);
}
if (global.window.mm_config.EnableSignUpWithEmail === 'true') {
buttons.push(
<a
@@ -0,0 +1,234 @@
// Copyright (c) 2015 Mattermost, Inc. All Rights Reserved.
// See License.txt for license information.
import * as utils from '../utils/utils.jsx';
import * as Client from '../utils/client.jsx';
import {injectIntl, intlShape, defineMessages, FormattedMessage} from 'mm-intl';
const holders = defineMessages({
team_error: {
id: 'ldap_signup.team_error',
defaultMessage: 'Please enter a team name'
},
length_error: {
id: 'ldap_signup.length_error',
defaultMessage: 'Name must be 3 or more characters up to a maximum of 15'
},
teamName: {
id: 'ldap_signup.teamName',
defaultMessage: 'Enter name of new team'
},
badTeam: {
id: 'login_ldap.badTeam',
defaultMessage: 'Bad team name'
},
idReq: {
id: 'login_ldap.idlReq',
defaultMessage: 'An LDAP ID is required'
},
pwdReq: {
id: 'login_ldap.pwdReq',
defaultMessage: 'An LDAP password is required'
},
username: {
id: 'login_ldap.username',
defaultMessage: 'LDAP Username'
},
pwd: {
id: 'login_ldap.pwd',
defaultMessage: 'LDAP Password'
}
});
class LdapSignUpPage extends React.Component {
constructor(props) {
super(props);
this.handleSubmit = this.handleSubmit.bind(this);
this.valueChange = this.valueChange.bind(this);
this.state = {name: '', id: '', password: ''};
}
handleSubmit(e) {
e.preventDefault();
const {formatMessage} = this.props.intl;
var teamSignup = {};
teamSignup.user = {};
teamSignup.team = {};
var state = this.state;
state.serverError = null;
teamSignup.team.display_name = this.state.name;
if (!teamSignup.team.display_name) {
state.serverError = formatMessage(holders.team_error);
this.setState(state);
return;
}
if (teamSignup.team.display_name.length <= 2) {
state.serverError = formatMessage(holders.length_error);
this.setState(state);
return;
}
const id = this.refs.id.value.trim();
if (!id) {
state.serverError = formatMessage(holders.idReq);
this.setState(state);
return;
}
const password = this.refs.password.value.trim();
if (!password) {
state.serverError = formatMessage(holders.pwdReq);
this.setState(state);
return;
}
state.serverError = '';
this.setState(state);
teamSignup.team.name = utils.cleanUpUrlable(teamSignup.team.display_name);
teamSignup.team.type = 'O';
teamSignup.user.username = ReactDOM.findDOMNode(this.refs.id).value.trim();
teamSignup.user.password = ReactDOM.findDOMNode(this.refs.password).value.trim();
teamSignup.user.allow_marketing = true;
teamSignup.user.ldap = true;
teamSignup.user.auth_service = 'ldap';
$('#ldap-button').button('loading');
Client.createTeamWithLdap(teamSignup,
() => {
Client.track('signup', 'signup_team_ldap_complete');
Client.loginByLdap(teamSignup.team.name, id, password,
() => {
window.location.href = '/' + teamSignup.team.name + '/channels/town-square';
},
(err) => {
$('#ldap-button').button('reset');
this.setState({serverError: err.message});
}
);
},
(err) => {
$('#ldap-button').button('reset');
this.setState({serverError: err.message});
}
);
}
valueChange() {
this.setState({
name: ReactDOM.findDOMNode(this.refs.teamname).value.trim(),
id: ReactDOM.findDOMNode(this.refs.id).value.trim(),
password: ReactDOM.findDOMNode(this.refs.password).value.trim()
});
}
render() {
const {formatMessage} = this.props.intl;
var nameError = null;
var nameDivClass = 'form-group';
if (this.state.nameError) {
nameError = <label className='control-label'>{this.state.nameError}</label>;
nameDivClass += ' has-error';
}
var serverError = null;
if (this.state.serverError) {
serverError = <div className='form-group has-error'><label className='control-label'>{this.state.serverError}</label></div>;
}
var disabled = false;
if (this.state.name.length <= 2) {
disabled = true;
}
if (this.state.id.length <= 1) {
disabled = true;
}
if (this.state.password.length <= 1) {
disabled = true;
}
return (
<form
role='form'
onSubmit={this.handleSubmit}
>
<div className={nameDivClass}>
<input
autoFocus={true}
type='text'
ref='teamname'
className='form-control'
placeholder={this.props.intl.formatMessage(holders.teamName)}
maxLength='128'
onChange={this.valueChange}
spellCheck='false'
/>
{nameError}
</div>
<div className={nameDivClass}>
<input
className='form-control'
ref='id'
placeholder={formatMessage(holders.username)}
spellCheck='false'
onChange={this.valueChange}
/>
</div>
<div className={nameDivClass}>
<input
type='password'
className='form-control'
ref='password'
placeholder={formatMessage(holders.pwd)}
spellCheck='false'
onChange={this.valueChange}
/>
</div>
<div className='form-group'>
<a
className='btn btn-custom-login ldap btn-full'
key='ldap'
id='ldap-button'
href='#'
onClick={this.handleSubmit}
disabled={disabled}
>
<span className='icon'/>
<span>
<FormattedMessage
id='ldap_signup.ldap'
defaultMessage='Create team with LDAP Account'
/>
</span>
</a>
{serverError}
</div>
<div className='form-group margin--extra-2x'>
<span><a href='/find_team'>
<FormattedMessage
id='ldap_signup.find'
defaultMessage='Find my teams'
/>
</a></span>
</div>
</form>
);
}
}
LdapSignUpPage.propTypes = {
intl: intlShape.isRequired
};
export default injectIntl(LdapSignUpPage);
+15
View File
@@ -87,6 +87,21 @@ export function createTeamFromSignup(teamSignup, success, error) {
});
}
export function createTeamWithLdap(teamSignup, success, error) {
$.ajax({
url: '/api/v1/teams/create_with_ldap',
dataType: 'json',
contentType: 'application/json',
type: 'POST',
data: JSON.stringify(teamSignup),
success,
error: function onError(xhr, status, err) {
var e = handleError('createTeamFromSignup', xhr, status, err);
error(e);
}
});
}
export function createTeamWithSSO(team, service, success, error) {
$.ajax({
url: '/api/v1/teams/create_with_sso/' + service,
@@ -214,6 +214,15 @@
background-image: url("../images/googleLogo.png");
}
}
&.ldap {
background: #dd4b39;
&:hover {
background: darken(#dd4b39, 10%);
}
span {
vertical-align: middle;
}
}
&.email {
background: #2389D7;
&:hover {
+6
View File
@@ -593,6 +593,7 @@
"choose_auth_page.find": "Find my teams",
"choose_auth_page.gitlabCreate": "Create new team with GitLab Account",
"choose_auth_page.googleCreate": "Create new team with Google Apps Account",
"choose_auth_page.ldapCreate": "Create new team with LDAP Account",
"choose_auth_page.noSignup": "No sign-up methods configured, please contact your system administrator.",
"claim.account.noEmail": "No email specified",
"claim.email_to_sso.enterPwd": "Enter the password for your {team} {site} account",
@@ -964,6 +965,11 @@
"sso_signup.length_error": "Name must be 3 or more characters up to a maximum of 15",
"sso_signup.teamName": "Enter name of new team",
"sso_signup.team_error": "Please enter a team name",
"ldap_signup.find": "Find my teams",
"ldap_signup.ldap": "Create team with LDAP Account",
"ldap_signup.length_error": "Name must be 3 or more characters up to a maximum of 15",
"ldap_signup.teamName": "Enter name of new team",
"ldap_signup.team_error": "Please enter a team name",
"suggestion.mention.all": "Notifies everyone in the team",
"suggestion.mention.channel": "Notifies everyone in the channel",
"suggestion.search.private": "Public Groups",