Exemple #1
0
class Attachment(Resource):
    @spec('/attachments/<string:attachment_id>',
          "Delete Image Attachment",
          header_params=Swagger.Params.Authorization,
          responses=[
              ApiResponse(200, "Succeed", dict(result=True)),
              ApiResponse.error(404, "Image Not Found"),
              ApiResponse.error(403, "Image Uploaded by another user"),
              ApiResponse.error(500, "s3 delete error. try again")
          ])
    @check_auth
    def delete(self, attachment_id):
        img = ImageAttachmentModel.objects.with_id(attachment_id)
        if img is None:
            exceptionReport(g.user.user_db, get_path(), get_path_args(),
                            get_args())
            raise InvalidUsage("Image Not Found", 404)

        if img.user_id != g.user.user_db.user_id:
            exceptionReport(g.user.user_db, get_path(), get_path_args(),
                            get_args())
            raise InvalidUsage("Image Uploaded by another user", 403)
        try:
            s3.delete_object(Bucket=app.config['ATTACHMENT_S3_BUCKET'],
                             Key=img.s3filename)
        except:
            exceptionReport(g.user.user_db, get_path(), get_path_args(),
                            get_args())
            raise InvalidUsage("s3 delete error. try again", 500)

        img.delete()
        return dict(result=True)
Exemple #2
0
class KakaoSignup(Resource):
    @spec('/kakao/signup',
          'New User Signup With Kakao',
          body_params=[
              ApiParam('kakao_auth_token',
                       'auth token from kakao open sdk',
                       required=True),
              ApiParam('email', 'user email', required=True),
              ApiParam('pwd', 'user password'),
              ApiParam('name', 'real name'),
              ApiParam('birthday', 'birthday', type='date'),
              ApiParam('gender',
                       'gender (male/female)',
                       default='',
                       constraints=[EnumConstraint(['', 'male', 'female'])]),
              ApiParam('place', 'office or home'),
              ApiParam('space', 'Where Arom will be installed'),
              ApiParam('purpose', 'Why use Arom'),
              ApiParam('prefer_scents',
                       'Prefer Scents',
                       type='array',
                       item=ApiParam("item", "item", type="string"))
          ],
          responses=[
              ApiResponse(200, 'User Signup Succeed', dict(result=True)),
              ApiResponse(
                  500, 'User Signup Fail because of DB Issue',
                  {'message': '[email protected] signup failed. Try again.'}),
              ApiResponse.error(403,
                                'Authorization Failed (from kakao server)'),
              ApiResponse.error(403, 'Already existing kakao user'),
              *signup_responses,
          ])
    def post(self):
        args = get_args()
        kauth_token = args['kakao_auth_token']

        resp = KakaoApi.user_info(kauth_token)

        if 'code' in resp:
            raise InvalidUsage("Authorization Failed", 403)

        kakao_id = str(resp['id'])
        properties = resp['properties']
        profile_image = properties['profile_image']
        nickname = properties['nickname']
        thumbnail_image = properties['thumbnail_image']

        if UserModel.objects(kakao_id=kakao_id).first() is not None:
            raise InvalidUsage("Already existing kakao user", 403)

        signup(args, random_pw=True, validate_pw=False, kakao_id=kakao_id)

        return {'result': True}
class FacebookSignup(Resource):
    @spec('/facebook/signup',
          'New User Signup With Facebook',
          body_params=[
              ApiParam('facebook_auth_token',
                       'auth token from facebook open sdk',
                       required=True),
              ApiParam('email', 'user email', required=True),
              ApiParam('name', 'real name'),
              ApiParam('birthday', 'birthday', type='date'),
              ApiParam('gender',
                       'gender (male/female)',
                       default='',
                       constraints=[EnumConstraint(['', 'male', 'female'])]),
              ApiParam('place', 'office or home'),
              ApiParam('space', 'Where Arom will be installed'),
              ApiParam('purpose', 'Why use Arom'),
              ApiParam('prefer_scents',
                       'Prefer Scents',
                       type='array',
                       item=ApiParam("item", "item", type="string"))
          ],
          responses=[
              ApiResponse(200, 'User Signup Succeed', dict(result=True)),
              ApiResponse(
                  500, 'User Signup Fail because of DB Issue',
                  {'message': '[email protected] signup failed. Try again.'}),
              ApiResponse.error(403,
                                'Authorization Failed (from facebook server)'),
              ApiResponse.error(403, 'Already existing facebook user'),
              *signup_responses,
          ])
    def post(self):
        args = get_args()
        fbauth_token = args['facebook_auth_token']

        token_resp = FacebookApi.debug_token(fbauth_token)
        if 'error' in token_resp or not token_resp['data']['is_valid'] or \
                token_resp['data']['app_id'] != app.config['FACEBOOK_APP_ID']:
            raise InvalidUsage("Authroization Failed", 403)
        facebook_id = str(token_resp['data']['user_id'])

        if UserModel.objects(facebook_id=facebook_id).first() is not None:
            raise InvalidUsage("Already existing facebook user", 403)

        signup(args,
               random_pw=True,
               validate_pw=False,
               facebook_id=facebook_id)

        return {'result': True}
Exemple #4
0
class Login(Resource):
    @spec(
        '/auth/login',
        'User Login',
        body_params=[
            ApiParam('email',
                     'user email',
                     required=True,
                     constraints=[LengthConstraint(5, 100)]),
            ApiParam('pwd',
                     'user password',
                     required=True,
                     constraints=[LengthConstraint(4)]),
        ],
        responses=[
            ApiResponse(200, 'Login Succeed', token_example),
            ApiResponse(403, 'User Login Fail because email not signed up',
                        {'message': '[email protected] is not signed up user.'}),
            ApiResponse(400, 'User Login Fail because email/pwd invalid',
                        {'message': 'Password is invalid.'}),
            ApiResponse.error(406, 'Expired Temporary Password')
        ])
    def post(self):
        args = get_args()
        email = args['email'].lower()
        pwd = args['pwd']

        user = User(email, pwd=pwd)

        if not user.is_user():
            err = email + ' is not signed up user.'
            raise InvalidUsage(err, status_code=403)

        is_tmp_pwd = user.check_tmp_pwd(pwd)
        if not user.check_pwd(pwd) and not is_tmp_pwd:
            err = 'Password is invalid.'
            raise InvalidUsage(err, status_code=400)

        if is_tmp_pwd and user.is_expired_tmp_pwd():
            err = 'Expired Temporary Password'
            raise InvalidUsage(err, status_code=406)

        auth_token, refresh_token, exp_time = user.generate_auth_token()
        user.authenticated = True

        result = {
            'auth_token': auth_token,
            'refresh_token': refresh_token,
            'exp_time': exp_time
        }

        if is_tmp_pwd:
            result['used_tmp_pwd'] = is_tmp_pwd

        return result
Exemple #5
0
class ResetPassword(Resource):
    @spec('/auth/reset_password',
          'Request reset password mail',
          body_params=[
              ApiParam('email', 'email to reset password', required=True)
          ],
          responses=[
              ApiResponse(200, 'Email sent', dict(result=True)),
              ApiResponse.error(404, 'User not found'),
              ApiResponse.error(500, 'Email Server Error')
          ])
    def post(self):
        args = get_args()
        user_model = UserModel.objects(email=args['email']).first()
        if user_model is None:
            raise InvalidUsage('User not found', 404)

        tmp_password = gen_pwd()

        body = render_template("pwd_reset_mail.template.html",
                               name=user_model.name,
                               password=tmp_password)

        try:
            charset = 'UTF-8'
            response = apitools.email_client.send_email(
                Destination={'ToAddresses': [user_model.email]},
                Message=dict(
                    Subject=dict(Data="[아롬] 임시 비밀번호 발급", Charset='utf8'),
                    Body=dict(Html=dict(Charset='utf8', Data=str(body)))),
                Source=app.config['CONTACT_EMAIL'])
        except Exception as ex:
            raise InvalidUsage("Email Server Error: {}".format(ex), 500)

        user_model.tmp_password = hash_pwd(tmp_password)
        user_model.tmp_password_valid_period = datetime.datetime.now() + \
                app.config['PASSWORD_RESET_EXPIRE_DURATION']
        user_model.save()

        return dict(result=True)
class DeviceRegister(Resource):
    @spec('/devices/<string:device_id>/register',
          'Register Device ID in User DB Document',
          header_params=[*Swagger.Params.Authorization],
          path_params=[ApiParam('device_id', 'Device ID')],
          responses=[
              ApiResponse(200, 'Register Device Succeed', shadow_example),
              ApiResponse(
                  401, 'Unauthenticated Device',
                  dict(message='This user is not owner of this device.')),
              ApiResponse.error(406, 'Expired Temporary Code'),
              ApiResponse.error(409, "Already Registered Device")
          ])
    @check_auth
    def post(self, device_id):

        user_db = g.user.user_db
        user_id = user_db.user_id
        res = iot_client.get_thing_shadow(thingName=device_id)
        payload = json.loads(res['payload'].read())
        state = payload['state']
        reported = state.get('reported', {})
        desired = state.get('desired', {})

        if device_id in user_db.devices:
            exceptionReport(g.user.user_db, get_path(), get_path_args(),
                            get_args())
            raise InvalidUsage('Already Registered Device', 409)

        if user_id == reported['owner_id']:
            user_db.update(**{'set__devices__' + device_id: device_id})
            user_db.reload()

            return state
        else:
            exceptionReport(g.user.user_db, get_path(), get_path_args(),
                            get_args())
            raise InvalidUsage('This user is not owner of this device.',
                               status_code=401)
Exemple #7
0
              birthday=birthday,
              gender=gender,
              place=place,
              space=space,
              purpose=purpose,
              prefer_scents=prefer_scents).save()

    try:
        user = UserModel.objects.get(email=email)
    except UserModel.DoesNotExist:
        err = email + ' signup failed. Try again.'
        raise InvalidUsage(err, status_code=500)


signup_responses = [
    ApiResponse.error(400, "Password is required"),
    ApiResponse.error(400, "Email is required"),
    ApiResponse.error(400, "Password is not secure one"),
    ApiResponse.error(403, "[email protected] already exists"),
    ApiResponse.error(403, "Email is not valid")
]

response_example = dict(user_id='User ID',
                        email='User E-Mail',
                        name='User Name',
                        birthday='2017-12-31T23:59:59',
                        gender='Female',
                        picture='User Profile Picture img_src',
                        devices={'Device ID': 'Device Name'})

Exemple #8
0
class AttachmentList(Resource):
    @spec('/attachments',
          'Get My Attachment List',
          header_params=Swagger.Params.Authorization,
          query_params=Swagger.Params.Page,
          responses=[
              ApiResponse(
                  200, "Succeed",
                  dict(attachments=[attachment_example],
                       limit=20,
                       total_size=100))
          ])
    @check_auth
    def get(self):
        args = get_args()
        offset = args['offset']
        limit = args['limit']

        user_id = g.user.user_db.user_id
        query = ImageAttachmentModel.objects(user_id=user_id)

        attachments = query[offset:offset + limit]

        return dict(
            attachments=seq(attachments).map(lambda x: x.marshall()).list(),
            limit=limit,
            total_size=len(query))

    @spec('/attachments',
          'Post Image Attachment',
          header_params=Swagger.Params.Authorization,
          body_type="data",
          body_params=[ApiParam("image", type="file", required=True)],
          responses=[
              ApiResponse(200, "Succeed", attachment_example),
              ApiResponse.error(400, "Invalid Image Type"),
              ApiResponse.error(500, "s3 upload error. try again")
          ])
    @check_auth
    def post(self):
        args = get_args()
        image = args['image']
        if not image.content_type.startswith('image'):
            exceptionReport(g.user.user_db, get_path(), get_path_args(),
                            get_args())
            raise InvalidUsage("Invalid Image Type", 400)

        extension = image.filename.split('.')[-1]

        image_model = ImageAttachmentModel(user_id=g.user.user_db.user_id,
                                           extension=extension,
                                           orignal_name=image.filename)
        image_model.save()

        key = image_model.s3filename
        upload_config = TransferConfig(use_threads=False)

        try:
            result = s3.upload_fileobj(image,
                                       app.config['ATTACHMENT_S3_BUCKET'],
                                       key,
                                       ExtraArgs={
                                           "ACL": "public-read",
                                           "ContentType": image.content_type
                                       },
                                       Config=upload_config)
        except:
            image_model.delete()
            exceptionReport(g.user.user_db, get_path(), get_path_args(),
                            get_args())
            raise InvalidUsage("s3 upload error. try again", 500)

        return image_model.marshall()