Skip to content

Commit

Permalink
Update to use new plugin init mechanism
Browse files Browse the repository at this point in the history
  • Loading branch information
rickmak committed Oct 25, 2016
2 parents c730e8c + 173932c commit 0a76b23
Show file tree
Hide file tree
Showing 5 changed files with 254 additions and 240 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ SMTP settings are required for the plugin to send outgoing email.

### Other settings

* `FORGOT_PASSWORD_APPNAME` - the app name that will appear in the built-in
* `FORGOT_PASSWORD_APP_NAME` - the app name that will appear in the built-in
template. If you use a different template, you do not need to supply an
app name. The default app name is the Skygear Server app name.
* `FORGOT_PASSWORD_URL_PREFIX` - the URL prefix for accessing the Skygear
Expand Down Expand Up @@ -53,7 +53,7 @@ Here are a list of templates you can override:

* `templates/forgot_password/reset_password.html` - HTML form for user
to enter a new password.

* `templates/forgot_password/reset_password_error.html` - HTML page
to show when there is an error with the code and User ID of the request.

Expand Down
183 changes: 7 additions & 176 deletions forgot_password/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,186 +11,17 @@
# 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.
import logging

import skygear
from skygear import error as skyerror
from skygear.error import SkygearException
from skygear.utils.db import conn

from . import template
from .util import email as emailutil
from .util import user as userutil
from .options import options as forgetoptions
from skygear.settings import add_parser as add_setting_parser

from .settings import get_settings_parser, get_smtp_settings_parser
from .handlers import register_handlers

logger = logging.getLogger(__name__)

def includeme(settings):
register_handlers(settings.forgot_password, settings.forgot_password_smtp)

def mail_is_configured():
"""
Returns true if mail is configured
"""
return bool(forgetoptions.smtp_host)


@skygear.op('user:forgot-password')
def forgot_password(email):
"""
Lambda function to handle forgot password request.
"""
if not mail_is_configured():
logger.error('Mail server is not configured. Configure SMTP_HOST.')
raise SkygearException('mail server is not configured',
skyerror.UnexpectedError)

if email is None:
raise SkygearException('email is not found',
skyerror.ResourceNotFound)

with conn() as c:
user = userutil.get_user_from_email(c, email)
if not user:
logger.debug('Unable to find user_id')
raise SkygearException('user_id is not found',
skyerror.ResourceNotFound)
if not user.email:
logger.debug('User does not have email address. This user cannot '
'reset password.')
raise SkygearException('email is not found',
skyerror.ResourceNotFound)

logger.debug('Found user with email address.')

user_record = userutil.get_user_record(c, user.id)
code = userutil.generate_code(user)
url_prefix = forgetoptions.url_prefix
link = '{0}/reset-password?code={1}&user_id={2}'.format(
url_prefix, code, user.id)

template_params = {
'appname': forgetoptions.appname,
'link': link,
'url_prefix': url_prefix,
'email': user.email,
'user_id': user.id,
'code': code,
'user': user,
'user_record': user_record,
}

text = template.reset_email_text(**template_params)
if text:
logger.debug('Generated plain text reset password email.')

html = template.reset_email_html(**template_params)
if html:
logger.debug('Generated html reset password email.')

sender = forgetoptions.sender
subject = forgetoptions.subject

try:
logger.debug('About to send email to user.')
mailer = emailutil.Mailer(
smtp_host=forgetoptions.smtp_host,
smtp_port=forgetoptions.smtp_port,
smtp_mode=forgetoptions.smtp_mode,
smtp_login=forgetoptions.smtp_login,
smtp_password=forgetoptions.smtp_password,
)
mailer.send_mail(sender, email, subject, text, html=html)
logger.info('Successfully sent reset password email to user.')
except Exception as ex:
logger.exception('An error occurred sending reset password email '
'to user.')
raise SkygearException(str(ex), skyerror.UnexpectedError)
return {'status': 'OK'}


@skygear.op('user:reset-password')
def reset_password(user_id, code, new_password):
"""
Lambda function to handle reset password request.
"""
if not user_id:
raise SkygearException('user_id is not found',
skyerror.ResourceNotFound)
if not code:
raise SkygearException('code is not found',
skyerror.ResourceNotFound)

with conn() as c:
user = userutil.get_user_and_validate_code(c, user_id, code)
if not user:
logger.debug('User ID is not found or the code is not valid.')
raise SkygearException('user_id is not found or code invalid',
skyerror.ResourceNotFound)

if not user.email:
raise SkygearException('email is not found',
skyerror.ResourceNotFound)

logger.debug('Found user and the verification code is valid.')

userutil.set_new_password(c, user.id, new_password)
logger.info('Successfully reset password for user.')
return {'status': 'OK'}


def reset_password_response(**kwargs):
"""
A shorthand for returning the reset password form as a response.
"""
body = template.reset_password_form(**kwargs)
return skygear.Response(body, content_type='text/html')


@skygear.handler('reset-password')
def reset_password_handler(request):
"""
A handler for handling reset password request.
"""
code = request.values.get('code')
user_id = request.values.get('user_id')

with conn() as c:
user = userutil.get_user_and_validate_code(c, user_id, code)
if not user:
logger.debug('User ID is not found or the code is not valid.')
error_msg = 'User not found or code is invalid.'
body = template.reset_password_error(error=error_msg)
return skygear.Response(body, content_type='text/html')
user_record = userutil.get_user_record(c, user.id)

logger.debug('Found user and the verification code is valid.')

template_params = {
'user': user,
'user_record': user_record,
'code': code,
'user_id': user_id,
}

if request.method == 'POST':
password = request.values.get('password')
if not password:
return reset_password_response(
error='Password cannot be empty.',
**template_params
)

if password != request.values.get('confirm'):
return reset_password_response(
error='Confirm password does not match new password.',
**template_params
)

with conn() as c:
userutil.set_new_password(c, user.id, password)
logger.info('Successfully reset password for user.')

body = template.reset_password_success()
return skygear.Response(body, content_type='text/html')

return reset_password_response(**template_params)
add_setting_parser('forgot_password', get_settings_parser())
add_setting_parser('forgot_password_smtp', get_smtp_settings_parser())
Loading

0 comments on commit 0a76b23

Please sign in to comment.