예제 #1
0
파일: account.py 프로젝트: CCrypto/ccvpn2
def orders(request):
    items_count = DBSession.query(func.count(Order.id)) \
                           .filter_by(uid=request.user.id) \
                           .filter(Order.close_date != None) \
                           .scalar()
    page_items = 100
    pages = int((items_count / page_items) + 0.5)
    try:
        page = int(request.GET['page'])
    except (KeyError, ValueError):
        page = 0
    offset = page * page_items
    orders = DBSession.query(Order).filter_by(uid=request.user.id) \

    now = datetime.datetime.now()

    orders = orders.filter(
        (Order.paid == True) |  # Order is paid
        ((Order.paid == False) & (Order.close_date > now)) |  # Or not expired
        ((Order.paid == False) & (Order.paid_amount > 0))  # Or not fully paid
    )

    orders = orders.order_by(Order.start_date.desc())
    orders = orders.limit(page_items).offset(offset).all()
    return {'orders': orders, 'page': page, 'pages': pages}
예제 #2
0
파일: api.py 프로젝트: theotix/ccvpn
def api_gateway_auth(request):
    try:
        fullname = request.POST['username']
        password = request.POST['password']
    except KeyError:
        return HTTPBadRequest('Require username/password')

    if '/' in fullname:
        username, profilename = fullname.split('/', 1)
    else:
        username = fullname
        profilename = None

    user = DBSession.query(User).filter_by(username=username).first()
    if not user or not user.check_password(password) or not user.is_active:
        return HTTPForbidden('Invalid username or password.')
    if not user.is_paid:
        return HTTPForbidden('Free account')

    if profilename:
        profile = DBSession.query(Profile) \
                           .filter_by(name=profilename, uid=user.id).first()
        if not profile:
            return HTTPForbidden('Unknown profile')
    return HTTPOk(empty_body=True)
예제 #3
0
파일: api.py 프로젝트: taron-ai/ccvpn2
def api_gateway_auth(request):
    try:
        fullname = request.POST['username']
        password = request.POST['password']
    except KeyError:
        return HTTPBadRequest('Require username/password')

    if '/' in fullname:
        username, profilename = fullname.split('/', 1)
    else:
        username = fullname
        profilename = None

    user = DBSession.query(User).filter_by(username=username).first()
    if not user or not user.check_password(password) or not user.is_active:
        return HTTPForbidden('Invalid username or password.')
    if not user.is_paid:
        return HTTPForbidden('Free account')

    if profilename:
        profile = DBSession.query(Profile) \
                           .filter_by(name=profilename, uid=user.id).first()
        if not profile:
            return HTTPForbidden('Unknown profile')
    return HTTPOk(empty_body=True)
예제 #4
0
파일: __init__.py 프로젝트: Graoumpf/ccvpn
def setup_database():
    """ Create an empty database and structure """
    DBSession.remove()
    engine = create_engine('sqlite://')
    Base.metadata.create_all(engine)
    DBSession.configure(bind=engine)
    return DBSession
예제 #5
0
def setup_database():
    """ Create an empty database and structure """
    DBSession.remove()
    engine = create_engine('sqlite://')
    Base.metadata.create_all(engine)
    DBSession.configure(bind=engine)
    return DBSession
예제 #6
0
파일: order.py 프로젝트: taron-ai/ccvpn2
def order_post(request):
    _ = request.translate
    code = request.POST.get('code')
    if code:
        return order_post_gc(request, code)

    times = (1, 3, 6, 12)
    try:
        method_name = request.POST.get('method')
        time_months = int(request.POST.get('time'))
    except (ValueError, TypeError):
        return HTTPSeeOther(location=request.route_url('account'))

    if method_name == 'admin' and request.user.is_admin:
        time = datetime.timedelta(days=30 * time_months)
        request.user.add_paid_time(time)
        return HTTPSeeOther(location=request.route_url('account'))

    method = request.payment_methods.get(method_name)
    if not method or time_months not in times:
        return HTTPBadRequest('Invalid method/time')

    time = datetime.timedelta(days=30 * time_months)

    o = method.init(request.user, time)
    DBSession.add(o)
    DBSession.flush()
    return method.start(request, o)
예제 #7
0
파일: __init__.py 프로젝트: Graoumpf/ccvpn
def status(request):
    settings = request.registry.settings
    domain = settings.get('net_domain', '')
    gateways = DBSession.query(Gateway) \
                        .filter_by(enabled=True) \
                        .order_by(Gateway.country, Gateway.name) \
                        .all()
    l = list(gateways)

    get_uptime = get_uptime_factory(settings)

    for host in l:
        host.host_name = '%s-%s.%s'%(host.country, host.name, domain)
        host.uptime = get_uptime(host.host_name)
        host.bps_formatted = format_bps(host.bps)

    bw_graph_url = settings.get('munin.bw_graph_url', None)
    bw_graph_img = settings.get('munin.bw_graph_img', None)
    bw_graph = (bw_graph_url, bw_graph_img)
    return {
        'gateways': l,
        'bw_graph': bw_graph if all(bw_graph) else None,
        'n_users': DBSession.query(func.count(User.id))
                            .filter_by(is_paid=True).scalar(),
        'n_countries': len(set(i.country for i in l)),
        'total_bw': format_bps(sum(i.bps for i in l)),
    }
예제 #8
0
파일: api.py 프로젝트: theotix/ccvpn
def api_gateway_connect(request):
    try:
        fullname = request.POST['username']
        client_addr = request.POST['remote_addr']
    except KeyError:
        return HTTPBadRequest('Require username/remote_addr')

    if '/' in fullname:
        username, profilename = fullname.split('/', 1)
    else:
        username = fullname
        profilename = None

    user = DBSession.query(User).filter_by(username=username).first()
    if not user or not user.is_active or not user.is_paid:
        return HTTPForbidden('Invalid account')

    sess = VPNSession()
    sess.gateway_id = request.gw.id
    sess.gateway_version = request.gw_version
    sess.user_id = user.id
    sess.remote_addr = client_addr

    if profilename:
        profile = DBSession.query(Profile) \
                           .filter_by(name=profilename, uid=user.id).first()
        if not profile:
            return HTTPForbidden('Unknown profile')
        sess.profile_id = profile.id

    DBSession.add(sess)

    params = {}

    return HTTPOk(body=json.dumps(params))
예제 #9
0
파일: account.py 프로젝트: taron-ai/ccvpn2
def orders(request):
    items_count = DBSession.query(func.count(Order.id)) \
                           .filter_by(uid=request.user.id) \
                           .filter(Order.close_date != None) \
                           .scalar()
    page_items = 100
    pages = int((items_count / page_items) + 0.5)
    try:
        page = int(request.GET['page'])
    except (KeyError, ValueError):
        page = 0
    offset = page * page_items
    orders = DBSession.query(Order).filter_by(uid=request.user.id) \

    now = datetime.datetime.now()

    orders = orders.filter((Order.paid == True) |  # Order is paid
                           ((Order.paid == False) & (Order.close_date > now))
                           |  # Or not expired
                           ((Order.paid == False)
                            & (Order.paid_amount > 0))  # Or not fully paid
                           )

    orders = orders.order_by(Order.start_date.desc())
    orders = orders.limit(page_items).offset(offset).all()
    return {'orders': orders, 'page': page, 'pages': pages}
예제 #10
0
파일: __init__.py 프로젝트: Graoumpf/ccvpn
def status(request):
    settings = request.registry.settings
    domain = settings.get('net_domain', '')
    gateways = DBSession.query(Gateway) \
                        .filter_by(enabled=True) \
                        .order_by(Gateway.country, Gateway.name) \
                        .all()
    l = list(gateways)

    get_uptime = get_uptime_factory(settings)

    for host in l:
        host.host_name = '%s-%s.%s' % (host.country, host.name, domain)
        host.uptime = get_uptime(host.host_name)
        host.bps_formatted = format_bps(host.bps)

    bw_graph_url = settings.get('munin.bw_graph_url', None)
    bw_graph_img = settings.get('munin.bw_graph_img', None)
    bw_graph = (bw_graph_url, bw_graph_img)
    return {
        'gateways':
        l,
        'bw_graph':
        bw_graph if all(bw_graph) else None,
        'n_users':
        DBSession.query(func.count(User.id)).filter_by(is_paid=True).scalar(),
        'n_countries':
        len(set(i.country for i in l)),
        'total_bw':
        format_bps(sum(i.bps for i in l)),
    }
예제 #11
0
파일: account.py 프로젝트: taron-ai/ccvpn2
def forgot(request):
    _ = request.translate
    if request.method != 'POST' or 'username' not in request.POST:
        return {}

    u = DBSession.query(User) \
        .filter_by(username=request.POST['username']) \
        .first()
    if not u:
        request.messages.error(_('Unknown username.'))
        request.response.status_code = HTTPBadRequest.code
        return {}
    if not u.email:
        request.messages.error(
            _('No e-mail address associated with username.'))
        request.response.status_code = HTTPBadRequest.code
        return {}

    token = PasswordResetToken(u)
    DBSession.add(token)
    DBSession.flush()

    mailer = get_mailer(request)
    body = render('mail/password_reset.mako', {
        'user': u,
        'requested_by': request.remote_addr,
        'url': request.route_url('account_reset', token=token.token)
    },
                  request=request)
    message = Message(subject=_('CCVPN: Password reset request'),
                      recipients=[u.email],
                      body=body)
    mailer.send(message)
    request.messages.info(_('We sent a reset link. Check your emails.'))
    return {}
예제 #12
0
파일: account.py 프로젝트: Logolo/ccvpn
def forgot(request):
    if request.method != 'POST' or 'username' not in request.POST:
        return {}

    u = DBSession.query(User) \
        .filter_by(username=request.POST['username']) \
        .first()
    if not u:
        request.messages.error('Unknown username.')
        request.response.status_code = HTTPBadRequest.code
        return {}
    if not u.email:
        request.messages.error('No e-mail address associated with username.')
        request.response.status_code = HTTPBadRequest.code
        return {}

    token = PasswordResetToken(u)
    with transaction.manager:
        DBSession.add(token)

    mailer = get_mailer(request)
    body = render('mail/password_reset.mako', {
        'user': u,
        'requested_by': request.remote_addr,
        'url': request.route_url('account_reset', token=token.token)
    })
    message = Message(subject='CCVPN: Password reset request',
                      recipients=[u.email],
                      body=body)
    mailer.send(message)
    request.messages.info('We sent a reset link. Check your emails.')
    return {}
예제 #13
0
def initialize_db():
    Base.metadata.create_all(DBSession.bind.engine)
    if not DBSession.query(User).filter_by(username='******').count():
        with transaction.manager:
            admin = User(username='******', is_admin=True)
            admin.set_password('admin')
            DBSession.add(admin)
예제 #14
0
파일: mail.py 프로젝트: taron-ai/ccvpn2
def main(argv=sys.argv):
    parser = ArgumentParser(description=__doc__,
                            formatter_class=RawTextHelpFormatter)
    parser.add_argument('-v', '--verbose', action='count')
    parser.add_argument('-S', '--send', action='store_true', default=False)
    parser.add_argument('--active', action='store_true', default=True)
    parser.add_argument('-s', '--subject', action='store')
    parser.add_argument('config')
    parser.add_argument('textfile')

    args = parser.parse_args()

    log_level = logging.WARNING
    if args.verbose is not None:
        verbose = int(args.verbose)
        if verbose == 1:
            log_level = logging.INFO
        elif verbose >= 2:
            log_level = logging.DEBUG
    logging.basicConfig(level=log_level)

    config_uri = args.config
    setup_logging(config_uri)
    settings = get_appsettings(config_uri)
    engine = engine_from_config(settings, 'sqlalchemy.')
    DBSession.configure(bind=engine)

    mailer = mailer_factory_from_settings(settings)

    if not args.subject:
        print('Require a subject.')
        exit(1)

    message_in = open(args.textfile, 'r').read()
    if not message_in:
        print('Require a message.')
        exit(1)

    q = DBSession.query(User)
    q = q.filter(User.email != '')
    q = q.filter(User.email is not None)
    if args.active:
        q = q.filter_by(is_paid=True)
    users = list(q.all())

    print('Sending to: %d users.' % (len(users)))
    if args.verbose:
        for u in users:
            print('- %s [%s]' % (u.email, u.username))

    for u in users:
        if not args.send:
            print('Not sending message to %s.' % u.email)
            continue
        message = Message(subject=args.subject,
                          recipients=[u.email],
                          body=message_in)
        mailer.send_immediately(message)
예제 #15
0
def main(argv=sys.argv):
    if len(argv) != 2:
        usage(argv)
    config_uri = argv[1]
    setup_logging(config_uri)
    settings = get_appsettings(config_uri)
    engine = engine_from_config(settings, 'sqlalchemy.')
    DBSession.configure(bind=engine)
    initialize_db()
예제 #16
0
파일: account.py 프로젝트: Logolo/ccvpn
def order_callback(request):
    id = int(request.matchdict['hexid'], 16)
    o = DBSession.query(Order).filter_by(id=id).first()
    if not o:
        return HTTPNotFound()
    method = methods.METHOD_IDS[o.method]
    ret = method().callback(request, o)
    DBSession.flush()
    return ret
예제 #17
0
def main(argv=sys.argv):
    if len(argv) != 2:
        usage(argv)
    config_uri = argv[1]
    setup_logging(config_uri)
    settings = get_appsettings(config_uri)
    engine = engine_from_config(settings, 'sqlalchemy.')
    DBSession.configure(bind=engine)
    checkbtcorders(settings)
예제 #18
0
파일: account.py 프로젝트: taron-ai/ccvpn2
def profiles_edit_post(request):
    _ = request.translate
    try:
        profile_id = int(request.matchdict['id'])
        profile = DBSession.query(Profile).filter_by(id=profile_id) \
                           .filter_by(uid=request.user.id).one()
    except (KeyError, ValueError, NoResultFound):
        return HTTPSeeOther(location=request.route_url('account'))

    redirect = HTTPSeeOther(
        location=request.route_url('account_profiles_edit', id=profile.id))

    try:
        name = request.POST.get('name', '')
        client_os = request.POST['client_os']
        gateway = request.POST['gateway']
        protocol = request.POST['protocol']
        disable_ipv6 = 'enable_ipv6' not in request.POST
        http_proxy = request.POST.get('use_http_proxy', '')
    except (KeyError, ValueError):
        return redirect

    if protocol not in Profile.PROTOCOLS:
        return redirect

    if profile.name and name and name != profile.name:
        if not profile.validate_name(name):
            request.messages.error(_('Invalid name.'))
            return redirect

        # Check if the name is already used
        used = DBSession.query(Profile).filter_by(uid=request.user.id) \
                        .filter_by(name=name).first()
        if used:
            request.messages.error(_('Name already used.'))
            return redirect

        profile.name = name

    profile.client_os = client_os
    profile.protocol = protocol
    profile.disable_ipv6 = disable_ipv6
    profile.use_http_proxy = http_proxy

    if gateway.startswith('rr_') and len(gateway) == 5:
        # rr_<cc>  # random in country
        cc = gateway[3:]
        profile.gateway_country = cc
        profile.gateway_id = None
    else:
        # random
        profile.gateway_country = None
        profile.gateway_id = None

    request.messages.info(_('Saved!'))
    return HTTPSeeOther(location=request.route_url('account'))
예제 #19
0
파일: account.py 프로젝트: CCrypto/ccvpn2
def profiles_edit_post(request):
    _ = request.translate
    try:
        profile_id = int(request.matchdict['id'])
        profile = DBSession.query(Profile).filter_by(id=profile_id) \
                           .filter_by(uid=request.user.id).one()
    except (KeyError, ValueError, NoResultFound):
        return HTTPSeeOther(location=request.route_url('account'))

    redirect = HTTPSeeOther(location=request.route_url('account_profiles_edit',
                                                       id=profile.id))

    try:
        name = request.POST.get('name', '')
        client_os = request.POST['client_os']
        gateway = request.POST['gateway']
        protocol = request.POST['protocol']
        disable_ipv6 = 'enable_ipv6' not in request.POST
        http_proxy = request.POST.get('use_http_proxy', '')
    except (KeyError, ValueError):
        return redirect

    if protocol not in Profile.PROTOCOLS:
        return redirect

    if profile.name and name and name != profile.name:
        if not profile.validate_name(name):
            request.messages.error(_('Invalid name.'))
            return redirect

        # Check if the name is already used
        used = DBSession.query(Profile).filter_by(uid=request.user.id) \
                        .filter_by(name=name).first()
        if used:
            request.messages.error(_('Name already used.'))
            return redirect

        profile.name = name

    profile.client_os = client_os
    profile.protocol = protocol
    profile.disable_ipv6 = disable_ipv6
    profile.use_http_proxy = http_proxy

    if gateway.startswith('rr_') and len(gateway) == 5:
        # rr_<cc>  # random in country
        cc = gateway[3:]
        profile.gateway_country = cc
        profile.gateway_id = None
    else:
        # random
        profile.gateway_country = None
        profile.gateway_id = None

    request.messages.info(_('Saved!'))
    return HTTPSeeOther(location=request.route_url('account'))
예제 #20
0
파일: models.py 프로젝트: Logolo/ccvpn
    def setUp(self):
        self.config = testing.setUp()
        self.session = setup_database()
        with transaction.manager:
            self.u = User(username='******', password='******')
            DBSession.add(self.u)

            self.pu = User(username='******', password='******')
            self.pu.add_paid_time(datetime.timedelta(days=30))
            DBSession.add(self.pu)
예제 #21
0
def main(argv=sys.argv):
    if len(argv) != 2:
        usage(argv)
    config_uri = argv[1]
    setup_logging(config_uri)
    settings = get_appsettings(config_uri)
    engine = engine_from_config(settings, 'sqlalchemy.')
    DBSession.configure(bind=engine)
    with transaction.manager:
        checkbtcorders(settings)
예제 #22
0
파일: models.py 프로젝트: CCrypto/ccvpn2
    def setUp(self):
        super().setUp()

        self.u = User(username='******', password='******')
        DBSession.add(self.u)
        self.session.flush()

        self.pu = User(username='******', password='******')
        self.pu.add_paid_time(datetime.timedelta(days=30))
        DBSession.add(self.pu)
        self.session.flush()
예제 #23
0
    def setUp(self):
        super().setUp()

        self.u = User(username='******', password='******')
        DBSession.add(self.u)
        self.session.flush()

        self.pu = User(username='******', password='******')
        self.pu.add_paid_time(datetime.timedelta(days=30))
        DBSession.add(self.pu)
        self.session.flush()
예제 #24
0
파일: order.py 프로젝트: taron-ai/ccvpn2
def order_callback(request):
    _ = request.translate
    id = int(request.matchdict['hexid'], 16)
    o = DBSession.query(Order).filter_by(id=id).first()
    if not o:
        return HTTPNotFound()

    method = request.payment_methods.get(o.method)
    r = method.callback(request, o)
    DBSession.flush()
    return r
예제 #25
0
파일: models.py 프로젝트: Graoumpf/ccvpn
    def setUp(self):
        self.config = testing.setUp()
        self.session = setup_database()
        self.u = User(username='******', password='******')
        DBSession.add(self.u)
        self.session.flush()

        self.pu = User(username='******', password='******')
        self.pu.add_paid_time(datetime.timedelta(days=30))
        DBSession.add(self.pu)
        self.session.flush()
예제 #26
0
def add(args):
    t = Gateway()
    t.label = args.label
    if args.token == '-':
        args.token = input('Token (empty=random): ')
    if args.token:
        t.token = args.token
    if args.remote_addr:
        t.remote_addr = args.remote_addr
    DBSession.add(t)
    DBSession.commit()
    print('Inserted. token=%s' % t.token)
예제 #27
0
파일: apiacl.py 프로젝트: Logolo/ccvpn
def add(args):
    t = APIAccessToken()
    t.label = args.label
    if args.token == '-':
        args.token = input('Token (empty=random): ')
    if args.token:
        t.token = args.token
    if args.remote_addr:
        t.remote_addr = args.remote_addr
    DBSession.add(t)
    DBSession.commit()
    print('Inserted. token=%s' % t.token)
예제 #28
0
def main(argv=sys.argv):
    parser = ArgumentParser(description=__doc__,
                            formatter_class=RawTextHelpFormatter)
    parser.add_argument('-v', '--verbose', action='count')
    parser.add_argument('-s', '--send', action='store_true', default=False)
    parser.add_argument('config')

    args = parser.parse_args()

    log_level = logging.WARNING
    if args.verbose is not None:
        verbose = int(args.verbose)
        if verbose == 1:
            log_level = logging.INFO
        elif verbose >= 2:
            log_level = logging.DEBUG
    logging.basicConfig(level=log_level)

    config_uri = args.config
    setup_logging(config_uri)
    settings = get_appsettings(config_uri)
    engine = engine_from_config(settings, 'sqlalchemy.')
    DBSession.configure(bind=engine)

    if 'mako.directories' not in settings:
        settings['mako.directories'] = 'ccvpn:templates/'
    if 'mako.imports' not in settings:
        settings['mako.imports'] = 'from ccvpn.filters import check'
    config = Configurator(settings=settings)
    config.include('pyramid_mako')
    config.commit()
    config.begin()

    mailer = mailer_factory_from_settings(settings)

    try:
        days = int(settings.get('expire_mail_days', 3))
    except ValueError:
        log.warning('Invalid integer value for expire_mail_days. Using default')
        days = 3

    users = get_future_expire(days) + get_expired()

    if args.send:
        for u in users:
            print('sending notice to %s (%s)' % (u.username, u.email))
            send_notice(u, mailer)
        transaction.commit()
    else:
        for u in users:
            print('not sending notice to %s (%s)' % (u.username, u.email))
        print('Use -s to send messages')
예제 #29
0
파일: account.py 프로젝트: Logolo/ccvpn
def order_post_gc(request, code):
    try:
        gc = GiftCode.one(code=code)
        gc.use(request.user)

        time = gc.time.days
        request.messages.info('OK! Added %d days to your account.' % time)
        DBSession.flush()
    except (NoResultFound, MultipleResultsFound):
        request.messages.error('Unknown code.')
    except AlreadyUsedGiftCode:
        request.messages.error('Already used code')
    return HTTPSeeOther(location=request.route_url('account'))
예제 #30
0
파일: account.py 프로젝트: CCrypto/ccvpn2
def profiles_edit(request):
    _ = request.translate
    try:
        profile_id = int(request.matchdict['id'])
        profile = DBSession.query(Profile).filter_by(id=profile_id) \
                           .filter_by(uid=request.user.id).one()
    except (KeyError, ValueError, NoResultFound):
        return HTTPSeeOther(location=request.route_url('account'))

    return {
        'profile': profile,
        'edit_post_url': request.route_url('account_profiles_edit', id=profile.id),
        'gw_countries': set(i[0] for i in DBSession.query(Gateway.country).all()),
    }
예제 #31
0
파일: account.py 프로젝트: taron-ai/ccvpn2
def account_post(request):
    _ = request.translate
    redirect = HTTPSeeOther(location=request.route_url('account'))
    profiles_limit = 10

    profile_name = request.POST.get('profilename')
    profile_delete = request.POST.get('delete')

    if profile_name:
        p = Profile()
        if not p.validate_name(profile_name):
            request.messages.error(_('Invalid name.'))
            return redirect

        # Check if the name is already used
        used = DBSession.query(Profile).filter_by(uid=request.user.id) \
                        .filter_by(name=profile_name).first()
        if used:
            request.messages.error(_('Name already used.'))
            return redirect

        # Check if this user's under the profile number limit
        profiles_count = DBSession.query(func.count(Profile.id)) \
                                  .filter_by(uid=request.user.id).scalar()
        if profiles_count > profiles_limit:
            request.messages.error(_('You have too many profiles.'))
            return redirect

        p.name = profile_name
        p.uid = request.user.id
        DBSession.add(p)
        DBSession.flush()
        return HTTPSeeOther(
            location=request.route_url('account_profiles_edit', id=p.id))

    if profile_delete:
        try:
            profile_delete = int(profile_delete)
        except ValueError:
            return redirect

        p = DBSession.query(Profile) \
            .filter_by(id=int(profile_delete)) \
            .filter(Profile.name != '') \
            .filter_by(uid=request.user.id) \
            .first()

        if not p:
            request.messages.error(_('Unknown profile.'))
            return redirect

        DBSession.delete(p)

    return redirect
예제 #32
0
파일: order.py 프로젝트: taron-ai/ccvpn2
def order_post_gc(request, code):
    _ = request.translate
    try:
        gc = GiftCode.one(code=code)
        gc.use(request.user)

        time = gc.time.days
        request.messages.info(_('OK! Added ${time} days to your account.',
                                mapping={'time': time}))
        DBSession.flush()
    except (NoResultFound, MultipleResultsFound):
        request.messages.error(_('Unknown gift code.'))
    except AlreadyUsedGiftCode:
        request.messages.error(_('Gift code already used.'))
    return HTTPSeeOther(location=request.route_url('account'))
예제 #33
0
파일: account.py 프로젝트: CCrypto/ccvpn2
def logs(request):
    items_count = DBSession.query(func.count(VPNSession.id)) \
                           .filter_by(user_id=request.user.id) \
                           .scalar()
    page_items = 100
    pages = int((items_count / page_items) + 0.5)
    try:
        page = int(request.GET['page'])
    except (KeyError, ValueError):
        page = 0
    offset = page * page_items
    logs = DBSession.query(VPNSession).filter_by(user_id=request.user.id) \
                    .order_by(VPNSession.connect_date.desc()) \
                    .limit(page_items).offset(offset)
    return {'logs': logs, 'page': page, 'pages': pages}
예제 #34
0
파일: account.py 프로젝트: taron-ai/ccvpn2
def logs(request):
    items_count = DBSession.query(func.count(VPNSession.id)) \
                           .filter_by(user_id=request.user.id) \
                           .scalar()
    page_items = 100
    pages = int((items_count / page_items) + 0.5)
    try:
        page = int(request.GET['page'])
    except (KeyError, ValueError):
        page = 0
    offset = page * page_items
    logs = DBSession.query(VPNSession).filter_by(user_id=request.user.id) \
                    .order_by(VPNSession.connect_date.desc()) \
                    .limit(page_items).offset(offset)
    return {'logs': logs, 'page': page, 'pages': pages}
예제 #35
0
파일: account.py 프로젝트: CCrypto/ccvpn2
def account_post(request):
    _ = request.translate
    redirect = HTTPSeeOther(location=request.route_url('account'))
    profiles_limit = 10

    profile_name = request.POST.get('profilename')
    profile_delete = request.POST.get('delete')

    if profile_name:
        p = Profile()
        if not p.validate_name(profile_name):
            request.messages.error(_('Invalid name.'))
            return redirect

        # Check if the name is already used
        used = DBSession.query(Profile).filter_by(uid=request.user.id) \
                        .filter_by(name=profile_name).first()
        if used:
            request.messages.error(_('Name already used.'))
            return redirect

        # Check if this user's under the profile number limit
        profiles_count = DBSession.query(func.count(Profile.id)) \
                                  .filter_by(uid=request.user.id).scalar()
        if profiles_count > profiles_limit:
            request.messages.error(_('You have too many profiles.'))
            return redirect

        p.name = profile_name
        p.uid = request.user.id
        DBSession.add(p)
        DBSession.flush()
        return HTTPSeeOther(location=request.route_url('account_profiles_edit', id=p.id))

    if profile_delete:
        try:
            profile_delete = int(profile_delete)
        except ValueError:
            return redirect

        p = DBSession.query(Profile) \
            .filter_by(id=int(profile_delete)) \
            .filter(Profile.name != '') \
            .filter_by(uid=request.user.id) \
            .first()

        if not p:
            request.messages.error(_('Unknown profile.'))
            return redirect

        DBSession.delete(p)

    return redirect
예제 #36
0
파일: account.py 프로젝트: taron-ai/ccvpn2
def profiles_edit(request):
    _ = request.translate
    try:
        profile_id = int(request.matchdict['id'])
        profile = DBSession.query(Profile).filter_by(id=profile_id) \
                           .filter_by(uid=request.user.id).one()
    except (KeyError, ValueError, NoResultFound):
        return HTTPSeeOther(location=request.route_url('account'))

    return {
        'profile': profile,
        'edit_post_url': request.route_url('account_profiles_edit',
                                           id=profile.id),
        'gw_countries':
        set(i[0] for i in DBSession.query(Gateway.country).all()),
    }
예제 #37
0
def get_future_expire(days=3):
    """This function get user accounts that will expire in a few days.
    """

    limit_date = datetime.now() + timedelta(days=days)

    q = DBSession.query(User) \
                 .filter(User.email != '') \
                 .filter(User.email != None)

    # Expire now < expiration < N days
    q = q.filter(User.paid_until > datetime.now())
    q = q.filter(User.paid_until < limit_date)

    # Only send notice if the last one was before the first time we could have
    # sent a notice
    # [last notice] < [expiration - 3days] < [this notice] < [expiration]
    if DBSession.bind.dialect.name == 'sqlite':
        a1 = func.julianday(User.paid_until)
        a2 = func.julianday(User.last_expiry_notice)
        cond = a1 - a2 > days
    else:
        cond = User.paid_until - User.last_expiry_notice > timedelta(days=days)

    q = q.filter(or_(User.last_expiry_notice == None, cond))

    users = list(q.all())

    log.debug('found %d accounts that expire in less than %d days',
              len(users), days)
    return users
예제 #38
0
파일: admin.py 프로젝트: Logolo/ccvpn
 def get_item(self, id):
     item_id = self.request.GET['id']
     item = DBSession.query(self.model).filter_by(id=item_id).first()
     template = 'admin/item.mako'
     if item is None:
         raise HTTPNotFound()
     return render_to_response(self.item_template or template,
                               self.tvars(dict(item=item)))
예제 #39
0
파일: admin.py 프로젝트: Logolo/ccvpn
 def _get_uid(self, input):
     if input.startswith('#'):
         return input[1:]
     user = DBSession.query(User).filter_by(username=input).first()
     if not user:
         # TODO: handle that correctly
         raise HTTPBadRequest()
     return user.id
예제 #40
0
파일: account.py 프로젝트: taron-ai/ccvpn2
def config(request):
    _ = request.translate
    settings = request.registry.settings
    domain = settings.get('net_domain', '')
    if not domain.startswith('.'):
        domain = '.' + domain

    gw_countries = [i[0] for i in DBSession.query(Gateway.country).all()]

    try:
        username = request.matchdict['username']
        pname = request.matchdict.get('pname', '')
        if request.user.username != username:
            # Only allow corrently logged user for now
            raise ValueError()
        user = request.user

        profile = DBSession.query(Profile) \
                           .filter_by(uid=user.id) \
                           .filter_by(name=pname) \
                           .one()
    except (ValueError, KeyError, NoResultFound):
        return HTTPNotFound()

    # Use 'Other / GNU/Linux' as the default OS if no other is set
    client_os = profile.client_os or 'other'

    params = {
        'profile': profile,
        'remote': profile.get_vpn_remote(domain),
        'use_fragment': (profile.protocol == 'udpl'),
        'use_ipv6': (profile.client_os != 'freebox')
        and not profile.disable_ipv6,
        'use_http_proxy': (profile.protocol == 'tcp'),
        'use_resolvconf': (profile.client_os == 'ubuntu'),
        'openvpn_ca': openvpn_ca,
    }

    r = render_to_response('config.ovpn.mako', params, request=request)

    if 'plain' in request.GET:
        r.content_type = 'text/plain'
    else:
        r.content_type = 'application/x-openvpn-profile'

    return r
예제 #41
0
파일: account.py 프로젝트: Logolo/ccvpn
def order_view(request):
    id = int(request.matchdict['hexid'], 16)
    o = DBSession.query(Order).filter_by(id=id).first()
    if not o:
        return HTTPNotFound()
    if not request.user.is_admin and request.user.id != o.uid:
        return HTTPUnauthorized()
    return {'o': o}
예제 #42
0
파일: account.py 프로젝트: CCrypto/ccvpn2
def config(request):
    _ = request.translate
    settings = request.registry.settings
    domain = settings.get('net_domain', '')
    if not domain.startswith('.'):
        domain = '.' + domain

    gw_countries = [i[0] for i in DBSession.query(Gateway.country).all()]

    try:
        username = request.matchdict['username']
        pname = request.matchdict.get('pname', '')
        if request.user.username != username:
            # Only allow corrently logged user for now
            raise ValueError()
        user = request.user

        profile = DBSession.query(Profile) \
                           .filter_by(uid=user.id) \
                           .filter_by(name=pname) \
                           .one()
    except (ValueError, KeyError, NoResultFound):
        return HTTPNotFound()

    # Use 'Other / GNU/Linux' as the default OS if no other is set
    client_os = profile.client_os or 'other'

    params = {
        'profile': profile,
        'remote': profile.get_vpn_remote(domain),
        'use_fragment': (profile.protocol == 'udpl'),
        'use_ipv6': (profile.client_os != 'freebox') and not profile.disable_ipv6,
        'use_http_proxy': (profile.protocol == 'tcp'),
        'use_resolvconf': (profile.client_os == 'ubuntu'),
        'openvpn_ca': openvpn_ca,
    }

    r = render_to_response('config.ovpn.mako', params, request=request)

    if 'plain' in request.GET:
        r.content_type = 'text/plain'
    else:
        r.content_type = 'application/x-openvpn-profile'

    return r
예제 #43
0
파일: account.py 프로젝트: Graoumpf/ccvpn
def signup(request):
    _ = request.translate
    if request.method != 'POST':
        return {}
    errors = []

    try:
        username = request.POST.get('username')
        password = request.POST.get('password')
        password2 = request.POST.get('password2')
        email = request.POST.get('email')

        if not User.validate_username(username):
            errors.append(_('Invalid username.'))
        if not User.validate_password(password):
            errors.append(_('Invalid password.'))
        if email and not User.validate_email(email):
            errors.append(_('Invalid email address.'))
        if password != password2:
            errors.append(_('Both passwords do not match.'))

        assert not errors

        used = User.is_used(username, email)
        if used[0] > 0:
            errors.append(_('Username already registered.'))
        if used[1] > 0 and email:
            errors.append(_('E-mail address already registered.'))

        assert not errors

        with transaction.manager:
            u = User(username=username, email=email, password=password)
            if request.referrer:
                u.referrer_id = request.referrer.id
            DBSession.add(u)
            DBSession.flush()
            request.session['uid'] = u.id
        return HTTPSeeOther(location=request.route_url('account'))
    except AssertionError:
        for error in errors:
            request.messages.error(error)
        fields = ('username', 'password', 'password2', 'email')
        request.response.status_code = HTTPBadRequest.code
        return {k: request.POST[k] for k in fields}
예제 #44
0
파일: account.py 프로젝트: Graoumpf/ccvpn
def signup(request):
    _ = request.translate
    if request.method != 'POST':
        return {}
    errors = []

    try:
        username = request.POST.get('username')
        password = request.POST.get('password')
        password2 = request.POST.get('password2')
        email = request.POST.get('email')

        if not User.validate_username(username):
            errors.append(_('Invalid username.'))
        if not User.validate_password(password):
            errors.append(_('Invalid password.'))
        if email and not User.validate_email(email):
            errors.append(_('Invalid email address.'))
        if password != password2:
            errors.append(_('Both passwords do not match.'))

        assert not errors

        used = User.is_used(username, email)
        if used[0] > 0:
            errors.append(_('Username already registered.'))
        if used[1] > 0 and email:
            errors.append(_('E-mail address already registered.'))

        assert not errors

        with transaction.manager:
            u = User(username=username, email=email, password=password)
            if request.referrer:
                u.referrer_id = request.referrer.id
            DBSession.add(u)
            DBSession.flush()
            request.session['uid'] = u.id
        return HTTPSeeOther(location=request.route_url('account'))
    except AssertionError:
        for error in errors:
            request.messages.error(error)
        fields = ('username', 'password', 'password2', 'email')
        request.response.status_code = HTTPBadRequest.code
        return {k: request.POST[k] for k in fields}
예제 #45
0
def checkbtcorders(settings):
    method = BitcoinMethod()

    orders = DBSession.query(Order) \
        .filter_by(paid=False, method=Order.METHOD.BITCOIN)
    for order in orders:
        method.check_paid(settings, order)
        log.debug('Order#%d: amount=%f, paid=%f', order.id, order.amount,
                  order.paid_amount)
예제 #46
0
def checkbtcorders(settings):
    method = BitcoinMethod(settings)

    orders = DBSession.query(Order) \
        .filter_by(paid=False, method=Order.METHOD.BITCOIN)
    for order in orders:
        method.check_paid(order)
        log.debug('Order#%d: amount=%f, paid=%f', order.id, order.amount,
                  order.paid_amount)
예제 #47
0
파일: account.py 프로젝트: Graoumpf/ccvpn
def config(request):
    _ = request.translate
    settings = request.registry.settings
    domain = settings.get('net_domain', '')

    gw_countries = [i[0] for i in DBSession.query(Gateway.country).all()]

    pname = request.GET.get('profile')
    if pname:
        profile = DBSession.query(Profile) \
            .filter_by(uid=request.user.id, name=pname) \
            .first()
        if not profile:
            return HTTPNotFound()
    else:
        profile = None

    gw = request.GET.get('gw')
    if gw and gw[0:3] == 'rr_' and gw[3:] in gw_countries:
        gateway = 'gw.' + gw[3:] + '.' + domain
    else:
        gateway = 'gw.random.' + domain

    os = request.GET.get('os')

    # These clients do not fully support OpenVPN config
    not_real_ovpn = os == 'android' or os == 'ios'

    params = {
        'force_udp': os == 'freebox',
        'force_tcp': not_real_ovpn or 'forcetcp' in request.GET,
        'windows_dns': os == 'windows',
        'resolvconf': os == 'ubuntu',
        'ipv6': os != 'freebox' and 'enable_ipv6' in request.GET,
        'dhcp': os != 'freebox',
        'username': request.user.username,
        'profile': profile,
        'gateway': gateway,
        'openvpn_ca': openvpn_ca,
    }

    r = render_to_response('config.ovpn.mako', params, request=request)
    r.content_type = 'application/x-openvpn-profile'
    return r
예제 #48
0
파일: account.py 프로젝트: Graoumpf/ccvpn
def config(request):
    _ = request.translate
    settings = request.registry.settings
    domain = settings.get('net_domain', '')

    gw_countries = [i[0] for i in DBSession.query(Gateway.country).all()]

    pname = request.GET.get('profile')
    if pname:
        profile = DBSession.query(Profile) \
            .filter_by(uid=request.user.id, name=pname) \
            .first()
        if not profile:
            return HTTPNotFound()
    else:
        profile = None

    gw = request.GET.get('gw')
    if gw and gw[0:3] == 'rr_' and gw[3:] in gw_countries:
        gateway = 'gw.' + gw[3:] + '.' + domain
    else:
        gateway = 'gw.random.' + domain

    os = request.GET.get('os')

    # These clients do not fully support OpenVPN config
    not_real_ovpn = os == 'android' or os == 'ios'

    params = {
        'force_udp': os == 'freebox',
        'force_tcp': not_real_ovpn or 'forcetcp' in request.GET,
        'windows_dns': os == 'windows',
        'resolvconf': os == 'ubuntu',
        'ipv6': os != 'freebox' and 'enable_ipv6' in request.GET,
        'dhcp': os != 'freebox',
        'username': request.user.username,
        'profile': profile,
        'gateway': gateway,
        'openvpn_ca': openvpn_ca,
    }

    r = render_to_response('config.ovpn.mako', params, request=request)
    r.content_type = 'application/x-openvpn-profile'
    return r
예제 #49
0
def main(argv=sys.argv):
    parser = ArgumentParser(description=__doc__,
                            formatter_class=RawTextHelpFormatter)
    parser.add_argument('-v', '--verbose', action='count',
                        help='Increase verbosity')
    parser.add_argument('config')

    subparsers = parser.add_subparsers(title='subcommands')
    parser_add = subparsers.add_parser('add', help='add API access token')
    parser_add.set_defaults(func=add)
    parser_add.add_argument('label')
    parser_add.add_argument('-t', '--token', default='')
    parser_add.add_argument('-r', '--remote-addr', default='')

    parser_rev = subparsers.add_parser('rev', help='revoke API access token')
    parser_rev.set_defaults(func=revoke)
    parser_rev.add_argument('-n', '--label', default='')
    parser_rev.add_argument('-t', '--token', default='')
    parser_rev.add_argument('-r', '--remote-addr', default='')
    parser_rev.add_argument('-y', '--yes', default=False, action='store_true',
                            help='Dont ask for confirmation')
    parser_rev.add_argument('-f', '--force', default=False,
                            action='store_true',
                            help='Revoke even if multiple found')

    args = parser.parse_args()

    log_level = logging.WARNING
    if args.verbose is not None:
        verbose = int(args.verbose)
        if verbose == 1:
            log_level = logging.INFO
        elif verbose >= 2:
            log_level = logging.DEBUG
    logging.basicConfig(level=log_level)

    config_uri = args.config
    setup_logging(config_uri)
    settings = get_appsettings(config_uri)
    engine = engine_from_config(settings, 'sqlalchemy.')
    DBSession.configure(bind=engine)

    args.func(args)
예제 #50
0
파일: account.py 프로젝트: taron-ai/ccvpn2
def reset(request):
    _ = request.translate
    token = DBSession.query(PasswordResetToken) \
        .filter_by(token=request.matchdict['token']) \
        .first()

    if not token or not token.user:
        request.messages.error(_('Unknown password reset token.'))
        url = request.route_url('account_forgot')
        return HTTPMovedPermanently(location=url)

    password = request.POST.get('password')
    password2 = request.POST.get('password2')

    if request.method != 'POST' or not password or not password2:
        return {'token': token}

    if not User.validate_password(password) or password != password2:
        request.messages.error(_('Invalid password.'))
        request.response.status_code = HTTPBadRequest.code
        return {'token': token}

    token.user.set_password(password)

    mailer = get_mailer(request)
    body = render('mail/password_reset_done.mako', {
        'user': token.user,
        'changed_by': request.remote_addr,
    },
                  request=request)
    message = Message(subject=_('CCVPN: Password changed'),
                      recipients=[token.user.email],
                      body=body)
    mailer.send(message)

    msg = _('You have changed the password for ${user}.',
            mapping={'user': token.user.username})
    msg += ' ' + _('You can now log in.')
    request.messages.info(msg)
    DBSession.delete(token)
    url = request.route_url('account_login')
    return HTTPMovedPermanently(location=url)
예제 #51
0
    def get_list(self, page):
        query = DBSession.query(self.model).order_by(self.model.id)

        for f in self.get_list_filters:
            query = f(query)

        # Pagination
        count_q = DBSession.query(func.count(self.model.id))
        for f in self.get_list_filters:
            count_q = f(count_q)
        count = count_q.scalar()

        pages = ceil(count / self.list_page_items)
        query = query.limit(self.list_page_items)
        query = query.offset(self.list_page_items * page)

        items = query.all()
        self.main_template = 'list.mako'
        if self.can_add:
            self.templates.append('add.mako')
        return {'list_items': items, 'page': page, 'pages': pages}
예제 #52
0
파일: __init__.py 프로젝트: taron-ai/ccvpn2
    def setUp(self):
        if not 'mako.directories' in self.settings:
            self.settings['mako.directories'] = 'ccvpn:templates/'
        if not 'mako.imports' in self.settings:
            self.settings['mako.imports'] = 'from ccvpn.filters import check'

        self.config = testing.setUp(settings=self.settings)
        self.config.include('pyramid_mailer.testing')
        self.config.include('pyramid_mako')
        self.config.include('pyramid_beaker')
        self.config.include('pyramid_mailer.testing')
        setup_routes(self.config)

        DBSession.remove()

        #self.engine = engine_from_config(settings, 'sqlalchemy.')
        self.conn = self.engine.connect()
        self.trans = self.conn.begin()

        DBSession.configure(bind=self.conn)
        Base.metadata.create_all(self.engine)
        self.session = DBSession
예제 #53
0
파일: api.py 프로젝트: taron-ai/ccvpn2
def api_gateway_connect(request):
    try:
        fullname = request.POST['username']
        client_addr = request.POST['remote_addr']
        internal_ip4 = request.POST['internal_ip4']
        internal_ip6 = request.POST['internal_ip6']
    except KeyError:
        return HTTPBadRequest('Require username/remote_addr')

    if '/' in fullname:
        username, profilename = fullname.split('/', 1)
    else:
        username = fullname
        profilename = None

    user = DBSession.query(User).filter_by(username=username).first()
    if not user or not user.is_active or not user.is_paid:
        return HTTPForbidden('Invalid account')

    sess = VPNSession()
    sess.gateway_id = request.gw.id
    sess.gateway_version = request.gw_version
    sess.user_id = user.id
    sess.remote_addr = client_addr
    sess.internal_ip4 = internal_ip4
    sess.internal_ip6 = internal_ip6

    if profilename:
        profile = DBSession.query(Profile) \
                           .filter_by(name=profilename, uid=user.id).first()
        if not profile:
            return HTTPForbidden('Unknown profile')
        sess.profile_id = profile.id

    DBSession.add(sess)

    params = {}

    return HTTPOk(body=json.dumps(params))