You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@couchdb.apache.org by ga...@apache.org on 2013/04/03 08:35:58 UTC
git commit: updated refs/heads/1715-admin-auth to 1f52687
Updated Branches:
refs/heads/1715-admin-auth 628a1b5cf -> 1f5268716
white list auth module
Project: http://git-wip-us.apache.org/repos/asf/couchdb/repo
Commit: http://git-wip-us.apache.org/repos/asf/couchdb/commit/1f526871
Tree: http://git-wip-us.apache.org/repos/asf/couchdb/tree/1f526871
Diff: http://git-wip-us.apache.org/repos/asf/couchdb/diff/1f526871
Branch: refs/heads/1715-admin-auth
Commit: 1f526871622d132481871e04d4f35aa0c607b088
Parents: 628a1b5
Author: Garren Smith <ga...@gmail.com>
Authored: Wed Apr 3 08:35:14 2013 +0200
Committer: Garren Smith <ga...@gmail.com>
Committed: Wed Apr 3 08:35:14 2013 +0200
----------------------------------------------------------------------
.gitignore | 1 +
src/fauxton/app/addons/auth/base.js | 34 ++
src/fauxton/app/addons/auth/resources.js | 325 +++++++++++++++
src/fauxton/app/addons/auth/routes.js | 22 +
.../auth/templates/change_password_modal.html | 35 ++
.../addons/auth/templates/create_admin_modal.html | 46 ++
.../app/addons/auth/templates/login_modal.html | 35 ++
.../app/addons/auth/templates/nav_link.html | 42 ++
8 files changed, 540 insertions(+), 0 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/couchdb/blob/1f526871/.gitignore
----------------------------------------------------------------------
diff --git a/.gitignore b/.gitignore
index e3f57eb..67da1c8 100644
--- a/.gitignore
+++ b/.gitignore
@@ -91,6 +91,7 @@ src/fauxton/app/addons/*
!src/fauxton/app/addons/logs
!src/fauxton/app/addons/stats
!src/fauxton/app/addons/contribute
+!src/fauxton/app/addons/auth
src/fauxton/settings.json*
!src/fauxton/settings.json.default
share/www/fauxton
http://git-wip-us.apache.org/repos/asf/couchdb/blob/1f526871/src/fauxton/app/addons/auth/base.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/addons/auth/base.js b/src/fauxton/app/addons/auth/base.js
new file mode 100644
index 0000000..4cf1b83
--- /dev/null
+++ b/src/fauxton/app/addons/auth/base.js
@@ -0,0 +1,34 @@
+// Licensed under the Apache License, Version 2.0 (the "License"); you may not
+// use this file except in compliance with the License. You may obtain a copy of
+// the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+// License for the specific language governing permissions and limitations under
+// the License.
+
+define([
+ "app",
+ "api",
+ "addons/auth/routes"
+],
+
+function(app, FauxtonAPI, Auth) {
+
+ Auth.initialize = function() {
+ Auth.session = new Auth.Session();
+ Auth.navLink = new Auth.NavLink({model: Auth.session});
+
+ FauxtonAPI.addHeaderLink({
+ title: "Auth",
+ href: "#_auth",
+ view: Auth.navLink,
+ establish: [Auth.session.fetchOnce()]
+ });
+ };
+
+ return Auth;
+});
http://git-wip-us.apache.org/repos/asf/couchdb/blob/1f526871/src/fauxton/app/addons/auth/resources.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/addons/auth/resources.js b/src/fauxton/app/addons/auth/resources.js
new file mode 100644
index 0000000..5b61d50
--- /dev/null
+++ b/src/fauxton/app/addons/auth/resources.js
@@ -0,0 +1,325 @@
+// Licensed under the Apache License, Version 2.0 (the "License"); you may not
+// use this file except in compliance with the License. You may obtain a copy of
+// the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+// License for the specific language governing permissions and limitations under
+// the License.
+
+define([
+ "app",
+ "api",
+ "addons/config/resources"
+],
+
+function (app, FauxtonAPI, Config) {
+ var Auth = new FauxtonAPI.addon();
+
+ Auth.Session = Backbone.Model.extend({
+ url: '/_session',
+
+ is_admin_party: function () {
+ var userCtx = this.get('userCtx');
+
+ if (!userCtx.name && userCtx.roles.indexOf("_admin") > -1) {
+ return true;
+ }
+
+ return false;
+ },
+
+ user: function () {
+ var userCtx = this.get('userCtx');
+
+ if (!userCtx || !userCtx.name) { return null; }
+
+ return {
+ name: userCtx.name,
+ roles: userCtx.roles
+ };
+ },
+
+ fetchOnce: function (opt) {
+ var options = _.extend({}, opt);
+
+ if (!this._deferred || this._deferred.isRejected() || options.forceFetch ) {
+ this._deferred = this.fetch();
+ }
+
+ return this._deferred;
+ },
+
+ validate_user: function (username, password, msg) {
+ if (_.isEmpty(username) || _.isEmpty(password)) {
+ var deferred = $.Deferred();
+
+ deferred.rejectWith(this, [msg]);
+ return deferred;
+ }
+ },
+
+ validate_passwords: function (password, password_confirm, msg) {
+ if (_.isEmpty(password) || _.isEmpty(password_confirm) || (password !== password_confirm)) {
+ var deferred = $.Deferred();
+
+ deferred.rejectWith(this, [msg]);
+ return deferred;
+ }
+
+ },
+
+ create_admin: function (username, password, login) {
+ var self = this,
+ error_promise = this.validate_user(username, password, 'Authname or password cannot be blank.');
+
+ if (error_promise) { return error_promise; }
+
+ var admin = new Config.OptionModel({
+ section: "admins",
+ name: username,
+ value: password
+ });
+
+ return admin.save().then(function () {
+ if (login) {
+ return self.login(username, password);
+ } else {
+ return self.fetchOnce({forceFetch: true});
+ }
+ });
+ },
+
+ login: function (username, password) {
+ var error_promise = this.validate_user(username, password, 'Authname or password cannot be blank.');
+
+ if (error_promise) { return error_promise; }
+
+ var self = this;
+
+ return $.ajax({
+ type: "POST",
+ url: "/_session",
+ dataType: "json",
+ data: {name: username, password: password}
+ }).then(function () {
+ return self.fetchOnce({forceFetch: true});
+ });
+ },
+
+ logout: function () {
+ var self = this;
+
+ return $.ajax({
+ type: "DELETE",
+ url: "/_session",
+ dataType: "json",
+ username : "_",
+ password : "_"
+ }).then(function () {
+ return self.fetchOnce({forceFetch: true });
+ });
+ },
+
+ change_password: function (password, password_confirm) {
+ var error_promise = this.validate_passwords(password, password_confirm, 'Passwords do not match.');
+
+ if (error_promise) { return error_promise; }
+
+ var self = this,
+ info = this.get('info'),
+ userCtx = this.get('userCtx');
+
+ var admin = new Config.OptionModel({
+ section: "admins",
+ name: userCtx.name,
+ value: password
+ });
+
+ return admin.save().then(function () {
+ return self.login(userCtx.name, password);
+ });
+ }
+ });
+
+ Auth.ModalView = FauxtonAPI.View.extend({
+
+ show_modal: function () {
+ this.clear_error_msg();
+ this.$('.modal').modal();
+ // hack to get modal visible
+ $('.modal-backdrop').css('z-index',1025);
+ },
+
+ hide_modal: function () {
+ this.$('.modal').modal('hide');
+ },
+
+ set_error_msg: function (msg) {
+ var text;
+ if (typeof(msg) == 'string') {
+ text = msg;
+ } else {
+ text = JSON.parse(msg.responseText).reason;
+ }
+
+ this.$('#modal-error').text(text).removeClass('hide');
+ },
+
+ clear_error_msg: function () {
+ this.$('#modal-error').text(' ').addClass('hide');
+ }
+
+ });
+
+ Auth.CreateAdminModal = Auth.ModalView.extend({
+ template: 'addons/auth/templates/create_admin_modal',
+
+ initialize: function (options) {
+ this.login_after = options.login_after || true;
+ },
+
+ events: {
+ "click #create-admin": "create_admin"
+ },
+
+ create_admin: function (event) {
+ event.preventDefault();
+ this.clear_error_msg();
+
+ var self = this,
+ username = this.$('#username').val(),
+ password = this.$('#password').val();
+
+ var promise = this.model.create_admin(username, password, this.login_after);
+
+ promise.then(function () {
+ self.$('.modal').modal('hide');
+ self.hide_modal();
+ });
+
+ promise.fail(function (rsp) {
+ self.set_error_msg(rsp);
+ });
+ }
+
+ });
+
+ Auth.LoginModal = Auth.ModalView.extend({
+ template: 'addons/auth/templates/login_modal',
+
+ events: {
+ "click #login": "login"
+ },
+
+ login: function () {
+ event.preventDefault();
+ this.clear_error_msg();
+
+ var self = this,
+ username = this.$('#username').val(),
+ password = this.$('#password').val();
+
+ var promise = this.model.login(username, password);
+
+ promise.done(function () {
+ self.hide_modal();
+ });
+
+ promise.fail(function (rsp) {
+ self.set_error_msg(rsp);
+ });
+ }
+
+ });
+
+ Auth.ChangePasswordModal = Auth.ModalView.extend({
+ template: 'addons/auth/templates/change_password_modal',
+
+ events: {
+ "click #change-password": "change_password"
+ },
+
+ change_password: function () {
+ event.preventDefault();
+ this.clear_error_msg();
+
+ var self = this,
+ new_password = this.$('#password').val(),
+ password_confirm = this.$('#password-confirm').val();
+
+ var promise = this.model.change_password(new_password, password_confirm);
+
+ promise.done(function () {
+ self.hide_modal();
+ });
+
+ promise.fail(function (rsp) {
+ self.set_error_msg(rsp);
+ });
+ }
+ });
+
+ Auth.NavLink = FauxtonAPI.View.extend({
+ template: 'addons/auth/templates/nav_link',
+
+ tagName: "li",
+ className: "dropdown",
+
+ initialize:function (options) {
+ },
+
+ serialize: function () {
+ return {
+ admin_party: this.model.is_admin_party(),
+ user: this.model.user()
+ };
+ },
+
+ events: {
+ "click #user-create-admin": 'show_admin_modal',
+ "click #user-create-more-admin": 'show_create_more_admin_modal',
+ "click #user-login": 'show_login_modal',
+ "click #user-change-password": 'show_change_password_modal',
+ "click #user-logout": 'logout_user'
+ },
+
+ beforeRender: function () {
+ this.listenTo(this.model, 'change', this.render);
+ this.create_admin_modal = this.setView('#user-create-admin-modal', new Auth.CreateAdminModal({model: this.model}));
+ this.login_modal = this.setView('#login-modal', new Auth.LoginModal({model: this.model}));
+ this.change_password_modal = this.setView('#change-password-modal', new Auth.ChangePasswordModal({model: this.model}));
+ },
+
+ show_admin_modal: function (event) {
+ event.preventDefault();
+ this.create_admin_modal.show_modal();
+ },
+
+ show_create_more_admin_modal: function (event) {
+ event.preventDefault();
+ this.create_admin_modal.login_after = false;
+ this.create_admin_modal.show_modal();
+ },
+
+ show_login_modal: function (event) {
+ event.preventDefault();
+ this.login_modal.show_modal();
+ },
+
+ show_change_password_modal: function (event) {
+ event.preventDefault();
+ this.change_password_modal.show_modal();
+ },
+
+ logout_user: function () {
+ event.preventDefault();
+ this.model.logout();
+ }
+ });
+
+ return Auth;
+});
http://git-wip-us.apache.org/repos/asf/couchdb/blob/1f526871/src/fauxton/app/addons/auth/routes.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/addons/auth/routes.js b/src/fauxton/app/addons/auth/routes.js
new file mode 100644
index 0000000..6ff7502
--- /dev/null
+++ b/src/fauxton/app/addons/auth/routes.js
@@ -0,0 +1,22 @@
+// Licensed under the Apache License, Version 2.0 (the "License"); you may not
+// use this file except in compliance with the License. You may obtain a copy of
+// the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+// License for the specific language governing permissions and limitations under
+// the License.
+
+define([
+ "app",
+ "api",
+ "addons/auth/resources"
+],
+
+function(app, FauxtonAPI, Auth) {
+
+ return Auth;
+});
http://git-wip-us.apache.org/repos/asf/couchdb/blob/1f526871/src/fauxton/app/addons/auth/templates/change_password_modal.html
----------------------------------------------------------------------
diff --git a/src/fauxton/app/addons/auth/templates/change_password_modal.html b/src/fauxton/app/addons/auth/templates/change_password_modal.html
new file mode 100644
index 0000000..5e3db38
--- /dev/null
+++ b/src/fauxton/app/addons/auth/templates/change_password_modal.html
@@ -0,0 +1,35 @@
+<!--
+Licensed under the Apache License, Version 2.0 (the "License"); you may not
+use this file except in compliance with the License. You may obtain a copy of
+the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+License for the specific language governing permissions and limitations under
+the License.
+-->
+
+<div class="modal hide fade">
+ <div class="modal-header">
+ <button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
+ <h3>Change Password</h3>
+ </div>
+ <div class="modal-body">
+ <div id="modal-error" class="hide alert alert-error"/>
+ <form>
+ <p class="help-block">
+ Enter your new password.
+ </p>
+ <input id="password" type="password" name="password" placeholder= "New Password:" size="24">
+ <br/>
+ <input id="password-confirm" type="password" name="password_confirm" placeholder= "Verify New Password" size="24">
+ </form>
+ </div>
+ <div class="modal-footer">
+ <a href="#" data-dismiss="modal" class="btn">Cancel</a>
+ <a href="#" id="change-password" class="btn btn-primary">Change</a>
+ </div>
+</div>
http://git-wip-us.apache.org/repos/asf/couchdb/blob/1f526871/src/fauxton/app/addons/auth/templates/create_admin_modal.html
----------------------------------------------------------------------
diff --git a/src/fauxton/app/addons/auth/templates/create_admin_modal.html b/src/fauxton/app/addons/auth/templates/create_admin_modal.html
new file mode 100644
index 0000000..0d16ca1
--- /dev/null
+++ b/src/fauxton/app/addons/auth/templates/create_admin_modal.html
@@ -0,0 +1,46 @@
+<!--
+Licensed under the Apache License, Version 2.0 (the "License"); you may not
+use this file except in compliance with the License. You may obtain a copy of
+the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+License for the specific language governing permissions and limitations under
+the License.
+-->
+
+<div class="modal hide fade">
+ <div class="modal-header">
+ <button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
+ <h3>Create Server Admin</h3>
+ </div>
+ <div class="modal-body">
+ <div id="modal-error" class="hide alert alert-error"/>
+ <form>
+ <input id="username" type="text" name="name" placeholder= "Username:" size="24">
+ <br/>
+ <input id="password" type="password" name="password" placeholder= "Password" size="24">
+ </form>
+ <p class="help-block">
+ Before a server admin is configured, all clients have admin privileges.
+ This is fine when HTTP access is restricted
+ to trusted users. <strong>If end-users will be accessing this CouchDB, you must
+ create an admin account to prevent accidental (or malicious) data loss.</strong>
+ </p>
+ <p class="help-block">Server admins can create and destroy databases, install
+ and update _design documents, run the test suite, and edit all aspects of CouchDB
+ configuration.
+ </p>
+ <p class="help-block">Non-admin users have read and write access to all databases, which
+ are controlled by validation functions. CouchDB can be configured to block all
+ access to anonymous users.
+ </p>
+ </div>
+ <div class="modal-footer">
+ <a href="#" data-dismiss="modal" class="btn">Cancel</a>
+ <a href="#" id="create-admin" class="btn btn-primary">Create Admin</a>
+ </div>
+</div>
http://git-wip-us.apache.org/repos/asf/couchdb/blob/1f526871/src/fauxton/app/addons/auth/templates/login_modal.html
----------------------------------------------------------------------
diff --git a/src/fauxton/app/addons/auth/templates/login_modal.html b/src/fauxton/app/addons/auth/templates/login_modal.html
new file mode 100644
index 0000000..e0395da
--- /dev/null
+++ b/src/fauxton/app/addons/auth/templates/login_modal.html
@@ -0,0 +1,35 @@
+<!--
+Licensed under the Apache License, Version 2.0 (the "License"); you may not
+use this file except in compliance with the License. You may obtain a copy of
+the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+License for the specific language governing permissions and limitations under
+the License.
+-->
+
+<div class="modal hide fade">
+ <div class="modal-header">
+ <button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
+ <h3>Login</h3>
+ </div>
+ <div class="modal-body">
+ <div id="modal-error" class="hide alert alert-error"/>
+ <form>
+ <p class="help-block">
+ Login to CouchDB with your name and password.
+ </p>
+ <input id="username" type="text" name="name" placeholder= "Username:" size="24">
+ <br/>
+ <input id="password" type="password" name="password" placeholder= "Password" size="24">
+ </form>
+ </div>
+ <div class="modal-footer">
+ <a href="#" data-dismiss="modal" class="btn">Cancel</a>
+ <a href="#" id="login" class="btn btn-primary">Login</a>
+ </div>
+</div>
http://git-wip-us.apache.org/repos/asf/couchdb/blob/1f526871/src/fauxton/app/addons/auth/templates/nav_link.html
----------------------------------------------------------------------
diff --git a/src/fauxton/app/addons/auth/templates/nav_link.html b/src/fauxton/app/addons/auth/templates/nav_link.html
new file mode 100644
index 0000000..2f1462f
--- /dev/null
+++ b/src/fauxton/app/addons/auth/templates/nav_link.html
@@ -0,0 +1,42 @@
+<!--
+Licensed under the Apache License, Version 2.0 (the "License"); you may not
+use this file except in compliance with the License. You may obtain a copy of
+the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+License for the specific language governing permissions and limitations under
+the License.
+-->
+
+<a id="user-drop" class="dropdown-toggle" role="button" data-toggle="dropdown" href="#">
+ <% if (admin_party) { %>
+ Admin Party!
+ <% } else if (user) { %>
+ <%= user.name %>
+ <% } else { %>
+ Login
+ <% } %>
+ <b class="caret"></b>
+</a>
+<ul class="dropdown-menu" role="menu" aria-labelledby="user-drop">
+ <!-- dropdown menu links -->
+ <% if (admin_party) { %>
+ <li> <a id="user-create-admin" href="#"> Create Admin </a> </li>
+ <% } else if (user) { %>
+ <li> <a id="user-create-more-admin" href="#"> Create Admins </a> </li>
+ <li> <a id="user-change-password" href="#"> Change Password </a> </li>
+ <li> <a id="user-logout" href="#"> Logout </a> </li>
+ <% } else { %>
+ <li> <a id="user-login" href="#"> Login </a> </li>
+ <li> <a id="user-sign-up"> Sign up </a> </li>
+ <% } %>
+</ul>
+
+<div id="user-create-admin-modal"> </div>
+<div id="login-modal"> </div>
+<div id="change-password-modal"> </div>
+<div id="signup-modal"> </div>