Esempio n. 1
0
 def check(self, *args, **kwargs):
     auth = request.get_header('Authorization')
     if auth:
         (user, password) = parse_auth(auth)
         if user == self.username and password == self.password:
             return fn(self, *args, **kwargs)
     self._raise(401, 'Requires auth')
Esempio n. 2
0
def call_api(func, args=""):
    add_header(response)

    s = request.environ.get('beaker.session')
    auth = parse_auth(request.get_header('Authorization', ''))
    # TODO: session as GET
    if 'session' in request.POST:
        # removes "' so it works on json strings
        s = s.get_by_id(remove_chars(request.POST['session'], "'\""))
    elif auth:
        user = PYLOAD.checkAuth(auth[0], auth[1], request.environ.get('REMOTE_ADDR', None))
        # if auth is correct create a pseudo session
        if user: s = {'uid': user.uid}

    api = get_user_api(s)
    if not api:
        return HTTPError(403, dumps("Forbidden"))

    if not PYLOAD.isAuthorized(func, api.user):
        return HTTPError(401, dumps("Unauthorized"))

    args = args.split("/")[1:]
    kwargs = {}

    for x, y in chain(request.GET.iteritems(), request.POST.iteritems()):
        if x == "session": continue
        kwargs[x] = unquote(y)

    try:
        return callApi(api, func, *args, **kwargs)
    except ExceptionObject, e:
        return HTTPError(400, dumps(e))
Esempio n. 3
0
def get_token():
    credentials = request.headers.get("Authorization", "")
    username, password = parse_auth(credentials) or ("", "")

    username = username.strip().lower()
    password = hashlib.sha1(password).hexdigest()

    participant = participant_data.get(username)

    if not participant or participant["password"] != password:
        response.status = 401
        return {"status": 401, "error": "bad user credentials"}

    token = hashlib.sha256(os.urandom(1024)).hexdigest()

    if participant["token"]:  # ...invalidate previous token.
        del access_tokens[participant["token"]]

    participant["token"] = token

    access_tokens[token] = {
        "username": username,
        "uid": participant["uid"],
        "expires": int(time.time() + ACCESS_TOKEN_LIFETIME)
    }

    save_participants()

    response.status = 200
    return {
        "status": 200,
        "token": token,
        "uid": participant["uid"],
        "expires": access_tokens[token]["expires"]
    }
Esempio n. 4
0
def api_vnf_init_config(vnf_id):
  if auth_method == 'gatekeeper':
    if not gatekeeper_authentication(request.get_header('X-Auth-Token')):
      abort(401)
  elif auth_method == 'basic':
    user, passwd = parse_auth(request.get_header('Authorization'))
    if not check_credentials(user, passwd):
      abort(401)
  print "\n######## VNF INITIAL CONFIGURATION ########\n"
  print "VNF Validation: "
  if validate_VNF(vnf_id):
    print "Ok"
    print "\nRetrieving VNF Configuration: \n"
    try:
      vnfm_request = loads(request.body.getvalue())
      print vnfm_request
    except:
      print "Fail: Unable to retrieve VNF Configuration"
      print "\n############## END ##############\n"
      abort(400)
    finally:
      print "\nStarting VNF initial configuration workflow\n"
      response = initial_configuration(vnf_id, vnfm_request)
      if not response:
        print "Fail: Unable to configure VNF"
        print "\n############## END ##############\n"
        abort(500)
  else:
    print "Fail: VNF not found"
    print "\n############## END ##############\n"
    abort(404)
Esempio n. 5
0
def api_get_vnf_config(vnf_id):
  if auth_method == 'gatekeeper':
    if not gatekeeper_authentication(request.get_header('X-Auth-Token')):
      abort(401)
  elif auth_method == 'basic':
    user, passwd = parse_auth(request.get_header('Authorization'))
    if not check_credentials(user, passwd):
      abort(401)
  print "\n######## RETRIEVE VNF CURRENT CONFIGURATION ########\n"
  print "VNF Validation: "
  if validate_VNF(vnf_id):
    print "Ok"
    print "\nRetrieve Configuration workflow \n"
    conf_obj = get_current_configuration(vnf_id)
    if not conf_obj:
      print "\nThe VNF has not been configured\n"
      print "\n############## END ##############\n"
      abort(404)
    else:
      print "\n############## END ##############\n"
      return conf_obj
  else:
    print "Fail: VNF not found"
    print "\n############## END ##############\n"
    abort(404) 
Esempio n. 6
0
def api_delete_vnf(vnf_id):
  if auth_method == 'gatekeeper':
    if not gatekeeper_authentication(request.get_header('X-Auth-Token')):
      abort(401)
  if auth_method == 'basic':
    print "basic authentication"
    user, passwd = parse_auth(request.get_header('Authorization'))
    if not check_credentials(user, passwd):
      abort(401)
  print "\n######## DELETE VNF CONFIGURATION API ########\n"
  print "VNF Validation: "
  if validate_VNF(vnf_id):
    print "Ok\n"
    try:
      vnfm_request = loads(request.body.getvalue())
    except:
      vnfm_request = None
    finally:
      print "\nStarting VNF removal workflow\n"
      response = delete_vnf(vnf_id, vnfm_request)
      if not response:
        print "Fail: the VNF could not be removed\n"
        print "\n############## END ##############\n"
        abort(500)
      print "\n############## END ##############\n"
  else:
    print "Fail: VNF not found"
    print "\n############## END ##############\n"
    abort(404)
Esempio n. 7
0
def check_basic_auth():
    auth = request.headers.get('Authorization')
    print "auth--> ", auth
    username, password = parse_auth(auth)
    print "basic auth:", username, ",", password
    hashed = ''.join(API_TOKEN)
    print "hashed:", hashed
    return sha256_crypt.verify(password, hashed)
Esempio n. 8
0
def check_basic_auth():
    auth = request.headers.get('Authorization')
    print "auth--> ", auth
    username, password = parse_auth(auth)
    print "basic auth:", username, "," , password
    hashed = ''.join(API_TOKEN)
    print "hashed:" ,hashed
    return sha256_crypt.verify(password, hashed)
Esempio n. 9
0
 def login_basic(self):
     auth = request.headers.get('Authorization')
     email, p = parse_auth(auth)
     response.set_cookie(self.COOKIE_NAME_ACCOUNT,
                         email,
                         secret=self.COOKIE_SECRET)
     return self.send("<html><script>window.close();</script></html>",
                      ct="text/html")
Esempio n. 10
0
def must_authenticate() -> User:
    global config, users
    auth = request.get_header("Authorization")
    username, password = parse_auth(auth)
    conf = authenticate(config, username, password)
    if conf == None:
        raise StatusError(403, "Unrecognized login")
    return users[username]
Esempio n. 11
0
def check_pass():
    auth = request.headers.get('Authorization')
    username, password = parse_auth(auth)
    auth_pass = False
    print "checking"
    if username == 'thioden':
        auth_pass = True
        cleared = True
    return auth_pass
Esempio n. 12
0
 def cookie(self):
     auth = request.headers.get('Authorization')
     if not auth:
         return self.application.send("<html><script>window.close();</script></html>", ct="text/html", );
     who, p = parse_auth(auth)      
     origin = request.query.get('origin', '*')
     # who is an identity (the username)
     value = {'sub': who}
     self.set_cookie(value, origin, response)
     return self.application.send("<html><script>window.close();</script></html>", ct="text/html", );
Esempio n. 13
0
        def decorator(*args, **kwargs):
            if not self.users:
                self.users = args[0].users

            (username, password) = bottle.parse_auth(bottle.request.get_header('Authorization'))
            user = self.users.get(username)
            if user and 'is_admin' in user and user['is_admin']:
                return f(*args, **kwargs)
            else:
                bottle.abort(401, 'Access denied')
Esempio n. 14
0
def call_api(func, args=""):
    add_json_header(response)

    s = request.environ.get('beaker.session')
    # Accepts standard http auth
    auth = parse_auth(request.get_header('Authorization', ''))
    if 'session' in request.POST or 'session' in request.GET:
        # removes "' so it works on json strings
        s = s.get_by_id(remove_chars(request.params.get('session'), "'\""))
    elif auth:
        user = PYLOAD.checkAuth(auth[0], auth[1],
                                request.environ.get('REMOTE_ADDR', None))
        # if auth is correct create a pseudo session
        if user: s = {'uid': user.uid}

    api = get_user_api(s)
    if not api:
        return error(401, "Unauthorized")

    if not PYLOAD.isAuthorized(func, api.user):
        return error(403, "Forbidden")

    if not hasattr(PYLOAD.EXTERNAL, func) or func.startswith("_"):
        print "Invalid API call", func
        return error(404, "Not Found")

    # TODO: possible encoding
    # TODO Better error codes on invalid input

    args = [loads(unquote(arg)) for arg in args.split("/")[1:]]
    kwargs = {}

    # accepts body as json dict
    if request.json:
        kwargs = request.json

    # file upload, reads whole file into memory
    for name, f in request.files.iteritems():
        kwargs["filename"] = f.filename
        content = StringIO()
        f.save(content)
        kwargs[name] = content.getvalue()
        content.close()

    # convert arguments from json to obj separately
    for x, y in request.params.iteritems():
        try:
            if not x or not y or x == "session": continue
            kwargs[x] = loads(unquote(y))
        except Exception, e:
            # Unsupported input
            msg = "Invalid Input %s, %s : %s" % (x, y, e.message)
            print_exc()
            print msg
            return error(415, msg)
Esempio n. 15
0
File: yadds.py Progetto: JF3/yadds
def dyndnsUpdate():
    auth = request.headers.get('Authorization')
    username, password = parse_auth(auth)


    hostnames = request.query.hostname
    ipv4 = request.query.myip or ""
    ipv6 = request.query.myip6 or ""

    # FIXME we need a way to adapt the return codes to other interfaces...
    return doUpdate(username, hostnames, ipv4, ipv6)
Esempio n. 16
0
def call_api(func, args=""):
    add_json_header(response)

    s = request.environ.get('beaker.session')
    # Accepts standard http auth
    auth = parse_auth(request.get_header('Authorization', ''))
    if 'session' in request.POST or 'session' in request.GET:
        # removes "' so it works on json strings
        s = s.get_by_id(remove_chars(request.params.get('session'), "'\""))
    elif auth:
        user = PYLOAD.checkAuth(auth[0], auth[1], request.environ.get('REMOTE_ADDR', None))
        # if auth is correct create a pseudo session
        if user: s = {'uid': user.uid}

    api = get_user_api(s)
    if not api:
        return error(401, "Unauthorized")

    if not PYLOAD.isAuthorized(func, api.user):
        return error(403, "Forbidden")

    if not hasattr(PYLOAD.EXTERNAL, func) or func.startswith("_"):
        print "Invalid API call", func
        return error(404, "Not Found")

    # TODO: possible encoding
    # TODO Better error codes on invalid input

    args = [loads(unquote(arg)) for arg in args.split("/")[1:]]
    kwargs = {}

    # accepts body as json dict
    if request.json:
        kwargs = request.json

    # file upload, reads whole file into memory
    for name, f in request.files.iteritems():
        kwargs["filename"] = f.filename
        content = StringIO()
        f.save(content)
        kwargs[name] = content.getvalue()
        content.close()

    # convert arguments from json to obj separately
    for x, y in request.params.iteritems():
        try:
            if not x or not y or x == "session": continue
            kwargs[x] = loads(unquote(y))
        except Exception, e:
            # Unsupported input
            msg = "Invalid Input %s, %s : %s" % (x, y, e.message)
            print_exc()
            print msg
            return error(415, msg)
Esempio n. 17
0
def terminal():
    auth = bottle.request.headers.get('Authorization')
    port = bottle.request.query.port
    command = bottle.request.forms.get("file")
    print command
    if auth:
        user, _ = bottle.parse_auth(auth)
        CONFIG['ports'][port]['user'] = user
    if command == "reset":
        cmd = CONFIG['ports'][port]["resetcmd"]
        os.system(cmd)

    return get_terminal_dict(port, user)
Esempio n. 18
0
def call_api(func, args=""):
    add_header(response)

    s = request.environ.get("beaker.session")
    # Accepts standard http auth
    auth = parse_auth(request.get_header("Authorization", ""))
    if "session" in request.POST or "session" in request.GET:
        # removes "' so it works on json strings
        s = s.get_by_id(remove_chars(request.params.get("session"), "'\""))
    elif auth:
        user = PYLOAD.checkAuth(auth[0], auth[1], request.environ.get("REMOTE_ADDR", None))
        # if auth is correct create a pseudo session
        if user:
            s = {"uid": user.uid}

    api = get_user_api(s)
    if not api:
        return HTTPError(401, dumps("Unauthorized"), **response.headers)

    if not PYLOAD.isAuthorized(func, api.user):
        return HTTPError(403, dumps("Forbidden"), **response.headers)

    if not hasattr(PYLOAD.EXTERNAL, func) or func.startswith("_"):
        print "Invalid API call", func
        return HTTPError(404, dumps("Not Found"), **response.headers)

    # TODO: possible encoding
    # TODO Better error codes on invalid input

    args = [loads(unquote(arg)) for arg in args.split("/")[1:]]
    kwargs = {}

    # accepts body as json dict
    if request.json:
        kwargs = request.json

    # convert arguments from json to obj separately
    for x, y in chain(request.GET.iteritems(), request.POST.iteritems()):
        if not x or not y or x == "session":
            continue
        kwargs[x] = loads(unquote(y))

    try:
        result = getattr(api, func)(*args, **kwargs)
        # null is invalid json response
        if result is None:
            result = True
        return dumps(result)

    except ExceptionObject, e:
        return HTTPError(400, dumps(e), **response.headers)
Esempio n. 19
0
def call_api(func, args=""):
    add_header(response)

    s = request.environ.get('beaker.session')
    # Accepts standard http auth
    auth = parse_auth(request.get_header('Authorization', ''))
    if 'session' in request.POST or 'session' in request.GET:
        # removes "' so it works on json strings
        s = s.get_by_id(remove_chars(request.params.get('session'), "'\""))
    elif auth:
        user = PYLOAD.checkAuth(auth[0], auth[1],
                                request.environ.get('REMOTE_ADDR', None))
        # if auth is correct create a pseudo session
        if user: s = {'uid': user.uid}

    api = get_user_api(s)
    if not api:
        return HTTPError(401, dumps("Unauthorized"), **response.headers)

    if not PYLOAD.isAuthorized(func, api.user):
        return HTTPError(403, dumps("Forbidden"), **response.headers)

    if not hasattr(PYLOAD.EXTERNAL, func) or func.startswith("_"):
        print "Invalid API call", func
        return HTTPError(404, dumps("Not Found"), **response.headers)

    # TODO: possible encoding
    # TODO Better error codes on invalid input

    args = [loads(unquote(arg)) for arg in args.split("/")[1:]]
    kwargs = {}

    # accepts body as json dict
    if request.json:
        kwargs = request.json

    # convert arguments from json to obj separately
    for x, y in chain(request.GET.iteritems(), request.POST.iteritems()):
        if not x or not y or x == "session": continue
        kwargs[x] = loads(unquote(y))

    try:
        result = getattr(api, func)(*args, **kwargs)
        # null is invalid json response
        if result is None: result = True
        return dumps(result)

    except ExceptionObject, e:
        return HTTPError(400, dumps(e), **response.headers)
Esempio n. 20
0
    def validate(*args, **kwargs):
        """
        Validation function for checking the credentials.
        """

        auth_header = request.headers.get('Authorization')
        if auth_header is None:
            abort(401, 'Access denied')
        credentials = parse_auth(auth_header)

        if (credentials[0] == settings['user']
                and credentials[1] == settings['password']):
            return func(**kwargs)
        else:
            abort(401, 'Access denied')
Esempio n. 21
0
def _is_authorized(vdc):
    """Check if the user is authorized through BasicAuth or API Keys.
    """
    auth_header = request.headers.get("Authorization")
    if auth_header:
        # Get vdc name and password from request Authorization header with Basic type
        name, password = parse_auth(auth_header)
        if vdc.validate_password(password) and name == vdc.vdc_name:
            return True
    else:
        api_key_header = request.headers.get("X-API-KEY")
        for name in APIKeyFactory.list_all():
            api_key = APIKeyFactory.find(name)
            if api_key_header == api_key.key:
                return True
Esempio n. 22
0
    def test_noforms_auth_user_password(self):
        """POSTed body is not a forms, so we need to decode authorization
        ourselves.
        """
        self.request.content_type = self.request.headers["Content-Type"] = "text/html"
        self.request.body = "<html>"
        self.request.auth = ("foobar", "barsecret")
        _, _, body, headers = oauth2.extract_params(self.request)
        self.assertEqual(body, "<html>")
        self.assertIn("Authorization", headers)

        import bottle
        client_id, client_secret = bottle.parse_auth(headers["Authorization"])
        self.assertEqual(client_id, "foobar")
        self.assertEqual(client_secret, "barsecret")
Esempio n. 23
0
    def validate(*args, **kwargs):
        """
        Validation function for checking the credentials.
        """

        auth_header = request.headers.get('Authorization')
        if auth_header is None:
            abort(401, 'Access denied')
        credentials = parse_auth(auth_header)

        if (credentials[0] == settings['user'] and
                credentials[1] == settings['password']):
            return func(**kwargs)
        else:
            abort(401, 'Access denied')
Esempio n. 24
0
    def wrapper(*args, **kwargs):
        auth = request.headers.get('Authorization')
        if not auth:
            raise HTTPError(status=401,
                            x_blobber_msg='Authentication required!')
        req_user, req_passwd = parse_auth(auth)

        USER = os.environ.get("CLIENT_USERNAME")
        PASSWORD = os.environ.get("CLIENT_PASSWORD")
        if not USER or not PASSWORD:
            raise HTTPError(
                status=500,
                x_blobber_msg='Client credentials unset on server!')

        if (req_user, req_passwd) != (USER, PASSWORD):
            raise HTTPError(status=403, x_blobber_msg='Authentication failed!')
        return fn(**kwargs)
Esempio n. 25
0
    def wrapper(*args, **kwargs):
        auth = request.headers.get('Authorization')
        if not auth:
            raise HTTPError(status=401,
                            x_blobber_msg='Authentication required!')
        req_user, req_passwd = parse_auth(auth)

        USER = os.environ.get("CLIENT_USERNAME")
        PASSWORD = os.environ.get("CLIENT_PASSWORD")
        if not USER or not PASSWORD:
            raise HTTPError(status=500,
                            x_blobber_msg='Client credentials unset on server!')

        if (req_user, req_passwd) != (USER, PASSWORD):
            raise HTTPError(status=403,
                            x_blobber_msg='Authentication failed!')
        return fn(**kwargs)
Esempio n. 26
0
 def is_auth_by_header(self):
     header = request.get_header('Authorization')
     if header is None:
         return False
     pair = parse_auth(header)
     if pair is None:
         return False
     user, passwd = pair
     userinfo = get_user_info(self.db.session, user)
     if userinfo is None:
         return False
     if authenticate(passwd, userinfo):
         beaker = request.environ.get('beaker.session')
         beaker['login_info'] = create_user_dict(userinfo)
         beaker.save()
         return userinfo
     return False
Esempio n. 27
0
 def is_auth_by_header(self):
     header = request.get_header('Authorization')
     if header is None:
         return False
     pair = parse_auth(header)
     if pair is None:
         return False
     user, passwd = pair
     userinfo = get_user_info(self.db.session, user)
     if userinfo is None:
         return False
     if authenticate(passwd, userinfo):
         beaker = request.environ.get('beaker.session')
         beaker['login_info'] = create_user_dict(userinfo)
         beaker.save()
         return True
     return False
Esempio n. 28
0
def br():
    a_token = request.headers.get('Authorization')
    try: credentials = parse_auth(a_token)
    except:
        raise HTTPResponse('Please provide a Basic Authentication header\n', 403)
    if not utils.is_authenticated(*credentials): raise HTTPResponse(
        'Unauthenticated\n', 403)
    u_and_c = credentials[0].split('__')
    user = u_and_c[0]
    if len(u_and_c) >1:
        company = u_and_c[1]
    else:
        company = user
    request.creds = utils.LocalEnv()
    request.creds.user = user
    request.creds.company = company
    request.creds.password = credentials[1]
Esempio n. 29
0
def br():
    a_token = request.headers.get('Authorization')
    try:
        credentials = parse_auth(a_token)
    except:
        raise HTTPResponse('Please provide a Basic Authentication header\n',
                           403)
    if not utils.is_authenticated(*credentials):
        raise HTTPResponse('Unauthenticated\n', 403)
    u_and_c = credentials[0].split('__')
    user = u_and_c[0]
    if len(u_and_c) > 1:
        company = u_and_c[1]
    else:
        company = user
    request.creds = utils.LocalEnv()
    request.creds.user = user
    request.creds.company = company
    request.creds.password = credentials[1]
Esempio n. 30
0
def api_registervnf():
  if auth_method == 'gatekeeper':
    print 'gatekeeper'
    if not gatekeeper_authentication(request.get_header('X-Auth-Token')):
      abort(401)
  if auth_method == 'basic':
    print 'basic authentication method'
    user, passwd = parse_auth(request.get_header('Authorization'))
    if not check_credentials(user, passwd):
      abort(401)
  try:
    vnfm_req = loads(request.body.getvalue())
    print "\n######## REGISTERING VNF ########\n"
    print "VNF Id: " + vnfm_req['id'] + '\n'
    print "VNF Descriptor: "
    print vnfm_req
    register_vnf(vnfm_req['id'], vnfm_req['vnfd'])
    print "\n############## END ##############\n"
  except:
    abort(400)
Esempio n. 31
0
def login():
    auth = request.get_header('Authorization')
    
    try:
        username, password = parse_auth(auth)
    except:
        response.content_type = 'application/json'
        response.status = 401
        resp = {'error': 'Empty credentials'}
        return dumps(resp)

    if check_auth(username, password):
        response.content_type = 'application/json'
        response.status = 200
        return dumps({'token': user_token(username)})

    response.content_type = 'application/json'
    response.status = 401
    response.headers['WWW-Authenticate'] = 'Basic realm="Login Required"'
    resp = {'message': 'Authentication failed'}
    return dumps(resp)
Esempio n. 32
0
        def decorator(*args, **kwargs):
            if not self.users:
                self.users = args[0].users
            if not self.__l:
                self.__l = args[0].logger

            (username, password) = bottle.parse_auth(bottle.request.get_header('Authorization'))

            self.__l.debug('username: %s' % username)
            self.__l.debug('password: %s' % password)

            """User/pass based auth"""
            user = self.users.get(username)
            server = None
            if not user:
                self.__l.error('No user found for %s' % username)
                bottle.abort(401, 'Access denied')
            if not self.users.validate_password(username, password):
                self.__l.error('Password mismatch')
                bottle.abort(401, 'Access denied')

            return f(*args, username=user['username'], user=user, server=server, **kwargs)
Esempio n. 33
0
 def login_basic(self):
     auth = request.headers.get('Authorization')
     email,p = parse_auth(auth)        
     response.set_cookie("account", email, secret="abc-123-!@#")
     return self.send("<html><script>window.close();</script></html>", ct="text/html");
Esempio n. 34
0
def external(widget_type, identifier, action=None):
    # pylint: disable=too-many-return-statements, unsupported-membership-test
    # pylint: disable=unsubscriptable-object
    """
    Application external identifier

    Use internal authentication (if a user is logged-in) or external basic authentication provided
    by the requiring application.

    Search in the known 'widget_type' (widget or table) to find the element 'identifier'.

    Use the 'links' parameter to prefix the navigation URLs.
    """

    session = request.environ['beaker.session']
    if 'current_user' in session:
        current_user = session['current_user']
        if not user_authentication(current_user.token, None):
            # Redirect to application login page
            logger.warning(
                "before_request, current_user in the session is not authenticated."
                " Redirecting to the login page...")
            redirect('/login')
        credentials = current_user.token + ':'

    else:
        # Authenticate external access...
        if 'Authorization' not in request.headers or not request.headers[
                'Authorization']:
            logger.warning("external application access denied")
            response.status = 401
            response.content_type = 'text/html'
            return _(
                '<div>'
                '<h1>External access denied.</h1>'
                '<p>To embed an Alignak WebUI widget or table, you must provide credentials.<br>'
                'Log into the Alignak WebUI with your credentials, or make a request '
                'with a Basic-Authentication allowing access to Alignak backend.</p>'
                '</div>')

        # Get HTTP authentication
        authentication = request.headers.get('Authorization')
        username, password = parse_auth(authentication)

        if not user_authentication(username, password):
            logger.warning("external application access denied for %s",
                           username)
            response.status = 401
            response.content_type = 'text/html'
            return _(
                '<div>'
                '<h1>External access denied.</h1>'
                '<p>The provided credentials do not grant you access to Alignak WebUI.<br>'
                'Please provide proper credentials.</p>'
                '</div>')

        current_user = session['current_user']
        credentials = current_user.token + ':'

        # Make session data available in the templates
        BaseTemplate.defaults['current_user'] = session['current_user']
        BaseTemplate.defaults['target_user'] = session['target_user']
        BaseTemplate.defaults['datamgr'] = session['datamanager']

    logger.debug("External request, widget type: %s", widget_type)

    if widget_type not in ['widget', 'table', 'list', 'host']:
        logger.warning("External application requested unknown type: %s",
                       widget_type)
        response.status = 409
        response.content_type = 'text/html'
        return _('<div><h1>Unknown required type: %s.</h1>'
                 '<p>The required type is unknwown</p></div>' % widget_type)

    if widget_type == 'widget':
        found_widget = None
        for widget in get_app_webui().get_widgets_for('external'):
            if identifier == widget['id']:
                found_widget = widget
                break
        else:
            logger.warning("External application requested unknown widget: %s",
                           identifier)
            response.status = 409
            response.content_type = 'text/html'
            return _('<div><h1>Unknown required widget: %s.</h1>'
                     '<p>The required widget is not available.</p></div>' %
                     identifier)
        logger.debug("Found widget: %s", found_widget)

        embedded_element = found_widget['function'](embedded=True,
                                                    identifier=identifier,
                                                    credentials=credentials)

        if request.params.get('page', 'no') == 'no':
            return embedded_element

        return template('external_widget',
                        {'embedded_element': embedded_element})

    if widget_type == 'table':
        found_table = None
        for table in get_app_webui().get_tables_for('external'):
            if identifier == table['id']:
                found_table = table
                break
        else:
            logger.warning("External application requested unknown table: %s",
                           identifier)
            response.status = 409
            response.content_type = 'text/html'
            return _('<div><h1>Unknown required table: %s.</h1>'
                     '<p>The required table is not available.</p></div>' %
                     identifier)
        logger.debug("Found table: %s", found_table)

        if action and action in found_table['actions']:
            logger.info("Required action: %s", action)
            return found_table['actions'][action]()

        if request.params.get('page', 'no') == 'no':
            return found_table['function'](embedded=True,
                                           identifier=identifier,
                                           credentials=credentials)

        return template(
            'external_table', {
                'embedded_element':
                found_table['function'](embedded=True,
                                        identifier=identifier,
                                        credentials=credentials)
            })

    if widget_type == 'list':
        if identifier in get_app_webui().lists:
            return get_app_webui().lists[identifier]['function'](embedded=True)
        else:
            logger.warning("External application requested unknown list: %s",
                           identifier)
            return WebUI.response_ko(_('Unknown required list'))

    if widget_type == 'host':
        if not action:
            logger.warning(
                "External application requested host widget without widget name"
            )
            response.status = 409
            response.content_type = 'text/html'
            return _('<div><h1>Missing host widget name.</h1>'
                     '<p>You must provide a widget name</p></div>')

        # Identifier is the host identifier, not the widget one !
        found_widget = None
        for widget in get_app_webui().get_widgets_for('host'):
            if action == widget['id']:
                found_widget = widget
                break
        else:
            logger.warning("External application requested unknown widget: %s",
                           action)
            response.status = 409
            response.content_type = 'text/html'
            return _('<div><h1>Unknown required widget: %s.</h1>'
                     '<p>The required widget is not available.</p></div>' %
                     action)
        logger.debug("Found host widget: %s", found_widget)

        if request.params.get('page', 'no') == 'no':
            return found_widget['function'](host_id=identifier,
                                            widget_id=found_widget['id'],
                                            embedded=True,
                                            identifier=identifier,
                                            credentials=credentials)

        return template(
            'external_widget', {
                'embedded_element':
                found_widget['function'](host_id=identifier,
                                         widget_id=found_widget['id'],
                                         embedded=True,
                                         identifier=identifier,
                                         credentials=credentials)
            })
Esempio n. 35
0
def external(widget_type, identifier, action=None):
    # pylint: disable=too-many-return-statements, unsupported-membership-test
    # pylint: disable=unsubscriptable-object, too-many-locals
    """Application external identifier

    Use internal authentication (if a user is logged-in) or external basic authentication provided
    by the requiring application.

    Search in the known 'widget_type' (widget or table) to find the element 'identifier'.

    Use the 'links' parameter to prefix the navigation URLs.
    """

    logger.warning("external request, url: %s %s", request.method,
                   request.urlparts.path)

    # Get the WebUI instance
    webui = request.app.config['webui']

    # Get the server session (it always exist...)
    session = request.environ['beaker.session']
    st = datetime.datetime.fromtimestamp(
        session['_creation_time']).strftime('%Y-%m-%d %H:%M:%S')
    origin = request.environ.get(
        'HTTP_X_FORWARDED_FOR') or request.environ.get('REMOTE_ADDR')
    logger.debug("client: %s, session: %s / %s / %s", origin, session.id, st,
                 session)

    current_user = None
    if 'current_user' in session and session['current_user']:
        current_user = session['current_user']

        # Get the application instance authentication
        logger.debug("webapp: %s, request app: %s", webapp, request.app)
        logger.debug("current_user: %s", current_user)
        if not webapp.user_authentication(current_user.token, None, session):
            # Redirect to application login page
            logger.warning(
                "External request. User in the session is not authenticated. "
                "Redirecting to the login page...")
            redirect('/login')
        credentials = current_user.token + ':'

    else:
        # Authenticate external access...
        if 'Authorization' not in request.headers or not request.headers[
                'Authorization']:
            logger.warning("external application access denied")
            response.status = 401
            response.content_type = 'text/html'
            return _(
                '<div>'
                '<h1>External access denied.</h1>'
                '<p>To embed an Alignak WebUI widget or table, you must provide credentials.<br>'
                'Log into the Alignak WebUI with your credentials, or make a request '
                'with a Basic-Authentication allowing access to Alignak backend.</p>'
                '</div>')

        # Get HTTP authentication
        authentication = request.headers.get('Authorization')
        username, password = parse_auth(authentication)

        # Get the application instance authentication
        logger.debug("external application, checking authentication for %s",
                     username)
        if not webapp.user_authentication(username, password, session):
            logger.warning("external application access denied for %s",
                           username)
            response.status = 401
            response.content_type = 'text/html'
            return _(
                '<div>'
                '<h1>External access denied.</h1>'
                '<p>The provided credentials do not grant you access to Alignak WebUI.<br>'
                'Please provide proper credentials.</p>'
                '</div>')

        current_user = session['current_user']
        credentials = current_user.token + ':'

        # Make session data available in the templates
        BaseTemplate.defaults['current_user'] = session['current_user']

        # Make data manager available in the request and in the templates
        request.app.datamgr = DataManager(webapp, session=session)
        request.app.datamgr.load()
        logger.warning("request.app.datamgr: %s", request.app.datamgr)
        BaseTemplate.defaults['datamgr'] = request.app.datamgr

    logger.info("External request, element type: %s", widget_type)

    if widget_type not in [
            'files', 'widget', 'table', 'list', 'host', 'service', 'user'
    ]:
        logger.warning("External application requested unknown type: %s",
                       widget_type)
        response.status = 409
        response.content_type = 'text/html'
        return _('<div><h1>Unknown required type: %s.</h1>'
                 '<p>The required type is unknwown</p></div>' % widget_type)

    if widget_type == 'files':
        if identifier == 'js_list':
            response.status = 200
            response.content_type = 'application/json'
            return json.dumps({'status': 'ok', 'files': webui.js_list})

        if identifier == 'css_list':
            response.status = 200
            response.content_type = 'application/json'
            return json.dumps({'status': 'ok', 'files': webui.css_list})

        logger.warning("External application requested unknown files: %s",
                       identifier)
        response.status = 409
        response.content_type = 'application/json'
        return json.dumps({
            'status': 'ko',
            'message': "Unknown files list: %s" % identifier
        })

    if widget_type == 'widget':
        found_widget = None
        for widget in webui.get_widgets_for('external'):
            if identifier == widget['id']:
                found_widget = widget
                break
        else:
            logger.warning("External application requested unknown widget: %s",
                           identifier)
            response.status = 409
            response.content_type = 'text/html'
            return _('<div><h1>Unknown required widget: %s.</h1>'
                     '<p>The required widget is not available.</p></div>' %
                     identifier)
        logger.debug("found widget: %s", found_widget)

        embedded_element = found_widget['function'](embedded=True,
                                                    identifier=identifier,
                                                    credentials=credentials)

        if request.params.get('page', 'no') == 'no':
            return embedded_element

        return template('external_widget',
                        {'embedded_element': embedded_element})

    if widget_type == 'table':
        found_table = None
        for table in webui.get_tables_for('external'):
            if identifier == table['id']:
                found_table = table
                break
        else:
            logger.warning("External application requested unknown table: %s",
                           identifier)
            response.status = 409
            response.content_type = 'text/html'
            return _('<div><h1>Unknown required table: %s.</h1>'
                     '<p>The required table is not available.</p></div>' %
                     identifier)
        logger.info("Found table: %s", found_table)

        if action and action in found_table['actions']:
            logger.info("Required action: %s = %s", action,
                        found_table['actions'][action])
            return found_table['actions'][action]()

        if request.params.get('page', 'no') == 'no':
            return found_table['function'](embedded=True,
                                           identifier=identifier,
                                           credentials=credentials)

        return template(
            'external_table', {
                'embedded_element':
                found_table['function'](embedded=True,
                                        identifier=identifier,
                                        credentials=credentials)
            })

    if widget_type == 'list':
        if identifier in webui.lists:
            return webui.lists[identifier]['function'](embedded=True)

        logger.warning("External application requested unknown list: %s",
                       identifier)
        response.status = 409
        response.content_type = 'text/html'
        return _('<div><h1>Unknown required list: %s.</h1>'
                 '<p>The required list is not available.</p></div>' %
                 identifier)

    if widget_type in ['host', 'service', 'user']:
        if not action:
            logger.warning(
                "External application requested %s widget without widget name",
                widget_type)
            response.status = 409
            response.content_type = 'text/html'
            return _('<div><h1>Missing %s widget name.</h1>'
                     '<p>You must provide a widget name</p></div>' %
                     widget_type)

        # Identifier is the element identifier, not the widget one !
        found_widget = None
        for widget in webui.get_widgets_for(widget_type):
            if action == widget['id']:
                found_widget = widget
                break
        else:
            logger.warning("External application requested unknown widget: %s",
                           action)
            response.status = 409
            response.content_type = 'text/html'
            return _('<div><h1>Unknown required widget: %s.</h1>'
                     '<p>The required widget is not available.</p></div>' %
                     action)
        logger.debug("Found %s widget: %s", widget_type, found_widget)

        if request.params.get('page', 'no') == 'no':
            return found_widget['function'](element_id=identifier,
                                            widget_id=found_widget['id'],
                                            embedded=True,
                                            identifier=identifier,
                                            credentials=credentials)

        return template(
            'external_widget', {
                'embedded_element':
                found_widget['function'](element_id=identifier,
                                         widget_id=found_widget['id'],
                                         embedded=True,
                                         identifier=identifier,
                                         credentials=credentials)
            })
Esempio n. 36
0
 def login_basic(self):
     auth = request.headers.get('Authorization')
     email,p = parse_auth(auth)        
     response.set_cookie(self.COOKIE_NAME_ACCOUNT, email, secret=self.COOKIE_SECRET)
     return self.send("<html><script>window.close();</script></html>", ct="text/html");
Esempio n. 37
0
    def register(self, username=None, password=None, user_info=None):
        '''
        Register a new user.

        Parameters
        ----------
        username : str
            Username to register. Must be unique in the application. It can also be passed as the
            value of key `Username` as part of the GET or POST request.
        password : str
            Plaintext password for this username. It can also be passed as the value of key
            `Password` as part of the GET or POST request.
        user_info : dict
            Dictionary containing any additional information about this user. The key
            `RemoteIpAddr` will be added to this dictionary with the value provided by
            `bottle.request.environ.get("REMOTE_ADDR")` prior to matching the user against the
            whitelist and blacklist parameters given to the constructor of this class.
            The parameters `username` and `password` can also be passed to this method as items in
            the `user_info` dictionary. Any key-value pairs not described above that are passed as
            part of the GET or POST request will be added to this dictionary. If the requested
            security level requires it, all user info including username and password must be
            serialized and signed/encrypted into a field named `Data` as a json string. In that
            case, the single-use `Token` provided by the key exchange must also be provided.

        Returns
        -------
        response : bottle.HTTPResponse
            Status code and body will determine if the login was successful. If successful, the
            body will contain the user record in JSON format. 

        Examples
        --------
        >>> app = BottleShip()
        >>> app.register("john", "1234").body
            '{"Username": "******", "Password": "******", "__id__": "2c849965-251f-4b5d-
            8a27-77f86fa9e0e3", "RemoteIpAddr": null}'
        '''
        request_dict = PandasDatabase._request(bottle.request, request_fallback=user_info)

        # If data and token are provided, then this must be secure data transfer
        secure_data = False
        if 'Data' in request_dict and 'Token' in request_dict:
            secure_data = True
            request_dict, err_msg = self._read_secure_json(request_dict)
            if err_msg:
                self._print(err_msg)
                return bottle.HTTPResponse(status=400, body=err_msg)

        # Cleanup information from the request
        request_dict = {tos(req_k): tos(req_v) for req_k, req_v in request_dict.items()
                        if re.match(PandasDatabase._colname_rgx, tos(req_k))}

        # Verify username and password
        username = username or request_dict.get('Username')
        password = password or request_dict.get('Password', '')
        auth_header = bottle.request.get_header('Authorization')
        if auth_header: # If auth is available in the headers, take that
            username, password = bottle.parse_auth(auth_header)
        error_msg = self._error_username_password(username, password)
        if error_msg:
            self._print(error_msg)
            return bottle.HTTPResponse(status=400, body=error_msg)

        # Look for existing user record and, if any, reject registration
        user_record = self.pddb.find_one(
            'bottleship_users', where={'Username': username}, astype='dict')
        if user_record:
            msg = 'Register error: Provided username already exists in the database.'
            self._print(msg)
            return bottle.HTTPResponse(status=400, body=msg)

        # Get the user requested security level or default
        security_level = request_dict.get('SecurityLevel', self.allowed_security[0])
        request_dict['SecurityLevel'] = security_level
        if security_level not in self.allowed_security:
            msg = 'Login error: Security level must be one of: %r' % list(self.allowed_security)
            self._print(msg)
            res = bottle.HTTPResponse(status=400, body=msg)
            return res
        elif not secure_data and ('hmac' in security_level or 'rsa' in security_level):
            msg = ('Login error: Security level requested requires secure data transfer but '
                   'plaintext was used instead')
            self._print(msg)
            res = bottle.HTTPResponse(status=400, body=msg)
            return res

        # Get user's IP address from request
        request_dict['RemoteIpAddr'] = bottle.request.environ.get('REMOTE_ADDR', '')

        # Insert the hashed password into user's record
        if password is not None:
            request_dict['Password'] = str(hash(password))

        # Validate the user against our rules
        if not self._check_user(request_dict):
            msg = 'User does not meet the requirements.'
            self._print(msg)
            return bottle.HTTPResponse(status=403, body=msg)

        # Insert or update the user record
        user_cond = {'Username': username}
        user_record = self.pddb.upsert('bottleship_users', record=request_dict, 
                                       where=user_cond, astype='dict')[0]

        # Depending on the security level, we may need to encrypt or sign the data
        user_record_json = self._dump_user_record(security_level, user_record)

        # Return the inserted user record
        return bottle.HTTPResponse(status=200, body=user_record_json)
def external(widget_type, identifier, action=None):
    # pylint: disable=too-many-return-statements, unsupported-membership-test
    # pylint: disable=unsubscriptable-object, too-many-locals
    """Application external identifier

    Use internal authentication (if a user is logged-in) or external basic authentication provided
    by the requiring application.

    Search in the known 'widget_type' (widget or table) to find the element 'identifier'.

    Use the 'links' parameter to prefix the navigation URLs.
    """

    logger.warning("external request, url: %s %s", request.method, request.urlparts.path)

    # Get the WebUI instance
    webui = request.app.config['webui']

    # Get the server session (it always exist...)
    session = request.environ['beaker.session']
    st = datetime.datetime.fromtimestamp(session['_creation_time']).strftime('%Y-%m-%d %H:%M:%S')
    origin = request.environ.get('HTTP_X_FORWARDED_FOR') or request.environ.get('REMOTE_ADDR')
    logger.debug("client: %s, session: %s / %s / %s", origin, session.id, st, session)

    current_user = None
    if 'current_user' in session and session['current_user']:
        current_user = session['current_user']

        # Get the application instance authentication
        logger.debug("webapp: %s, request app: %s", webapp, request.app)
        logger.debug("current_user: %s", current_user)
        if not webapp.user_authentication(current_user.token, None, session):
            # Redirect to application login page
            logger.warning("External request. User in the session is not authenticated. "
                           "Redirecting to the login page...")
            redirect('/login')
        credentials = current_user.token + ':'

    else:
        # Authenticate external access...
        if 'Authorization' not in request.headers or not request.headers['Authorization']:
            logger.warning("external application access denied")
            response.status = 401
            response.content_type = 'text/html'
            return _(
                '<div>'
                '<h1>External access denied.</h1>'
                '<p>To embed an Alignak WebUI widget or table, you must provide credentials.<br>'
                'Log into the Alignak WebUI with your credentials, or make a request '
                'with a Basic-Authentication allowing access to Alignak backend.</p>'
                '</div>'
            )

        # Get HTTP authentication
        authentication = request.headers.get('Authorization')
        username, password = parse_auth(authentication)

        # Get the application instance authentication
        logger.debug("external application, checking authentication for %s", username)
        if not webapp.user_authentication(username, password, session):
            logger.warning("external application access denied for %s", username)
            response.status = 401
            response.content_type = 'text/html'
            return _(
                '<div>'
                '<h1>External access denied.</h1>'
                '<p>The provided credentials do not grant you access to Alignak WebUI.<br>'
                'Please provide proper credentials.</p>'
                '</div>'
            )

        current_user = session['current_user']
        credentials = current_user.token + ':'

        # Make session data available in the templates
        BaseTemplate.defaults['current_user'] = session['current_user']

        # Make data manager available in the request and in the templates
        request.app.datamgr = DataManager(webapp, session=session)
        request.app.datamgr.load()
        logger.warning("request.app.datamgr: %s", request.app.datamgr)
        BaseTemplate.defaults['datamgr'] = request.app.datamgr

    logger.info("External request, element type: %s", widget_type)

    if widget_type not in ['files', 'widget', 'table', 'list', 'host', 'service', 'user']:
        logger.warning("External application requested unknown type: %s", widget_type)
        response.status = 409
        response.content_type = 'text/html'
        return _(
            '<div><h1>Unknown required type: %s.</h1>'
            '<p>The required type is unknwown</p></div>' % widget_type
        )

    if widget_type == 'files':
        if identifier == 'js_list':
            response.status = 200
            response.content_type = 'application/json'
            return json.dumps({'status': 'ok', 'files': webui.js_list})

        if identifier == 'css_list':
            response.status = 200
            response.content_type = 'application/json'
            return json.dumps({'status': 'ok', 'files': webui.css_list})

        logger.warning("External application requested unknown files: %s", identifier)
        response.status = 409
        response.content_type = 'application/json'
        return json.dumps({'status': 'ko', 'message': "Unknown files list: %s" % identifier})

    if widget_type == 'widget':
        found_widget = None
        for widget in webui.get_widgets_for('external'):
            if identifier == widget['id']:
                found_widget = widget
                break
        else:
            logger.warning("External application requested unknown widget: %s", identifier)
            response.status = 409
            response.content_type = 'text/html'
            return _(
                '<div><h1>Unknown required widget: %s.</h1>'
                '<p>The required widget is not available.</p></div>' % identifier
            )
        logger.debug("found widget: %s", found_widget)

        embedded_element = found_widget['function'](
            embedded=True,
            identifier=identifier, credentials=credentials
        )

        if request.params.get('page', 'no') == 'no':
            return embedded_element

        return template('external_widget', {
            'embedded_element': embedded_element
        })

    if widget_type == 'table':
        found_table = None
        for table in webui.get_tables_for('external'):
            if identifier == table['id']:
                found_table = table
                break
        else:
            logger.warning("External application requested unknown table: %s", identifier)
            response.status = 409
            response.content_type = 'text/html'
            return _(
                '<div><h1>Unknown required table: %s.</h1>'
                '<p>The required table is not available.</p></div>' % identifier
            )
        logger.info("Found table: %s", found_table)

        if action and action in found_table['actions']:
            logger.info("Required action: %s = %s", action, found_table['actions'][action])
            return found_table['actions'][action]()

        if request.params.get('page', 'no') == 'no':
            return found_table['function'](
                embedded=True, identifier=identifier, credentials=credentials
            )

        return template('external_table', {
            'embedded_element': found_table['function'](
                embedded=True, identifier=identifier, credentials=credentials
            )
        })

    if widget_type == 'list':
        if identifier in webui.lists:
            return webui.lists[identifier]['function'](embedded=True)

        logger.warning("External application requested unknown list: %s", identifier)
        response.status = 409
        response.content_type = 'text/html'
        return _(
            '<div><h1>Unknown required list: %s.</h1>'
            '<p>The required list is not available.</p></div>' % identifier
        )

    if widget_type in ['host', 'service', 'user']:
        if not action:
            logger.warning(
                "External application requested %s widget without widget name", widget_type
            )
            response.status = 409
            response.content_type = 'text/html'
            return _(
                '<div><h1>Missing %s widget name.</h1>'
                '<p>You must provide a widget name</p></div>' % widget_type
            )

        # Identifier is the element identifier, not the widget one !
        found_widget = None
        for widget in webui.get_widgets_for(widget_type):
            if action == widget['id']:
                found_widget = widget
                break
        else:
            logger.warning("External application requested unknown widget: %s", action)
            response.status = 409
            response.content_type = 'text/html'
            return _(
                '<div><h1>Unknown required widget: %s.</h1>'
                '<p>The required widget is not available.</p></div>' % action
            )
        logger.debug("Found %s widget: %s", widget_type, found_widget)

        if request.params.get('page', 'no') == 'no':
            return found_widget['function'](
                element_id=identifier, widget_id=found_widget['id'],
                embedded=True, identifier=identifier, credentials=credentials
            )

        return template('external_widget', {
            'embedded_element': found_widget['function'](
                element_id=identifier, widget_id=found_widget['id'],
                embedded=True, identifier=identifier, credentials=credentials
            )
        })
Esempio n. 39
0
    def login(self, username=None, password=None, _request_fallback=None):
        '''
        Log in an existing user.

        Parameters
        ----------
        username : str
            Username to login. It can also be passed as the value of key `Username` as part of the
            GET or POST request.
        password : str
            Plaintext password for this username. It can also be passed as the value of key
            `Password` as part of the GET or POST request. If the requested security level requires
            it, password must be signed/encrypted.
        _request_fallback : dict
            Used for testing purposes.
            The parameters `Username` and `Password` can also be passed to this method as items in
            the `_request_fallback` dictionary.

        Returns
        -------
        response : bottle.HTTPResponse
            Status code and body will determine if the login was successful. If successful, the
            body will contain the user record in JSON format. 

        Examples
        --------
        >>> app = BottleShip()
        >>> res = app.login("john", "1234")
        >>> print(res.status_code, res.body)
            403 Login error: Provided password does not match records for that username or username does not exist.
        '''
        request_dict = PandasDatabase._request(bottle.request, request_fallback=_request_fallback)

        # If data and token are provided, then this must be secure data transfer
        secure_data = False
        if 'Data' in request_dict and 'Token' in request_dict:
            secure_data = True
            request_dict, err_msg = self._read_secure_json(request_dict)
            if err_msg:
                self._print(err_msg)
                return bottle.HTTPResponse(status=400, body=err_msg)

        # Cleanup information from the request
        request_dict = {tos(req_k): tos(req_v) for req_k, req_v in request_dict.items()
                        if re.match(PandasDatabase._colname_rgx, tos(req_k))}

        # Verify username and password
        username = username or request_dict.get('Username')
        password = password or request_dict.get('Password', '')
        auth_header = bottle.request.get_header('Authorization')
        if auth_header: # If auth is available in the headers, take that
            username, password = bottle.parse_auth(auth_header)
        error_msg = self._error_username_password(username, password)
        if error_msg:
            self._print(error_msg)
            return bottle.HTTPResponse(status=400, body=error_msg)

        # Look for existing user record
        user_record = self.pddb.find_one(
            'bottleship_users', where={'Username': username}, astype='dict')
        if not user_record:
            msg = ('Login error: Provided password does not match records for that username or '
                   'username does not exist.')
            self._print(msg)
            return bottle.HTTPResponse(status=403, body=msg)

        # Make sure that the security level is supported
        security_level = request_dict.get(
            'SecurityLevel', user_record.get('SecurityLevel', self.allowed_security[0]))
        if 'ipaddr' in user_record.get('SecurityLevel') and 'ipaddr' not in security_level:
            security_level += '+ipaddr' # Force IP address verification if registration requests it
        user_record['SecurityLevel'] = security_level
        if security_level not in self.allowed_security:
            msg = 'Login error: Security level must be one of: %r' % list(self.allowed_security)
            self._print(msg)
            res = bottle.HTTPResponse(status=400, body=msg)
            return res
        elif not secure_data and ('hmac' in security_level or 'rsa' in security_level):
            msg = ('Login error: Security level requested requires secure data transfer but '
                   'plaintext was used instead')
            self._print(msg)
            res = bottle.HTTPResponse(status=400, body=msg)
            return res

        # Verify user password
        if 'Password' in user_record and user_record.get('Password') != str(hash(password)):
            msg = ('Login error: Provided password does not match records for that username or '
                   'username does not exist.')
            self._print(msg)
            return bottle.HTTPResponse(status=403, body=msg)

        # Get user's IP address from request
        ip_addr = bottle.request.environ.get('REMOTE_ADDR', '')
        if ip_addr != user_record.get('RemoteIpAddr'):
            if 'ipaddr' in security_level:
                msg = 'Login error: Registration IP address does not match login attempt.'
                self._print(msg)
                return bottle.HTTPResponse(status=403, body=msg)
            else:
                user_record['RemoteIpAddr'] = ip_addr

        # Provide user with a temporary token
        token_key = str(request_dict.get('Key') if secure_data else user_record.get('Key'))
        token_record = self._gen_token(username, security_level=security_level, key=token_key)
        user_record['Token'] = token_record['Token']

        # Update the user record
        user_cond = {'Username': username}
        user_record['Key'] = token_record.get('Key')
        user_record['LastLogin'] = str(time.time())
        user_record = self.pddb.upsert('bottleship_users', record=user_record, 
                                         where=user_cond, astype='dict')[0]

        # Depending on the security level, we may need to encrypt or sign the data
        user_record_json = self._dump_user_record(security_level, user_record)

        res = bottle.HTTPResponse(status=200, body=user_record_json)
        res.set_cookie('Token', token_record['Token'], path='/', expires=int(float(token_record.get('Expiry'))))
        return res
Esempio n. 40
0
def call_api(func, args=""):
    add_json_header(response)

    s = request.environ.get('beaker.session')
    # Accepts standard http auth
    auth = parse_auth(request.get_header('Authorization', ''))
    if 'session' in request.POST or 'session' in request.GET:
        # removes "' so it works on json strings
        s = s.get_by_id(purge.chars(request.params.get('session'), "'\""))
    elif auth:
        user = API.check_auth(auth[0], auth[1],
                              request.environ.get('REMOTE_ADDR', None))
        # if auth is correct create a pseudo session
        if user:
            s = {'uid': user.uid}

    api = get_user_api(s)
    if not api:
        return error(401, "Unauthorized")

    if not API.is_authorized(func, api.user):
        return error(403, "Forbidden")

    if not hasattr(API.EXTERNAL, func) or func.startswith("_"):
        print("Invalid API call", func)
        return error(404, "Not Found")

    # TODO: possible encoding
    # TODO: Better error codes on invalid input

    args = [loads(unquote(arg)) for arg in args.split("/")[1:]]
    kwargs = {}

    # accepts body as json dict
    if request.json:
        kwargs = request.json

    # file upload, reads whole file into memory
    for name, f in request.files.items():
        kwargs['filename'] = f.filename
        with closing(io.StringIO()) as content:
            f.save(content)
            kwargs[name] = content.getvalue()

    # convert arguments from json to obj separately
    for x, y in request.params.items():
        try:
            if not x or not y or x == "session":
                continue
            kwargs[x] = loads(unquote(y))
        except Exception as e:
            # Unsupported input
            msg = "Invalid Input {0}, {1} : {2}".format(x, y, e.message)
            print_exc()
            print(msg)
            return error(415, msg)

    try:
        result = getattr(api, func)(*args, **kwargs)
        # null is invalid json response
        if result is None:
            result = True
        return json_response(result)

    except ExceptionObject as e:
        return error(400, e.message)
    except Exception as e:
        print_exc()
        return error(500, {'error': e.message, 'traceback': format_exc()})
Esempio n. 41
0
 def __get_username(self):
     (username, password) = bottle.parse_auth(bottle.request.get_header('Authorization'))
     return username
Esempio n. 42
0
 def __check_auth(self):
     auth = request.headers.get('Authorization')
     credentials = parse_auth(auth)
     if self.__config.http_user != credentials[
             0] or self.__config.http_pass != credentials[1]:
         raise Exception('Request is not authorized')