<commit_before>#
# Paasmaker - Platform as a Service
#
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
#

import unittest
import uuid
import logging
import json

import paasmaker
from paasmaker.common.controller import BaseController, BaseControllerTest
from paasmaker.common.core import constants

import colander
import tornado
import tornado.testing

logger = logging.getLogger(__name__)
logger.addHandler(logging.NullHandler())

class Boolean(object):
	def serialize(self, node, appstruct):
		if appstruct is colander.null:
			return colander.null
		if not isinstance(appstruct, bool):
		   raise Invalid(node, '%r is not a boolean')
		return appstruct and 'true' or 'false'

	def deserialize(self, node, cstruct):
		if cstruct is colander.null:
		   return colander.null
		if isinstance(cstruct, bool):
			return cstruct
		if not isinstance(cstruct, basestring):
			raise Invalid(node, '%r is not a string' % cstruct)
		value = cstruct.lower()
		if value in ('true', 'yes', 'y', 'on', 't', '1'):
			return True
		return False

	def cstruct_children(self):
		return []

	def unflatten(self, subnode, subpaths, subfstruct):
		return self.deserialize(subnode, subfstruct[subnode.name])

class UserSchema(colander.MappingSchema):
	name = colander.SchemaNode(colander.String(),
		title="User name",
		description="A nice name for this user.",
		validator=colander.Length(min=2))
	login = colander.SchemaNode(colander.String(),
		title="Login",
		description="The handle that the user uses to login.",
		validator=colander.Length(min=2))
	email = colander.SchemaNode(colander.String(),
		title="Email address",
		description="The email address of this user.",
		validator=colander.Email())
	enabled = colander.SchemaNode(Boolean(),
		title="Enabled",
		description="If this user is enabled.",
		missing=False,
		default=False)
	password = colander.SchemaNode(colander.String(),
		title="Password",
		description="The users password (blank to leave unchanged)",
		default="",
		missing="",
		# TODO: more complex password requirements.
		validator=colander.Length(min=8))

class UserEditController(BaseController):
	AUTH_METHODS = [BaseController.SUPER, BaseController.USER]

	def _get_user(self, user_id=None):
		user = None
		if user_id:
			# Find and load the user.
			user = self.session.query(
				paasmaker.model.User
			).get(int(user_id))
			if not user:
				raise HTTPError(404, "No such user.")

			self.add_data('user', user)

		return user

	def _default_user(self):
		user = paasmaker.model.User()
		user.name = ''
		user.login = ''
		user.email = ''
		return user

	def get(self, user_id=None):
		self.require_permission(constants.PERMISSION.USER_EDIT)
		user = self._get_user(user_id)
		if not user:
			user = self._default_user()
			self.add_data('user', user)

		self.render("user/edit.html")

	def post(self, user_id=None):
		self.require_permission(constants.PERMISSION.USER_EDIT)
		user = self._get_user(user_id)

		valid_data = self.validate_data(UserSchema())

		if not user:
			user = self._default_user()

		user.name = self.params['name']
		user.login = self.params['login']
		user.email = self.params['email']
		user.enabled = self.params['enabled']

		if valid_data and not user.id:
			# Password must be supplied.
			if self.params['password'] == '':
				self.add_error("No password supplied.")
				valid_data = False

		if valid_data:
			if self.params.has_key('password'):
				user.password = self.params['password']

			self.session.add(user)
			self.session.commit()
			self.session.refresh(user)

			self.add_data('user', user)

			self.redirect('/user/list')
		else:
			self.add_data('user', user)
			self.render("user/edit.html")

	@staticmethod
	def get_routes(configuration):
		routes = []
		routes.append((r"/user/create", UserEditController, configuration))
		routes.append((r"/user/(\d+)", UserEditController, configuration))
		return routes

class UserListController(BaseController):
	AUTH_METHODS = [BaseController.SUPER, BaseController.USER]

	def get(self):<commit_msg>Handle unique constraints when creating a user - email and login are unique.<commit_after>#
# Paasmaker - Platform as a Service
#
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
#

import unittest
import uuid
import logging
import json

import paasmaker
from paasmaker.common.controller import BaseController, BaseControllerTest
from paasmaker.common.core import constants

import colander
import tornado
import tornado.testing
import sqlalchemy

logger = logging.getLogger(__name__)
logger.addHandler(logging.NullHandler())

class Boolean(object):
	def serialize(self, node, appstruct):
		if appstruct is colander.null:
			return colander.null
		if not isinstance(appstruct, bool):
		   raise Invalid(node, '%r is not a boolean')
		return appstruct and 'true' or 'false'

	def deserialize(self, node, cstruct):
		if cstruct is colander.null:
		   return colander.null
		if isinstance(cstruct, bool):
			return cstruct
		if not isinstance(cstruct, basestring):
			raise Invalid(node, '%r is not a string' % cstruct)
		value = cstruct.lower()
		if value in ('true', 'yes', 'y', 'on', 't', '1'):
			return True
		return False

	def cstruct_children(self):
		return []

	def unflatten(self, subnode, subpaths, subfstruct):
		return self.deserialize(subnode, subfstruct[subnode.name])

class UserSchema(colander.MappingSchema):
	name = colander.SchemaNode(colander.String(),
		title="User name",
		description="A nice name for this user.",
		validator=colander.Length(min=2))
	login = colander.SchemaNode(colander.String(),
		title="Login",
		description="The handle that the user uses to login.",
		validator=colander.Length(min=2))
	email = colander.SchemaNode(colander.String(),
		title="Email address",
		description="The email address of this user.",
		validator=colander.Email())
	enabled = colander.SchemaNode(Boolean(),
		title="Enabled",
		description="If this user is enabled.",
		missing=False,
		default=False)
	password = colander.SchemaNode(colander.String(),
		title="Password",
		description="The users password (blank to leave unchanged)",
		default="",
		missing="",
		# TODO: more complex password requirements.
		validator=colander.Length(min=8))

class UserEditController(BaseController):
	AUTH_METHODS = [BaseController.SUPER, BaseController.USER]

	def _get_user(self, user_id=None):
		user = None
		if user_id:
			# Find and load the user.
			user = self.session.query(
				paasmaker.model.User
			).get(int(user_id))
			if not user:
				raise HTTPError(404, "No such user.")

			self.add_data('user', user)

		return user

	def _default_user(self):
		user = paasmaker.model.User()
		user.name = ''
		user.login = ''
		user.email = ''
		return user

	def get(self, user_id=None):
		self.require_permission(constants.PERMISSION.USER_EDIT)
		user = self._get_user(user_id)
		if not user:
			user = self._default_user()
			self.add_data('user', user)

		self.render("user/edit.html")

	def post(self, user_id=None):
		self.require_permission(constants.PERMISSION.USER_EDIT)
		user = self._get_user(user_id)

		valid_data = self.validate_data(UserSchema())

		if not user:
			user = self._default_user()

		user.name = self.params['name']
		user.login = self.params['login']
		user.email = self.params['email']
		user.enabled = self.params['enabled']

		if valid_data and not user.id:
			# Password must be supplied.
			if self.params['password'] == '':
				self.add_error("No password supplied.")
				valid_data = False

		if valid_data:
			if self.params.has_key('password'):
				user.password = self.params['password']

			self.session.add(user)
			try:
				self.session.commit()
				self.session.refresh(user)
			except sqlalchemy.exc.IntegrityError, ex:
				self.session.rollback()
				if 'email is not' in str(ex):
					valid_data = False
					self.add_error('The email address is not unique.')
				elif 'login is not' in str(ex):
					valid_data = False
					self.add_error('The login name is not unique.')
				else:
					raise ex

		if valid_data:
			self.add_data('user', user)
			self.redirect('/user/list')
		else:
			self.add_data('user', user)
			self.render("user/edit.html")

	@staticmethod
	def get_routes(configuration):
		routes = []
		routes.append((r"/user/create", UserEditController, configuration))
		routes.append((r"/user/(\d+)", UserEditController, configuration))
		return routes

class UserListController(BaseController):
	AUTH_METHODS = [BaseController.SUPER, BaseController.USER]

	def get(self):
{'fraction_non_alphanumeric': 0.12324386065105654, 'fraction_numerical': 0.0025128498001142203, 'mean_word_length': 4.368485591661558, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3209471', 'n_tokens_mistral': 3091, 'n_tokens_neox': 2774, 'n_words': 734}