def post(self): """POST action to authorize the Client Application. To authorize will be send a POST with 'grant' parameter set to true, to deny 'parameter' set to false.""" grant = self.get_argument("grant") client_id = self.get_argument("client_id") response_type = self.get_argument("response_type") redirect_uri = self.get_argument("redirect_uri") scope = self.get_argument("scope") # the client send correct paramenters, we need to check if the client id exist and we # create the relation between the user-agent and the client if grant == "true": try: #check if the client exist client = Client() exist = client.get(client_id=client_id) if exist['redirect_uri'] != redirect_uri: #have an error, return a 403 raise tornado.web.HTTPError(403,"redirect uri problem") except ObjectDoesNotExist, e: raise tornado.web.HTTPError(403,"the client id not correspond to any Client") grant = Grant() try: #we accept the grant for the user grant.is_already_authorized(client_id,self.get_current_user()) grant.update(client_id,self.get_current_user()) except ObjectDoesNotExist, e: grant.add(client_id,self.get_current_user())
def get(self): """This Method check if the Application Client exist, if yes redirect to the login page. In Case something goes wrong the Handler return a 400 status code if the Client Id does not exist and 400 if the parameters send are not correct.""" client_id = self.get_argument("client_id") response_type = self.get_argument("response_type") redirect_uri = self.get_argument("redirect_uri") scope = self.get_argument("scope") # before check if the client pass client_id, redirect_url and response_type # we accept only token "Implicit Grant Flow" # if all is ok we need to check if the client_id and the redirect_uri are correct # if not we return a 403 to the client if response_type in ("token","code"): try: client_check = Client() exist = client_check.get(client_id=client_id) #check the redirect_uri parameter if exist['redirect_uri'] != redirect_uri: #have an error, return a 403 raise tornado.web.HTTPError(403,"redirect uri problem") # redirect to login page self.redirect(("/auth/login?client_id=%s&response_type=%s&redirect_uri=%s&scope=%s")%(client_id, response_type, urllib.quote_plus(redirect_uri), scope)) except ObjectDoesNotExist, e: raise tornado.web.HTTPError(403)
def generate_fakes(): Author.generate_fake() BookDetails.generate_fake() BookInventory.generate_fake() Client.generate_fake() Person.generate_fake() Volunteer.generate_fake() Donor.generate_fake()
def test_client_bad_init(self): c = Client('Alice', '*****@*****.**', '+79099946885') c.password = '******' db.session.add(c) flag = False try: db.session.commit() except: flag = True self.assertTrue(flag)
def test_client_unique(self): c1 = Client('Alice', '*****@*****.**', '+79099946885') c2 = Client('Alice', '*****@*****.**', '+79099946885') c1.password = '******' c2.password = '******' db.session.add(c1) db.session.add(c2) flag = False try: db.session.commit() except: flag = True self.assertTrue(flag)
def get(self): """This is the form where the user accept or denied the access to the Application Client. In this test the form is not returned.""" client_id = self.get_argument("client_id") response_type = self.get_argument("response_type") redirect_uri = self.get_argument("redirect_uri") scope = self.get_argument("scope") try: #check if the client exist client = Client() exist = client.get(client_id=client_id) if exist['redirect_uri'] != redirect_uri: #have an error, return a 403 raise tornado.web.HTTPError(403,"redirect uri problem") except ObjectDoesNotExist, e: raise tornado.web.HTTPError(403,"the client id not correspond to any Client")
def get(self): """Get method. return the token and the refresh if all the parameters passed are correct.""" code = self.get_argument("code") client_id = self.get_argument("client_id") client_secret = self.get_argument("client_secret") redirect_uri = self.get_argument("redirect_uri") grant_type = self.get_argument("grant_type") try: client_check = Client() exist = client_check.get(client_id=client_id) if exist["redirect_uri"] != redirect_uri: # have an error, return a 403 raise tornado.web.HTTPError(403, "redirect uri problem") # check the redirect_uri parameter token_result = client_check.authenticate(client_id, client_secret, code) self.redirect( (redirect_uri + "?access_token=%s&expires_in=%s&token_type=Bearer") % (token_result["token"], 3600) ) except ObjectDoesNotExist, e: raise tornado.web.HTTPError(403)
def new_client() -> Response: client: Client = Client.from_json(request.json) db.session.add(client) db.session.commit() return jsonify(client.to_json()), 201
def add_to_org(sender, **kwargs): org = sender.objects.last() user = org.creator member, created = OrganisationMember.objects.get_or_create(org=org, member=user) if created: tld = tldextract.extract(org.url) client = Client() client.name = org.name client.organisation = org client.schema_name = org.slug client.paid_until = datetime.now() + timedelta(days=90) try: client.domain_url = tld.domain client.save() except KeyError: try: client.domain_url = tld.domain + '-' + tld.subdomain client.save() except KeyError: client.domain_url = org.slug client.save()
def fake_data(): LOG.d("create fake data") # Remove db if exist if os.path.exists("db.sqlite"): LOG.d("remove existing db file") os.remove("db.sqlite") # Create all tables db.create_all() # Create a user user = User.create( email="*****@*****.**", name="John Wick", password="******", activated=True, is_admin=True, ) db.session.commit() # Create a subscription for user Subscription.create( user_id=user.id, cancel_url="https://checkout.paddle.com/subscription/cancel?user=1234", update_url="https://checkout.paddle.com/subscription/update?user=1234", subscription_id="123", event_time=arrow.now(), next_bill_date=arrow.now().shift(days=10).date(), plan=PlanEnum.monthly, ) db.session.commit() api_key = ApiKey.create(user_id=user.id, name="Chrome") api_key.code = "code" GenEmail.create_new(user.id, "e1@") GenEmail.create_new(user.id, "e2@") GenEmail.create_new(user.id, "e3@") CustomDomain.create(user_id=user.id, domain="ab.cd", verified=True) CustomDomain.create( user_id=user.id, domain="very-long-domain.com.net.org", verified=True ) db.session.commit() # Create a client client1 = Client.create_new(name="Demo", user_id=user.id) client1.oauth_client_id = "client-id" client1.oauth_client_secret = "client-secret" client1.published = True db.session.commit() RedirectUri.create(client_id=client1.id, uri="https://ab.com") client2 = Client.create_new(name="Demo 2", user_id=user.id) client2.oauth_client_id = "client-id2" client2.oauth_client_secret = "client-secret2" client2.published = True db.session.commit() db.session.commit()
def setting(): form = SettingForm() promo_form = PromoCodeForm() change_email_form = ChangeEmailForm() email_change = EmailChange.get_by(user_id=current_user.id) if email_change: pending_email = email_change.new_email else: pending_email = None if request.method == "POST": if request.form.get("form-name") == "update-email": if change_email_form.validate(): # whether user can proceed with the email update new_email_valid = True if (change_email_form.email.data.lower().strip() != current_user.email and not pending_email): new_email = change_email_form.email.data.strip().lower() # check if this email is not already used if personal_email_already_used(new_email) or Alias.get_by( email=new_email): flash(f"Email {new_email} already used", "error") new_email_valid = False elif not email_can_be_used_as_mailbox(new_email): flash( "You cannot use this email address as your personal inbox.", "error", ) new_email_valid = False # a pending email change with the same email exists from another user elif EmailChange.get_by(new_email=new_email): other_email_change: EmailChange = EmailChange.get_by( new_email=new_email) LOG.warning( "Another user has a pending %s with the same email address. Current user:%s", other_email_change, current_user, ) if other_email_change.is_expired(): LOG.d("delete the expired email change %s", other_email_change) EmailChange.delete(other_email_change.id) db.session.commit() else: flash( "You cannot use this email address as your personal inbox.", "error", ) new_email_valid = False if new_email_valid: email_change = EmailChange.create( user_id=current_user.id, code=random_string( 60), # todo: make sure the code is unique new_email=new_email, ) db.session.commit() send_change_email_confirmation(current_user, email_change) flash( "A confirmation email is on the way, please check your inbox", "success", ) return redirect(url_for("dashboard.setting")) if request.form.get("form-name") == "update-profile": if form.validate(): profile_updated = False # update user info if form.name.data != current_user.name: current_user.name = form.name.data db.session.commit() profile_updated = True if form.profile_picture.data: file_path = random_string(30) file = File.create(user_id=current_user.id, path=file_path) s3.upload_from_bytesio( file_path, BytesIO(form.profile_picture.data.read())) db.session.flush() LOG.d("upload file %s to s3", file) current_user.profile_picture_id = file.id db.session.commit() profile_updated = True if profile_updated: flash("Your profile has been updated", "success") return redirect(url_for("dashboard.setting")) elif request.form.get("form-name") == "change-password": flash( "You are going to receive an email containing instructions to change your password", "success", ) send_reset_password_email(current_user) return redirect(url_for("dashboard.setting")) elif request.form.get("form-name") == "notification-preference": choose = request.form.get("notification") if choose == "on": current_user.notification = True else: current_user.notification = False db.session.commit() flash("Your notification preference has been updated", "success") return redirect(url_for("dashboard.setting")) elif request.form.get("form-name") == "delete-account": LOG.warning("Delete account %s", current_user) User.delete(current_user.id) db.session.commit() flash("Your account has been deleted", "success") logout_user() return redirect(url_for("auth.register")) elif request.form.get("form-name") == "change-alias-generator": scheme = int(request.form.get("alias-generator-scheme")) if AliasGeneratorEnum.has_value(scheme): current_user.alias_generator = scheme db.session.commit() flash("Your preference has been updated", "success") return redirect(url_for("dashboard.setting")) elif request.form.get( "form-name") == "change-random-alias-default-domain": default_domain = request.form.get("random-alias-default-domain") if default_domain: sl_domain: SLDomain = SLDomain.get_by(domain=default_domain) if sl_domain: if sl_domain.premium_only and not current_user.is_premium( ): flash("You cannot use this domain", "error") return redirect(url_for("dashboard.setting")) # make sure only default_random_alias_domain_id or default_random_alias_public_domain_id is set current_user.default_random_alias_public_domain_id = sl_domain.id current_user.default_random_alias_domain_id = None else: custom_domain = CustomDomain.get_by(domain=default_domain) if custom_domain: # sanity check if (custom_domain.user_id != current_user.id or not custom_domain.verified): LOG.exception("%s cannot use domain %s", current_user, default_domain) else: # make sure only default_random_alias_domain_id or # default_random_alias_public_domain_id is set current_user.default_random_alias_domain_id = ( custom_domain.id) current_user.default_random_alias_public_domain_id = None else: current_user.default_random_alias_domain_id = None current_user.default_random_alias_public_domain_id = None db.session.commit() flash("Your preference has been updated", "success") return redirect(url_for("dashboard.setting")) elif request.form.get("form-name") == "change-sender-format": sender_format = int(request.form.get("sender-format")) if SenderFormatEnum.has_value(sender_format): current_user.sender_format = sender_format db.session.commit() flash("Your sender format preference has been updated", "success") db.session.commit() return redirect(url_for("dashboard.setting")) elif request.form.get("form-name") == "replace-ra": choose = request.form.get("replace-ra") if choose == "on": current_user.replace_reverse_alias = True else: current_user.replace_reverse_alias = False db.session.commit() flash("Your preference has been updated", "success") return redirect(url_for("dashboard.setting")) elif request.form.get("form-name") == "sender-in-ra": choose = request.form.get("enable") if choose == "on": current_user.include_sender_in_reverse_alias = True else: current_user.include_sender_in_reverse_alias = False db.session.commit() flash("Your preference has been updated", "success") return redirect(url_for("dashboard.setting")) elif request.form.get("form-name") == "export-data": data = { "email": current_user.email, "name": current_user.name, "aliases": [], "apps": [], "custom_domains": [], } for alias in Alias.filter_by( user_id=current_user.id).all(): # type: Alias data["aliases"].append( dict(email=alias.email, enabled=alias.enabled)) for custom_domain in CustomDomain.filter_by( user_id=current_user.id).all(): data["custom_domains"].append(custom_domain.domain) for app in Client.filter_by( user_id=current_user.id): # type: Client data["apps"].append( dict(name=app.name, home_url=app.home_url, published=app.published)) return Response( json.dumps(data), mimetype="text/json", headers={ "Content-Disposition": "attachment;filename=data.json" }, ) elif request.form.get("form-name") == "export-alias": data = [["alias", "note", "enabled"]] for alias in Alias.filter_by( user_id=current_user.id).all(): # type: Alias data.append([alias.email, alias.note, alias.enabled]) si = StringIO() cw = csv.writer(si) cw.writerows(data) output = make_response(si.getvalue()) output.headers[ "Content-Disposition"] = "attachment; filename=aliases.csv" output.headers["Content-type"] = "text/csv" return output manual_sub = ManualSubscription.get_by(user_id=current_user.id) coinbase_sub = CoinbaseSubscription.get_by(user_id=current_user.id) return render_template( "dashboard/setting.html", form=form, PlanEnum=PlanEnum, SenderFormatEnum=SenderFormatEnum, promo_form=promo_form, change_email_form=change_email_form, pending_email=pending_email, AliasGeneratorEnum=AliasGeneratorEnum, manual_sub=manual_sub, coinbase_sub=coinbase_sub, FIRST_ALIAS_DOMAIN=FIRST_ALIAS_DOMAIN, )
def test_func_get_id(self): client = Client(email='email') db.session.add(client) db.session.commit() self.assertEqual(client.id, Client.get_id(client.email))
def test_func_email_is_free(self): client = Client(email='email') db.session.add(client) db.session.commit() self.assertFalse(Client.email_is_free('email')) self.assertTrue(Client.email_is_free('email1'))
def test_authorize_code_id_token_flow(flask_client): """make sure the authorize redirects user to correct page for the *ID-Token Code Flow* , ie when response_type=id_token,code The /authorize endpoint should return an id_token, code and id_token must contain *c_hash* The /token endpoint must return a access_token and an id_token """ user = login(flask_client) client = Client.create_new("test client", user.id) db.session.commit() # user allows client on the authorization page r = flask_client.post( url_for( "oauth.authorize", client_id=client.oauth_client_id, state="teststate", redirect_uri="http://localhost", response_type="id_token code", # id_token,code flow ), data={ "button": "allow", "suggested-email": "[email protected]", "suggested-name": "AB CD" }, # user will be redirected to client page, do not allow redirection here # to assert the redirect url # follow_redirects=True, ) assert r.status_code == 302 # user gets redirected back to client page # r.location will have this form http://localhost?state=teststate&code=knuyjepwvg o = urlparse(r.location) assert o.netloc == "localhost" assert not o.fragment assert o.query # parse the query, should return something like # {'state': ['teststate'], 'id_token': ['knuyjepwvg'], 'code': ['longstring']} queries = parse_qs(o.query) assert len(queries) == 3 assert queries["state"] == ["teststate"] assert len(queries["id_token"]) == 1 assert len(queries["code"]) == 1 # id_token must be a valid, correctly signed JWT id_token = queries["id_token"][0] assert verify_id_token(id_token) # make sure jwt has all the necessary fields jwt = decode_id_token(id_token) # payload should have this format # { # 'at_hash': 'jLDmoGpuOIHwxeyFEe9SKw', # 'aud': 'testclient-sywcpwsyua', # 'auth_time': 1565450736, # 'avatar_url': None, # 'client': 'test client', # 'email': '[email protected]', # 'email_verified': True, # 'exp': 1565454336, # 'iat': 1565450736, # 'id': 1, # 'iss': 'http://localhost', # 'name': 'AB CD', # 'sub': '1' # } payload = json.loads(jwt.claims) # at_hash MUST be present when the flow is id_token,token assert "c_hash" in payload assert "aud" in payload assert "auth_time" in payload assert "avatar_url" in payload assert "client" in payload assert "email" in payload assert "email_verified" in payload assert "exp" in payload assert "iat" in payload assert "id" in payload assert "iss" in payload assert "name" in payload assert "sub" in payload # <<< Exchange the code to get access_token >>> basic_auth_headers = base64.b64encode( f"{client.oauth_client_id}:{client.oauth_client_secret}".encode( )).decode("utf-8") r = flask_client.post( url_for("oauth.token"), headers={"Authorization": "Basic " + basic_auth_headers}, data={ "grant_type": "authorization_code", "code": queries["code"][0] }, ) # r.json should have this format # { # 'access_token': 'avmhluhonsouhcwwailydwvhankspptgidoggcbu', # 'id_token': 'ab.cd.xy', # 'expires_in': 3600, # 'scope': '', # 'token_type': 'bearer', # 'user': { # 'avatar_url': None, # 'client': 'test client', # 'email': '[email protected]', # 'email_verified': True, # 'id': 1, # 'name': 'AB CD' # } # } assert r.status_code == 200 assert r.json["access_token"] assert r.json["expires_in"] == 3600 assert not r.json["scope"] assert r.json["token_type"] == "Bearer" assert r.json["user"] == { "avatar_url": None, "client": "test client", "email": "[email protected]", "email_verified": True, "id": 1, "name": "AB CD", "sub": "1", } # id_token must be returned assert r.json["id_token"] # id_token must be a valid, correctly signed JWT assert verify_id_token(r.json["id_token"])
def post_user(): user = Client(request.form['first_name'], request.form['last_name']) db.session.add(user) db.session.commit() return redirect(url_for('index'))
def fake_data(): LOG.d("create fake data") # Remove db if exist if os.path.exists("db.sqlite"): LOG.d("remove existing db file") os.remove("db.sqlite") # Create all tables db.create_all() # Create a user user = User.create( email="*****@*****.**", name="John Wick", password="******", activated=True, is_admin=True, enable_otp=False, otp_secret="base32secret3232", intro_shown=True, fido_uuid=None, ) user.include_sender_in_reverse_alias = None db.session.commit() user.trial_end = None LifetimeCoupon.create(code="coupon", nb_used=10) db.session.commit() # Create a subscription for user Subscription.create( user_id=user.id, cancel_url="https://checkout.paddle.com/subscription/cancel?user=1234", update_url="https://checkout.paddle.com/subscription/update?user=1234", subscription_id="123", event_time=arrow.now(), next_bill_date=arrow.now().shift(days=10).date(), plan=PlanEnum.monthly, ) db.session.commit() api_key = ApiKey.create(user_id=user.id, name="Chrome") api_key.code = "code" api_key = ApiKey.create(user_id=user.id, name="Firefox") api_key.code = "codeFF" pgp_public_key = open(get_abs_path("local_data/public-pgp.asc")).read() m1 = Mailbox.create( user_id=user.id, email="*****@*****.**", verified=True, pgp_public_key=pgp_public_key, ) m1.pgp_finger_print = load_public_key(pgp_public_key) db.session.commit() for i in range(3): if i % 2 == 0: a = Alias.create(email=f"e{i}@{FIRST_ALIAS_DOMAIN}", user_id=user.id, mailbox_id=m1.id) else: a = Alias.create( email=f"e{i}@{FIRST_ALIAS_DOMAIN}", user_id=user.id, mailbox_id=user.default_mailbox_id, ) db.session.commit() if i % 5 == 0: if i % 2 == 0: AliasMailbox.create(alias_id=a.id, mailbox_id=user.default_mailbox_id) else: AliasMailbox.create(alias_id=a.id, mailbox_id=m1.id) db.session.commit() # some aliases don't have any activity # if i % 3 != 0: # contact = Contact.create( # user_id=user.id, # alias_id=a.id, # website_email=f"contact{i}@example.com", # reply_email=f"rep{i}@sl.local", # ) # db.session.commit() # for _ in range(3): # EmailLog.create(user_id=user.id, contact_id=contact.id) # db.session.commit() # have some disabled alias if i % 5 == 0: a.enabled = False db.session.commit() CustomDomain.create(user_id=user.id, domain="ab.cd", verified=True) CustomDomain.create(user_id=user.id, domain="very-long-domain.com.net.org", verified=True) db.session.commit() Directory.create(user_id=user.id, name="abcd") Directory.create(user_id=user.id, name="xyzt") db.session.commit() # Create a client client1 = Client.create_new(name="Demo", user_id=user.id) client1.oauth_client_id = "client-id" client1.oauth_client_secret = "client-secret" client1.published = True db.session.commit() RedirectUri.create(client_id=client1.id, uri="https://ab.com") client2 = Client.create_new(name="Demo 2", user_id=user.id) client2.oauth_client_id = "client-id2" client2.oauth_client_secret = "client-secret2" client2.published = True db.session.commit() ClientUser.create(user_id=user.id, client_id=client1.id, name="Fake Name") referral = Referral.create(user_id=user.id, code="REFCODE", name="First referral") db.session.commit() for i in range(6): Notification.create(user_id=user.id, message=f"""Hey hey <b>{i}</b> """ * 10) db.session.commit() User.create( email="*****@*****.**", name="Winston", password="******", activated=True, referral_id=referral.id, ) db.session.commit()
username3 = User('username3', '*****@*****.**', bcrypt.generate_password_hash('12345678')) username4 = User('username4', '*****@*****.**', bcrypt.generate_password_hash('12345678')) username5 = User('username5', '*****@*****.**', bcrypt.generate_password_hash('12345678')) user = User('username', '*****@*****.**', bcrypt.generate_password_hash('12345678')) db.session.add(user) db.session.add(username1) db.session.add(username2) db.session.add(username3) db.session.add(username4) db.session.add(username5) clientA = Client('Client A') clientB = Client('Client B') clientC = Client('Client C') clientD = Client('Client D') db.session.add(clientA) db.session.add(clientB) db.session.add(clientC) db.session.add(clientD) policies = ProductArea('Policies') claims = ProductArea('Claims') billing = ProductArea('Billing') reports = ProductArea('Reports') db.session.add(policies) db.session.add(claims) db.session.add(billing)
def __init__(self, id=None): if id is not None: self.data = Client().find(id) self.new = False else: self.new = True
def test_client_model(self): c = Client('Client A', '*****@*****.**') db.session.add(c) db.session.commit() assert c.id > 0 assert 'Client' in repr(c)
def fake_data(): LOG.d("create fake data") # Remove db if exist if os.path.exists("db.sqlite"): LOG.d("remove existing db file") os.remove("db.sqlite") # Create all tables db.create_all() # Create a user user = User.create( email="*****@*****.**", name="John Wick", password="******", activated=True, is_admin=True, # enable_otp=True, otp_secret="base32secret3232", intro_shown=True, fido_uuid=None, ) user.trial_end = None db.session.commit() # add a profile picture file_path = "profile_pic.svg" s3.upload_from_bytesio( file_path, open(os.path.join(ROOT_DIR, "static", "default-icon.svg"), "rb"), content_type="image/svg", ) file = File.create(user_id=user.id, path=file_path, commit=True) user.profile_picture_id = file.id db.session.commit() # create a bounced email alias = Alias.create_new_random(user) db.session.commit() bounce_email_file_path = "bounce.eml" s3.upload_email_from_bytesio( bounce_email_file_path, open(os.path.join(ROOT_DIR, "local_data", "email_tests", "2.eml"), "rb"), "download.eml", ) refused_email = RefusedEmail.create( path=bounce_email_file_path, full_report_path=bounce_email_file_path, user_id=user.id, commit=True, ) contact = Contact.create( user_id=user.id, alias_id=alias.id, website_email="*****@*****.**", reply_email="*****@*****.**", commit=True, ) EmailLog.create( user_id=user.id, contact_id=contact.id, refused_email_id=refused_email.id, bounced=True, commit=True, ) LifetimeCoupon.create(code="coupon", nb_used=10, commit=True) # Create a subscription for user Subscription.create( user_id=user.id, cancel_url="https://checkout.paddle.com/subscription/cancel?user=1234", update_url="https://checkout.paddle.com/subscription/update?user=1234", subscription_id="123", event_time=arrow.now(), next_bill_date=arrow.now().shift(days=10).date(), plan=PlanEnum.monthly, commit=True, ) CoinbaseSubscription.create( user_id=user.id, end_at=arrow.now().shift(days=10), commit=True ) api_key = ApiKey.create(user_id=user.id, name="Chrome") api_key.code = "code" api_key = ApiKey.create(user_id=user.id, name="Firefox") api_key.code = "codeFF" pgp_public_key = open(get_abs_path("local_data/public-pgp.asc")).read() m1 = Mailbox.create( user_id=user.id, email="*****@*****.**", verified=True, pgp_public_key=pgp_public_key, ) m1.pgp_finger_print = load_public_key(pgp_public_key) db.session.commit() for i in range(3): if i % 2 == 0: a = Alias.create( email=f"e{i}@{FIRST_ALIAS_DOMAIN}", user_id=user.id, mailbox_id=m1.id ) else: a = Alias.create( email=f"e{i}@{FIRST_ALIAS_DOMAIN}", user_id=user.id, mailbox_id=user.default_mailbox_id, ) db.session.commit() if i % 5 == 0: if i % 2 == 0: AliasMailbox.create(alias_id=a.id, mailbox_id=user.default_mailbox_id) else: AliasMailbox.create(alias_id=a.id, mailbox_id=m1.id) db.session.commit() # some aliases don't have any activity # if i % 3 != 0: # contact = Contact.create( # user_id=user.id, # alias_id=a.id, # website_email=f"contact{i}@example.com", # reply_email=f"rep{i}@sl.local", # ) # db.session.commit() # for _ in range(3): # EmailLog.create(user_id=user.id, contact_id=contact.id) # db.session.commit() # have some disabled alias if i % 5 == 0: a.enabled = False db.session.commit() custom_domain1 = CustomDomain.create(user_id=user.id, domain="ab.cd", verified=True) db.session.commit() Alias.create( user_id=user.id, email="*****@*****.**", mailbox_id=user.default_mailbox_id, custom_domain_id=custom_domain1.id, commit=True, ) Alias.create( user_id=user.id, email="*****@*****.**", mailbox_id=user.default_mailbox_id, custom_domain_id=custom_domain1.id, commit=True, ) Directory.create(user_id=user.id, name="abcd") Directory.create(user_id=user.id, name="xyzt") db.session.commit() # Create a client client1 = Client.create_new(name="Demo", user_id=user.id) client1.oauth_client_id = "client-id" client1.oauth_client_secret = "client-secret" db.session.commit() RedirectUri.create( client_id=client1.id, uri="https://your-website.com/oauth-callback" ) client2 = Client.create_new(name="Demo 2", user_id=user.id) client2.oauth_client_id = "client-id2" client2.oauth_client_secret = "client-secret2" db.session.commit() ClientUser.create(user_id=user.id, client_id=client1.id, name="Fake Name") referral = Referral.create(user_id=user.id, code="Website", name="First referral") Referral.create(user_id=user.id, code="Podcast", name="First referral") Payout.create( user_id=user.id, amount=1000, number_upgraded_account=100, payment_method="BTC" ) Payout.create( user_id=user.id, amount=5000, number_upgraded_account=200, payment_method="PayPal", ) db.session.commit() for i in range(6): Notification.create(user_id=user.id, message=f"""Hey hey <b>{i}</b> """ * 10) db.session.commit() user2 = User.create( email="*****@*****.**", password="******", activated=True, referral_id=referral.id, ) Mailbox.create(user_id=user2.id, email="*****@*****.**", verified=True) db.session.commit() ManualSubscription.create( user_id=user2.id, end_at=arrow.now().shift(years=1, days=1), comment="Local manual", commit=True, )
def addUpdateClient(self, old_client_name, new_client_name, product_name, cluster_name, release_number): try: #check if the new client already exists or not exists_client = db.session.query(Client.client_name).filter( Client.client_name == new_client_name).scalar() is not None #if not exists then add new client record if not exists_client: client = Client(client_name=new_client_name, is_active=True) db.session.add(client) db.session.commit() print("New client is being added!!!!!!!!") # make the old client record as inactive if old_client_name != "": self.deactivateClient(old_client_name) self.deactivateCPRC(old_client_name, product_name, cluster_name, release_number) #add new cprc record with new client self.addCPRC(new_client_name, product_name, cluster_name, release_number) #if the new client already exists then mark it as active client, deactivate cprc for old and add new cprc record if exists_client: client = db.session.query(Client).filter( Client.client_name == new_client_name).first() if client: client.is_active = True db.session.commit() exists_cprc = self.checkCPRCExists(new_client_name, cluster_name, product_name, release_number) #if the cprc entry already exists then make it as active if exists_cprc is not None: if exists_cprc.is_active == False: exists_cprc.is_active = True db.session.commit() self.deactivateClient(old_client_name) self.deactivateCPRC(old_client_name, product_name, cluster_name, release_number) return "Client-cprc record already exists" #else add new cprc record and deactivate the old record else: self.deactivateCPRC(old_client_name, product_name, cluster_name, release_number) self.addCPRC(new_client_name, product_name, cluster_name, release_number) except Exception as ex: date = datetime.utcnow() tb = sys.exc_info()[2] errorMsg = str( date ) + " - File: addUpdateDB.py - Function: addUpdateClient - " + str( ex.args) + " - on line " + str(tb.tb_lineno) + " \r\n" f.write(errorMsg) f.close()
def setUp(self): TestFactory.setUp(self) client = Client(nombre="AGENCIA TUDAD", email="*****@*****.**") db.session.add(client) db.session.commit() self.path = '/clients'
def test_authorize_code_flow_with_openid_scope(flask_client): """make sure the authorize redirects user to correct page for the *Code Flow* and when the *openid* scope is present , ie when response_type=code, openid in scope The authorize endpoint should stay the same: return the *code*. The token endpoint however should now return id_token in addition to the access_token """ user = login(flask_client) client = Client.create_new("test client", user.id) db.session.commit() # user allows client on the authorization page r = flask_client.post( url_for( "oauth.authorize", client_id=client.oauth_client_id, state="teststate", redirect_uri="http://localhost", response_type="code", scope="openid", # openid is in scope ), data={ "button": "allow", "suggested-email": "[email protected]", "suggested-name": "AB CD" }, # user will be redirected to client page, do not allow redirection here # to assert the redirect url # follow_redirects=True, ) assert r.status_code == 302 # user gets redirected back to client page # r.location will have this form http://localhost?state=teststate&code=knuyjepwvg o = urlparse(r.location) assert o.netloc == "localhost" assert not o.fragment # parse the query, should return something like # {'state': ['teststate'], 'code': ['knuyjepwvg'], 'scope': ["openid"]} queries = parse_qs(o.query) assert len(queries) == 3 assert queries["state"] == ["teststate"] assert len(queries["code"]) == 1 # Exchange the code to get access_token basic_auth_headers = base64.b64encode( f"{client.oauth_client_id}:{client.oauth_client_secret}".encode( )).decode("utf-8") r = flask_client.post( url_for("oauth.token"), headers={"Authorization": "Basic " + basic_auth_headers}, data={ "grant_type": "authorization_code", "code": queries["code"][0] }, ) # r.json should have this format # { # 'access_token': 'avmhluhonsouhcwwailydwvhankspptgidoggcbu', # 'expires_in': 3600, # 'scope': '', # 'token_type': 'bearer', # 'user': { # 'avatar_url': None, # 'client': 'test client', # 'email': '[email protected]', # 'email_verified': True, # 'id': 1, # 'name': 'AB CD' # } # } assert r.status_code == 200 assert r.json["access_token"] assert r.json["expires_in"] == 3600 assert r.json["scope"] == "openid" assert r.json["token_type"] == "Bearer" assert r.json["user"] == { "avatar_url": None, "client": "test client", "email": "[email protected]", "email_verified": True, "id": 1, "name": "AB CD", "sub": "1", } # id_token must be returned assert r.json["id_token"] # id_token must be a valid, correctly signed JWT assert verify_id_token(r.json["id_token"])
from app import db from datetime import datetime from app.models import Product, Product_Release, Client #this file cretes the database schema and pre populates the table db.create_all() product = Product(product_name="UNKNOWN") client = Client(client_name="UNKNOWN") product_release = Product_Release(product_id=1, release_number="UNKNOWN",inserted_at=datetime.utcnow()) db.session.add(product) db.session.add(client) db.session.add(product_release) db.session.commit() print("DB Created")
def initial(request): if Company.objects.count() == 0: Company.objects.create(name="pushe") Criteria.objects.all().delete() my_tickets = Criteria.objects.create(name="My Tickets") i_follow = Criteria.objects.create(name="Tickets I Follow") my_team = Criteria.objects.create(name="My Team's Tickets") unassigned = Criteria.objects.create(name="Unassigned Tickets") all = Criteria.objects.create(name="All Tickets") clause_my_tickets = CriteriaClause.objects.create(criteria=my_tickets) clause_i_follow = CriteriaClause.objects.create(criteria=i_follow) clause_my_team = CriteriaClause.objects.create(criteria=my_team) clause_unassigned = CriteriaClause.objects.create(criteria=unassigned) clause_all = CriteriaClause.objects.create(criteria=all) single_my_tickets = SingleCriteria.objects.create( criteria_clause=clause_my_tickets, field="assigned_to", operation="is", value="shooka_current_agent") single_i_follow = SingleCriteria.objects.create( criteria_clause=clause_i_follow, field="followers", operation="is", value="shooka_current_agent") single_my_team = SingleCriteria.objects.create( criteria_clause=clause_my_team, field="assigned_team", operation="is", value="shooka_current_agent_team") single_unassigned = SingleCriteria.objects.create( criteria_clause=clause_unassigned, field="assigned_to", operation="isnull", value="True", value_type="boolean") single_all = SingleCriteria.objects.create(criteria_clause=clause_all, field="pk", operation="isnull", value="", value_type="boolean") if User.objects.count() == 0: user = User.objects.create(first_name="amirhossein", email="*****@*****.**", username="******", company=Company.objects.first(), is_staff=True, is_superuser=True) user.set_password("123123") user.save() Client.objects.all().delete() Message.objects.all().delete() Ticket.objects.all().delete() for i in range(100): client_profile = ClientProfile(name=generate_text(5) + "client") client_profile.save() client = Client(profile=client_profile, email=generate_text(5) + "@gmail.com") client.save() message = Message(client_sender=client, title=generate_text(15), content='<p>' + generate_text(20) + '</p>') message.save() return HttpResponse("done")
def toggl_api(duration=None): # Check WorkSpace workspace = Workspace.query.filter_by(id=WORKSPACE_ID).first() if workspace is None: workspace = Workspace(id=WORKSPACE_ID, name='Vitamin') db.session.add(workspace) db.session.commit() PARAMET_URL = urllib.parse.urlencode({ 'workspace_id': workspace.id, 'since': '2018-09-01T00:00:00Z', # Sep 2018 'until': '2018-10-31T00:00:00Z', # Out 2010 'user_agent': USER_AGENT, }) # GET all Workspace members users = toggl.request(''.join([WORKSPACES_URL, str(workspace.id), '/users'])) for user in users: member = Member.query.filter_by(id=user.get('id')).first() if member is None: member = Member( id=user.get('id'), name=user.get('fullname'), email=user.get('email')) db.session.add(member) db.session.commit() # GET Detailed report time entries response = toggl.request(''.join([REPORTS_URL, 'details?', PARAMET_URL])) for data in response.get('data'): client = Client.query.filter_by(name=data.get('client')).first() if client is None: client = Client(name=data.get('client') or '(no client)') db.session.add(client) member = Member.query.filter_by(id=data.get('uid')).first() if member is None: member = Member(id=data.get('uid'), name=data.get('user')) db.session.add(member) project = Project.query.filter_by(id=data.get('pid')).first() if project is None: project = Project( name=data.get('project') or '(without a project)', workspace_id=workspace.id, client_id=client.id) if data.get('pid') is not None: project.id = data.get('pid') # GET all Project members project_users = toggl.request(''.join( [PROJECTS_URL, str(data.get('pid')), '/project_users'])) for user in project_users: member = Member.query.filter_by(id=user.get('uid')).first() project.members.append(member) db.session.add(project) db.session.commit() if data.get('dur') > DEFAULT_LONG_TASK: task = Task.query.filter_by(id=data.get('id')).first() if task is None: task = Task( id=data.get('id'), name=data.get('description') or '(no description)', project_id=project.id, start=datetime.datetime.fromisoformat(data.get('start')), end=datetime.datetime.fromisoformat(data.get('end')), duration=data.get('dur')) db.session.add(task) db.session.commit()
def authorize(): """ Redirected from client when user clicks on "Login with Server". This is a GET request with the following field in url - client_id - (optional) state - response_type: must be code """ oauth_client_id = request.args.get("client_id") state = request.args.get("state") scope = request.args.get("scope") redirect_uri = request.args.get("redirect_uri") response_mode = request.args.get("response_mode") nonce = request.args.get("nonce") try: response_types: [ResponseType] = get_response_types(request) except ValueError: return ( "response_type must be code, token, id_token or certain combination of these." " Please see /.well-known/openid-configuration to see what response_type are supported ", 400, ) if set(response_types) not in SUPPORTED_OPENID_FLOWS: return ( f"SimpleLogin only support the following OIDC flows: {SUPPORTED_OPENID_FLOWS_STR}", 400, ) if not redirect_uri: LOG.d("no redirect uri") return "redirect_uri must be set", 400 client = Client.get_by(oauth_client_id=oauth_client_id) if not client: final_redirect_uri = ( f"{redirect_uri}?error=invalid_client_id&client_id={oauth_client_id}" ) return redirect(final_redirect_uri) # check if redirect_uri is valid # allow localhost by default hostname, scheme = get_host_name_and_scheme(redirect_uri) if hostname != "localhost" and hostname != "127.0.0.1": # support custom scheme for mobile app if scheme == "http": final_redirect_uri = f"{redirect_uri}?error=http_not_allowed" return redirect(final_redirect_uri) if not RedirectUri.get_by(client_id=client.id, uri=redirect_uri): final_redirect_uri = f"{redirect_uri}?error=unknown_redirect_uri" return redirect(final_redirect_uri) # redirect from client website if request.method == "GET": if current_user.is_authenticated: suggested_email, other_emails, email_suffix = None, [], None suggested_name, other_names = None, [] # user has already allowed this client client_user: ClientUser = ClientUser.get_by( client_id=client.id, user_id=current_user.id ) user_info = {} if client_user: LOG.debug("user %s has already allowed client %s", current_user, client) user_info = client_user.get_user_info() else: suggested_email, other_emails = current_user.suggested_emails( client.name ) suggested_name, other_names = current_user.suggested_names() email_suffix = random_word() return render_template( "oauth/authorize.html", client=client, user_info=user_info, client_user=client_user, Scope=Scope, suggested_email=suggested_email, personal_email=current_user.email, suggested_name=suggested_name, other_names=other_names, other_emails=other_emails, email_suffix=email_suffix, EMAIL_DOMAIN=EMAIL_DOMAIN, ) else: # after user logs in, redirect user back to this page return render_template( "oauth/authorize_nonlogin_user.html", client=client, next=request.url, Scope=Scope, ) else: # user allows or denies if request.form.get("button") == "deny": LOG.debug("User %s denies Client %s", current_user, client) final_redirect_uri = f"{redirect_uri}?error=deny&state={state}" return redirect(final_redirect_uri) LOG.debug("User %s allows Client %s", current_user, client) client_user = ClientUser.get_by(client_id=client.id, user_id=current_user.id) # user has already allowed this client, user cannot change information if client_user: LOG.d("user %s has already allowed client %s", current_user, client) else: email_suffix = request.form.get("email-suffix") custom_email_prefix = request.form.get("custom-email-prefix") chosen_email = request.form.get("suggested-email") suggested_name = request.form.get("suggested-name") custom_name = request.form.get("custom-name") use_default_avatar = request.form.get("avatar-choice") == "default" gen_email = None if custom_email_prefix: # check if user can generate custom email if not current_user.can_create_new_alias(): raise Exception(f"User {current_user} cannot create custom email") email = f"{convert_to_id(custom_email_prefix)}.{email_suffix}@{EMAIL_DOMAIN}" LOG.d("create custom email alias %s for user %s", email, current_user) if GenEmail.get_by(email=email) or DeletedAlias.get_by(email=email): LOG.error("email %s already used, very rare!", email) flash(f"alias {email} already used", "error") return redirect(request.url) gen_email = GenEmail.create(email=email, user_id=current_user.id) db.session.flush() else: # user picks an email from suggestion if chosen_email != current_user.email: gen_email = GenEmail.get_by(email=chosen_email) if not gen_email: gen_email = GenEmail.create( email=chosen_email, user_id=current_user.id ) db.session.flush() client_user = ClientUser.create( client_id=client.id, user_id=current_user.id ) if gen_email: client_user.gen_email_id = gen_email.id if custom_name: LOG.d( "use custom name %s for user %s client %s", custom_name, current_user, client, ) client_user.name = custom_name elif suggested_name != current_user.name: LOG.d( "use another name %s for user %s client %s", custom_name, current_user, client, ) client_user.name = suggested_name if use_default_avatar: # use default avatar LOG.d("use default avatar for user %s client %s", current_user, client) client_user.default_avatar = True db.session.flush() LOG.d("create client-user for client %s, user %s", client, current_user) redirect_args = {} if state: redirect_args["state"] = state else: LOG.warning( "more security reason, state should be added. client %s", client ) if scope: redirect_args["scope"] = scope auth_code = None if ResponseType.CODE in response_types: # Create authorization code auth_code = AuthorizationCode.create( client_id=client.id, user_id=current_user.id, code=random_string(), scope=scope, redirect_uri=redirect_uri, response_type=response_types_to_str(response_types), ) db.session.add(auth_code) redirect_args["code"] = auth_code.code oauth_token = None if ResponseType.TOKEN in response_types: # create access-token oauth_token = OauthToken.create( client_id=client.id, user_id=current_user.id, scope=scope, redirect_uri=redirect_uri, access_token=generate_access_token(), response_type=response_types_to_str(response_types), ) db.session.add(oauth_token) redirect_args["access_token"] = oauth_token.access_token if ResponseType.ID_TOKEN in response_types: redirect_args["id_token"] = make_id_token( client_user, nonce, oauth_token.access_token if oauth_token else None, auth_code.code if auth_code else None, ) db.session.commit() # should all params appended the url using fragment (#) or query fragment = False if response_mode and response_mode == "fragment": fragment = True # if response_types contain "token" => implicit flow => should use fragment # except if client sets explicitly response_mode if not response_mode: if ResponseType.TOKEN in response_types: fragment = True # construct redirect_uri with redirect_args return redirect(construct_url(redirect_uri, redirect_args, fragment))
def setting(): form = SettingForm() promo_form = PromoCodeForm() change_email_form = ChangeEmailForm() email_change = EmailChange.get_by(user_id=current_user.id) if email_change: pending_email = email_change.new_email else: pending_email = None if request.method == "POST": if request.form.get("form-name") == "update-email": if change_email_form.validate(): if (change_email_form.email.data.lower().strip() != current_user.email and not pending_email): new_email = change_email_form.email.data.strip().lower() # check if this email is not already used if personal_email_already_used(new_email) or Alias.get_by( email=new_email): flash(f"Email {new_email} already used", "error") elif not email_domain_can_be_used_as_mailbox(new_email): flash( "You cannot use this email address as your personal inbox.", "error", ) else: email_change = EmailChange.create( user_id=current_user.id, code=random_string( 60), # todo: make sure the code is unique new_email=new_email, ) db.session.commit() send_change_email_confirmation(current_user, email_change) flash( "A confirmation email is on the way, please check your inbox", "success", ) return redirect(url_for("dashboard.setting")) if request.form.get("form-name") == "update-profile": if form.validate(): profile_updated = False # update user info if form.name.data != current_user.name: current_user.name = form.name.data db.session.commit() profile_updated = True if form.profile_picture.data: file_path = random_string(30) file = File.create(user_id=current_user.id, path=file_path) s3.upload_from_bytesio( file_path, BytesIO(form.profile_picture.data.read())) db.session.flush() LOG.d("upload file %s to s3", file) current_user.profile_picture_id = file.id db.session.commit() profile_updated = True if profile_updated: flash(f"Your profile has been updated", "success") return redirect(url_for("dashboard.setting")) elif request.form.get("form-name") == "change-password": flash( "You are going to receive an email containing instructions to change your password", "success", ) send_reset_password_email(current_user) return redirect(url_for("dashboard.setting")) elif request.form.get("form-name") == "notification-preference": choose = request.form.get("notification") if choose == "on": current_user.notification = True else: current_user.notification = False db.session.commit() flash("Your notification preference has been updated", "success") return redirect(url_for("dashboard.setting")) elif request.form.get("form-name") == "delete-account": LOG.warning("Delete account %s", current_user) User.delete(current_user.id) db.session.commit() flash("Your account has been deleted", "success") logout_user() return redirect(url_for("auth.register")) elif request.form.get("form-name") == "change-alias-generator": scheme = int(request.form.get("alias-generator-scheme")) if AliasGeneratorEnum.has_value(scheme): current_user.alias_generator = scheme db.session.commit() flash("Your preference has been updated", "success") return redirect(url_for("dashboard.setting")) elif request.form.get( "form-name") == "change-random-alias-default-domain": default_domain = request.form.get("random-alias-default-domain") if default_domain: default_domain_id = int(default_domain) # sanity check domain = CustomDomain.get(default_domain_id) if (not domain or domain.user_id != current_user.id or not domain.verified): flash( "Something went wrong, sorry for the inconvenience. Please retry. ", "error", ) return redirect(url_for("dashboard.setting")) current_user.default_random_alias_domain_id = default_domain_id else: current_user.default_random_alias_domain_id = None db.session.commit() flash("Your preference has been updated", "success") return redirect(url_for("dashboard.setting")) elif request.form.get("form-name") == "change-sender-format": sender_format = int(request.form.get("sender-format")) if SenderFormatEnum.has_value(sender_format): current_user.sender_format = sender_format db.session.commit() flash("Your sender format preference has been updated", "success") db.session.commit() return redirect(url_for("dashboard.setting")) elif request.form.get("form-name") == "replace-ra": choose = request.form.get("replace-ra") if choose == "on": current_user.replace_reverse_alias = True else: current_user.replace_reverse_alias = False db.session.commit() flash("Your preference has been updated", "success") return redirect(url_for("dashboard.setting")) elif request.form.get("form-name") == "export-data": data = { "email": current_user.email, "name": current_user.name, "aliases": [], "apps": [], "custom_domains": [], } for alias in Alias.filter_by( user_id=current_user.id).all(): # type: Alias data["aliases"].append( dict(email=alias.email, enabled=alias.enabled)) for custom_domain in CustomDomain.filter_by( user_id=current_user.id).all(): data["custom_domains"].append(custom_domain.domain) for app in Client.filter_by( user_id=current_user.id): # type: Client data["apps"].append( dict(name=app.name, home_url=app.home_url, published=app.published)) return Response( json.dumps(data), mimetype="text/json", headers={ "Content-Disposition": "attachment;filename=data.json" }, ) manual_sub = ManualSubscription.get_by(user_id=current_user.id) return render_template( "dashboard/setting.html", form=form, PlanEnum=PlanEnum, SenderFormatEnum=SenderFormatEnum, promo_form=promo_form, change_email_form=change_email_form, pending_email=pending_email, AliasGeneratorEnum=AliasGeneratorEnum, manual_sub=manual_sub, FIRST_ALIAS_DOMAIN=FIRST_ALIAS_DOMAIN, )
from app import create_app,db from app.models import FeatureRequest, Client,ProductArea from datetime import datetime app = create_app() app.app_context().push() with app.app_context(): db.create_all() db.session.add(Client(name='Client A')) db.session.add(Client(name='Client B')) db.session.add(Client(name='Client C')) db.session.add(ProductArea(name='Policies')) db.session.add(ProductArea(name='Billings')) db.session.add(ProductArea(name='Claims')) db.session.add(ProductArea(name='Reports')) featureRequest = FeatureRequest( title='First Title', description='First Description', target_date=datetime.strptime('2019/05/24', '%Y/%m/%d'), client_priority=1, client_id=3, product_area_id=2 ) db.session.add(featureRequest) featureRequest = FeatureRequest( title='Second Title', description='Second Description', target_date=datetime.strptime('2019/05/31', '%Y/%m/%d'), client_priority=1, client_id=2,
def test_authorize_token_id_token_flow(flask_client): """make sure the authorize redirects user to correct page for the *ID-Token Token Flow* , ie when response_type=id_token,token The /authorize endpoint should return an id_token and access_token id_token, once decoded, should contain *at_hash* in payload """ user = login(flask_client) client = Client.create_new("test client", user.id) db.session.commit() # user allows client on the authorization page r = flask_client.post( url_for( "oauth.authorize", client_id=client.oauth_client_id, state="teststate", redirect_uri="http://localhost", response_type="id_token token", # id_token,token flow ), data={ "button": "allow", "suggested-email": "[email protected]", "suggested-name": "AB CD" }, # user will be redirected to client page, do not allow redirection here # to assert the redirect url # follow_redirects=True, ) assert r.status_code == 302 # user gets redirected back to client page # r.location will have this form http://localhost?state=teststate&code=knuyjepwvg o = urlparse(r.location) assert o.netloc == "localhost" assert o.fragment assert not o.query # parse the fragment, should return something like # {'state': ['teststate'], 'id_token': ['knuyjepwvg']} queries = parse_qs(o.fragment) assert len(queries) == 3 assert queries["state"] == ["teststate"] # access_token must be returned assert len(queries["id_token"]) == 1 assert len(queries["access_token"]) == 1 # id_token must be a valid, correctly signed JWT id_token = queries["id_token"][0] assert verify_id_token(id_token) # make sure jwt has all the necessary fields jwt = decode_id_token(id_token) # payload should have this format # { # 'at_hash': 'jLDmoGpuOIHwxeyFEe9SKw', # 'aud': 'testclient-sywcpwsyua', # 'auth_time': 1565450736, # 'avatar_url': None, # 'client': 'test client', # 'email': '[email protected]', # 'email_verified': True, # 'exp': 1565454336, # 'iat': 1565450736, # 'id': 1, # 'iss': 'http://localhost', # 'name': 'AB CD', # 'sub': '1' # } payload = json.loads(jwt.claims) # at_hash MUST be present when the flow is id_token,token assert "at_hash" in payload assert "aud" in payload assert "auth_time" in payload assert "avatar_url" in payload assert "client" in payload assert "email" in payload assert "email_verified" in payload assert "exp" in payload assert "iat" in payload assert "id" in payload assert "iss" in payload assert "name" in payload assert "sub" in payload
def feature_requests(): if request.method == 'POST': title = str(request.form['title']) description = str(request.form['description']) if "client" in request.form and request.form['client'] != "": client = Client(name=request.form['client']) db.session.add(client) db.session.commit() client_id = client.id else: client_id = request.form['client_id'] if "product_area" in request.form and request.form[ 'product_area'] != "": product_area = ProductArea(name=request.form['product_area']) db.session.add(product_area) db.session.commit() product_area_id = product_area.id else: product_area_id = request.form['product_area_id'] target_date = str(request.form['target_date']) priority = int(request.form['priority']) feature_request = FeatureRequest(title=title, description=description, client_id=client_id, target_date=target_date, priority=priority, product_area_id=product_area_id) db.session.add(feature_request) priority_to_update = priority feat_requests_to_update_count = FeatureRequest.query.filter_by( client_id=client_id, priority=priority_to_update).count() while feat_requests_to_update_count > 1: feat_requests_to_update = FeatureRequest.query.filter_by( client_id=client_id, priority=priority_to_update).order_by('id').first() feat_requests_to_update.priority = feat_requests_to_update.priority + 1 priority_to_update = priority_to_update + 1 feat_requests_to_update_count = FeatureRequest.query.filter_by( client_id=client_id, priority=priority_to_update).count() db.session.commit() response = jsonify({ 'id': feature_request.id, 'title': feature_request.title, 'description': feature_request.description, 'client_id': feature_request.client_id, 'client': feature_request.client.name, 'target_date': feature_request.target_date, 'product_area_id': feature_request.product_area_id, 'product_area': feature_request.product_area.name, 'priority': feature_request.priority }) response.status_code = 201 return response else: feature_requests = FeatureRequest.query.all() results = [] for item in feature_requests: results.append({ 'id': item.id, 'title': item.title, 'description': item.description, 'client_id': item.client_id, 'target_date': item.target_date, 'client': item.client.name, 'product_area_id': item.product_area_id, 'product_area': item.product_area.name, 'priority': item.priority }) response = jsonify(results) response.status_code = 200 return response
def index(): clients = Client.filter_by(published=True).all() return render_template("discover/index.html", clients=clients)
def test_client_good_init(self): c = Client('Alice', '*****@*****.**', '+79099946885') c.password = '******' db.session.add(c) self.assertIsNone(db.session.commit())
def setting(): form = SettingForm() promo_form = PromoCodeForm() email_change = EmailChange.get_by(user_id=current_user.id) if email_change: pending_email = email_change.new_email else: pending_email = None if request.method == "POST": if request.form.get("form-name") == "update-profile": if form.validate(): profile_updated = False # update user info if form.name.data != current_user.name: current_user.name = form.name.data db.session.commit() profile_updated = True if form.profile_picture.data: file_path = random_string(30) file = File.create(path=file_path) s3.upload_from_bytesio( file_path, BytesIO(form.profile_picture.data.read())) db.session.flush() LOG.d("upload file %s to s3", file) current_user.profile_picture_id = file.id db.session.commit() profile_updated = True if profile_updated: flash(f"Your profile has been updated", "success") if (form.email.data and form.email.data != current_user.email and not pending_email): new_email = form.email.data # check if this email is not used by other user, or as alias if (User.get_by(email=new_email) or GenEmail.get_by(email=new_email) or DeletedAlias.get_by(email=new_email)): flash(f"Email {new_email} already used", "error") elif not can_be_used_as_personal_email(new_email): flash( "You cannot use this email address as your personal inbox.", "error", ) else: email_change = EmailChange.create( user_id=current_user.id, code=random_string( 60), # todo: make sure the code is unique new_email=new_email, ) db.session.commit() send_change_email_confirmation(current_user, email_change) flash( "A confirmation email is on the way, please check your inbox", "success", ) elif request.form.get("form-name") == "change-password": send_reset_password_email(current_user) elif request.form.get("form-name") == "notification-preference": choose = request.form.get("notification") if choose == "on": current_user.notification = True else: current_user.notification = False db.session.commit() flash("Your notification preference has been updated", "success") elif request.form.get("form-name") == "delete-account": User.delete(current_user.id) db.session.commit() flash("Your account has been deleted", "success") logout_user() return redirect(url_for("auth.register")) elif request.form.get("form-name") == "change-alias-generator": scheme = int(request.form.get("alias-generator-scheme")) if AliasGeneratorEnum.has_value(scheme): current_user.alias_generator = scheme db.session.commit() flash("Your preference has been updated", "success") elif request.form.get("form-name") == "export-data": data = { "email": current_user.email, "name": current_user.name, "aliases": [], "apps": [], "custom_domains": [], } for alias in GenEmail.filter_by( user_id=current_user.id).all(): # type: GenEmail data["aliases"].append( dict(email=alias.email, enabled=alias.enabled)) for custom_domain in CustomDomain.filter_by( user_id=current_user.id).all(): data["custom_domains"].append(custom_domain.domain) for app in Client.filter_by( user_id=current_user.id): # type: Client data["apps"].append( dict(name=app.name, home_url=app.home_url, published=app.published)) return Response( json.dumps(data), mimetype="text/json", headers={ "Content-Disposition": "attachment;filename=data.json" }, ) return redirect(url_for("dashboard.setting")) return render_template( "dashboard/setting.html", form=form, PlanEnum=PlanEnum, promo_form=promo_form, pending_email=pending_email, AliasGeneratorEnum=AliasGeneratorEnum, )
def test_func_save(self): client = Client(email='email') client.save() committed_client = Client.query.get(client.id) self.assertEqual(committed_client, client)
def profile(request): """User profile page""" context = get_global_context(request) if request.method == 'POST': user = request.user if user.has_perm('app.employee_role'): employee = Employee.objects.get(user_id=user.id) employee_form = EmployeeProfileForm(request.POST, request.FILES, instance=employee) user_form = UserProfileForm(request.POST, instance=request.user) if user_form.is_valid() and employee_form.is_valid(): if user_form.has_changed(): user.username = user_form.cleaned_data['username'] user.email = user_form.cleaned_data['email'] user.first_name = user_form.cleaned_data['first_name'] user.last_name = user_form.cleaned_data['last_name'] user.save() if employee_form.has_changed(): # saving data if employee_form.cleaned_data['avatar'] and\ employee.avatar !=\ employee_form.cleaned_data['avatar']: cur_avatar = employee.avatar employee.avatar = employee_form.cleaned_data['avatar'] delete_current_avatar_file(cur_avatar.path) employee.save() else: user_data = dict((key, user_form.data[key]) for key in list( set(user_form.data) & set(user_form.fields))) current_data_user = User(**user_data) employee_data = dict( (key, employee_form.data[key]) for key in list( set(employee_form.data) & set(employee_form.fields)) if key != 'avatar') current_data_employee = Employee(**employee_data) current_data_employee.avatar = employee.avatar context.update({ 'title': employee.get_short_instance_name(), 'cur_user': current_data_user, 'employee': current_data_employee, 'employee_form': employee_form, 'user_form': user_form, }) return render_profile(request, context) elif user.has_perm('app.client_role'): client = Client.objects.get(user_id=request.user.id) client_form = ClientProfileForm(request.POST, request.FILES, instance=client) user_form = UserProfileForm(request.POST, instance=request.user) if user_form.is_valid() and client_form.is_valid(): if user_form.has_changed(): user.username = user_form.cleaned_data['username'] user.email = user_form.cleaned_data['email'] user.first_name = user_form.cleaned_data['first_name'] user.last_name = user_form.cleaned_data['last_name'] user.save() if client_form.has_changed(): # saving data client = Client.objects.get(user_id=user.id) client.name = client_form.cleaned_data['name'] client.full_name = client_form.cleaned_data['full_name'] client.code_ipn = client_form.cleaned_data['code_ipn'] client.address = client_form.cleaned_data['address'] client.phone = client_form.cleaned_data['phone'] client.overall_mark_id =\ client_form.data['overall_mark'] if client_form.cleaned_data['avatar'] and\ client.avatar != client_form.cleaned_data['avatar']: cur_avatar = client.avatar client.avatar = client_form.cleaned_data['avatar'] delete_current_avatar_file(cur_avatar.path) client.save() else: user_data = dict((key, user_form.data[key]) for key in list( set(user_form.data) & set(user_form.fields))) current_data_user = User(**user_data) client_data = dict( (key, client_form.data[key]) for key in list( set(client_form.data) & set(client_form.fields)) if key != 'avatar') client_data.update({ 'overall_mark': Mark.objects.get(id=client_form.data['overall_mark']), }) current_data_client = Client(**client_data) current_data_client.balance = client.balance current_data_client.avatar = client.avatar context.update({ 'title': client.get_title_name(), 'cur_user': current_data_user, 'client': current_data_client, 'client_form': client_form, 'user_form': user_form, }) return render_profile(request, context) else: return render_profile(request, context)
def token(): """ Calls by client to exchange the access token given the authorization code. The client authentications using Basic Authentication. The form contains the following data: - grant_type: must be "authorization_code" - code: the code obtained in previous step """ # Basic authentication oauth_client_id = (request.authorization and request.authorization.username ) or request.form.get("client_id") oauth_client_secret = (request.authorization and request.authorization.password ) or request.form.get("client_secret") client = Client.filter_by(oauth_client_id=oauth_client_id, oauth_client_secret=oauth_client_secret).first() if not client: return jsonify(error="wrong client-id or client-secret"), 400 # Get code from form data grant_type = request.form.get("grant_type") code = request.form.get("code") # sanity check if grant_type != "authorization_code": return jsonify(error="grant_type must be authorization_code"), 400 auth_code: AuthorizationCode = AuthorizationCode.filter_by( code=code).first() if not auth_code: return jsonify(error=f"no such authorization code {code}"), 400 elif auth_code.is_expired(): AuthorizationCode.delete(auth_code.id) db.session.commit() LOG.d("delete expired authorization code:%s", auth_code) return jsonify(error=f"{code} already expired"), 400 if auth_code.client_id != client.id: return jsonify(error="are you sure this code belongs to you?"), 400 LOG.debug("Create Oauth token for user %s, client %s", auth_code.user, auth_code.client) # Create token oauth_token = OauthToken.create( client_id=auth_code.client_id, user_id=auth_code.user_id, scope=auth_code.scope, redirect_uri=auth_code.redirect_uri, access_token=generate_access_token(), response_type=auth_code.response_type, ) db.session.add(oauth_token) # Auth code can be used only once AuthorizationCode.delete(auth_code.id) db.session.commit() client_user: ClientUser = ClientUser.get_by(client_id=auth_code.client_id, user_id=auth_code.user_id) user_data = client_user.get_user_info() res = { "access_token": oauth_token.access_token, "token_type": "Bearer", "expires_in": 3600, "scope": auth_code.scope, "user": user_data, # todo: remove this } if oauth_token.scope and Scope.OPENID.value in oauth_token.scope: res["id_token"] = make_id_token(client_user) # Also return id_token if the initial flow is "code,id_token" # cf https://medium.com/@darutk/diagrams-of-all-the-openid-connect-flows-6968e3990660 response_types = get_response_types_from_str(auth_code.response_type) if ResponseType.ID_TOKEN in response_types: res["id_token"] = make_id_token(client_user) return jsonify(res)
def add_to_org(sender, **kwargs): org = sender.objects.last() user = org.creator member, created = OrganisationMember.objects.get_or_create( org=org, member=user) if created: tld = tldextract.extract(org.url) client = Client() client.name = org.name client.organisation = org client.schema_name = org.slug client.paid_until = datetime.now() + timedelta(days=90) try: client.domain_url = tld.domain client.save() except KeyError: try: client.domain_url = tld.domain + '-' + tld.subdomain client.save() except KeyError: client.domain_url = org.slug client.save()
def authorize(): """ Redirected from client when user clicks on "Login with Server". This is a GET request with the following field in url - client_id - (optional) state - response_type: must be code """ oauth_client_id = request.args.get("client_id") state = request.args.get("state") scope = request.args.get("scope") redirect_uri = request.args.get("redirect_uri") response_mode = request.args.get("response_mode") nonce = request.args.get("nonce") try: response_types: [ResponseType] = get_response_types(request) except ValueError: return ( "response_type must be code, token, id_token or certain combination of these." " Please see /.well-known/openid-configuration to see what response_type are supported ", 400, ) if set(response_types) not in SUPPORTED_OPENID_FLOWS: return ( f"SimpleLogin only support the following OIDC flows: {SUPPORTED_OPENID_FLOWS_STR}", 400, ) if not redirect_uri: LOG.d("no redirect uri") return "redirect_uri must be set", 400 client = Client.get_by(oauth_client_id=oauth_client_id) if not client: final_redirect_uri = ( f"{redirect_uri}?error=invalid_client_id&client_id={oauth_client_id}" ) return redirect(final_redirect_uri) # check if redirect_uri is valid # allow localhost by default hostname, scheme = get_host_name_and_scheme(redirect_uri) if hostname != "localhost" and hostname != "127.0.0.1": # support custom scheme for mobile app if scheme == "http": final_redirect_uri = f"{redirect_uri}?error=http_not_allowed" return redirect(final_redirect_uri) if not RedirectUri.get_by(client_id=client.id, uri=redirect_uri): final_redirect_uri = f"{redirect_uri}?error=unknown_redirect_uri" return redirect(final_redirect_uri) # redirect from client website if request.method == "GET": if current_user.is_authenticated: suggested_email, other_emails, email_suffix = None, [], None suggested_name, other_names = None, [] # user has already allowed this client client_user: ClientUser = ClientUser.get_by( client_id=client.id, user_id=current_user.id) user_info = {} if client_user: LOG.debug("user %s has already allowed client %s", current_user, client) user_info = client_user.get_user_info() else: suggested_email, other_emails = current_user.suggested_emails( client.name) suggested_name, other_names = current_user.suggested_names() user_custom_domains = [ cd.domain for cd in current_user.verified_custom_domains() ] # List of (is_custom_domain, alias-suffix) suffixes = [] # put custom domain first for alias_domain in user_custom_domains: suffixes.append((True, "@" + alias_domain)) # then default domain for domain in ALIAS_DOMAINS: suffixes.append(( False, ("" if DISABLE_ALIAS_SUFFIX else "." + random_word()) + "@" + domain, )) return render_template( "oauth/authorize.html", Scope=Scope, EMAIL_DOMAIN=EMAIL_DOMAIN, **locals(), ) else: # after user logs in, redirect user back to this page return render_template( "oauth/authorize_nonlogin_user.html", client=client, next=request.url, Scope=Scope, ) else: # POST - user allows or denies if request.form.get("button") == "deny": LOG.debug("User %s denies Client %s", current_user, client) final_redirect_uri = f"{redirect_uri}?error=deny&state={state}" return redirect(final_redirect_uri) LOG.debug("User %s allows Client %s", current_user, client) client_user = ClientUser.get_by(client_id=client.id, user_id=current_user.id) # user has already allowed this client, user cannot change information if client_user: LOG.d("user %s has already allowed client %s", current_user, client) else: alias_prefix = request.form.get("prefix") alias_suffix = request.form.get("suffix") gen_email = None # user creates a new alias, not using suggested alias if alias_prefix: # should never happen as this is checked on the front-end if not current_user.can_create_new_alias(): raise Exception( f"User {current_user} cannot create custom email") user_custom_domains = [ cd.domain for cd in current_user.verified_custom_domains() ] from app.dashboard.views.custom_alias import verify_prefix_suffix if verify_prefix_suffix(current_user, alias_prefix, alias_suffix, user_custom_domains): full_alias = alias_prefix + alias_suffix if GenEmail.get_by( email=full_alias) or DeletedAlias.get_by( email=full_alias): LOG.error("alias %s already used, very rare!", full_alias) flash(f"Alias {full_alias} already used", "error") return redirect(request.url) else: gen_email = GenEmail.create( user_id=current_user.id, email=full_alias, mailbox_id=current_user.default_mailbox_id, ) # get the custom_domain_id if alias is created with a custom domain alias_domain = get_email_domain_part(full_alias) custom_domain = CustomDomain.get_by( domain=alias_domain) if custom_domain: gen_email.custom_domain_id = custom_domain.id db.session.flush() flash(f"Alias {full_alias} has been created", "success") # only happen if the request has been "hacked" else: flash("something went wrong", "warning") return redirect(request.url) # User chooses one of the suggestions else: chosen_email = request.form.get("suggested-email") # todo: add some checks on chosen_email if chosen_email != current_user.email: gen_email = GenEmail.get_by(email=chosen_email) if not gen_email: gen_email = GenEmail.create( email=chosen_email, user_id=current_user.id, mailbox_id=current_user.default_mailbox_id, ) db.session.flush() suggested_name = request.form.get("suggested-name") custom_name = request.form.get("custom-name") use_default_avatar = request.form.get("avatar-choice") == "default" client_user = ClientUser.create(client_id=client.id, user_id=current_user.id) if gen_email: client_user.gen_email_id = gen_email.id if custom_name: client_user.name = custom_name elif suggested_name != current_user.name: client_user.name = suggested_name if use_default_avatar: # use default avatar LOG.d("use default avatar for user %s client %s", current_user, client) client_user.default_avatar = True db.session.flush() LOG.d("create client-user for client %s, user %s", client, current_user) redirect_args = {} if state: redirect_args["state"] = state else: LOG.warning( "more security reason, state should be added. client %s", client) if scope: redirect_args["scope"] = scope auth_code = None if ResponseType.CODE in response_types: # Create authorization code auth_code = AuthorizationCode.create( client_id=client.id, user_id=current_user.id, code=random_string(), scope=scope, redirect_uri=redirect_uri, response_type=response_types_to_str(response_types), ) db.session.add(auth_code) redirect_args["code"] = auth_code.code oauth_token = None if ResponseType.TOKEN in response_types: # create access-token oauth_token = OauthToken.create( client_id=client.id, user_id=current_user.id, scope=scope, redirect_uri=redirect_uri, access_token=generate_access_token(), response_type=response_types_to_str(response_types), ) db.session.add(oauth_token) redirect_args["access_token"] = oauth_token.access_token if ResponseType.ID_TOKEN in response_types: redirect_args["id_token"] = make_id_token( client_user, nonce, oauth_token.access_token if oauth_token else None, auth_code.code if auth_code else None, ) db.session.commit() # should all params appended the url using fragment (#) or query fragment = False if response_mode and response_mode == "fragment": fragment = True # if response_types contain "token" => implicit flow => should use fragment # except if client sets explicitly response_mode if not response_mode: if ResponseType.TOKEN in response_types: fragment = True # construct redirect_uri with redirect_args return redirect(construct_url(redirect_uri, redirect_args, fragment))