def get(self, login=None):
        """get users"""
        user_profile = get_user(request=self.request)

        # return all users 
        if login is None:
            # security checks
            if user_profile['role'] != constant.ROLE_ADMIN:
                raise HTTP_403("access refused")

            success, details = usersmanager.get_users()
        
        # return one user
        else:
            
            login = fix_encoding_uri_param(login)

            # security checks
            if user_profile['role'] != constant.ROLE_ADMIN:
                if user_profile["login"] != login:
                    raise HTTP_403("access refused")

            #if login not in 
            success, details = usersmanager.get_user(login=login)

        if success != constant.OK:
            raise HTTP_500(details)

        return {"cmd": self.request.path,
                "users": details}
Exemplo n.º 2
0
    def before(self):
        if self.request.method == 'OPTIONS':
            return

        user = None
        token = self._parse_auth_header()
        if token:
            try:
                payload = jwt_auth.decode_token(token, self.audience)
                user_id = payload.get('id')

                user = rpc_call('get_vk_user', user_id)

                if not user:
                    raise HTTP_403("Access denied")
            except jwt_auth.DecodeError as e:
                self.logger.warning(e)
                raise HTTP_401("Unable to parse authentication token")
            except jwt_auth.ExpiredSignatureError:
                if 'guest' not in self.audience:
                    raise HTTP_401("Expired token")
            except jwt_auth.InvalidAudienceError:
                raise HTTP_403("Incorrect claims")
            except Exception as e:
                self.logger.exception(e)
                raise HTTP_500("Unable to parse authentication token")
        elif 'guest' not in self.audience:
            raise HTTP_403("Access denied")

        self.user = user or {}
Exemplo n.º 3
0
    def post(self, file_path):
        """upload file"""
        user_profile = _get_user(request=self.request)

        if user_profile['monitor']:
            raise HTTP_403("Access refused")

        try:
            projectId = self.request.args.get("workspace", 1)
            file_path = fix_encoding_uri_param(file_path)
            
            fileContent = self.request.data.get("file-content")
            if fileContent is None:
                raise EmptyValue("Please specify a file content")
        except EmptyValue as e:
            raise HTTP_400("%s" % e)
        except Exception as e:
            raise HTTP_400("Invalid request provided (%s ?)" % e)

        _check_project_permissions(
            user_login=user_profile['login'],
            project_id=projectId)

        try:
            filePath = os.path.normpath(file_path)
            p  = pathlib.Path(filePath)
            
            fileExt = p.suffix[1:]
            fileName = p.stem
            filePath = filePath.rsplit("%s%s" %(p.stem, p.suffix))[0]
        except Exception as e:
            raise HTTP_403('Invalid file name: %s' % e)
            
        success, _, _, _, _, _, _, _, _ = RepoTests.instance().uploadFile(pathFile=filePath,
                                                                        nameFile=fileName,
                                                                        extFile=fileExt,
                                                                        contentFile=fileContent,
                                                                        login=user_profile['login'],
                                                                        project=projectId,
                                                                        overwriteFile=True,
                                                                        createFolders=True,
                                                                        lockMode=False,
                                                                        binaryMode=True)

        if success != Context.instance().CODE_OK:
            raise HTTP_500("Unable to upload file")
            
        return {"cmd": self.request.path,
                "message": "success"}
    def patch(self, login):
        """update user"""
        user_profile = get_user(request=self.request)
        login = fix_encoding_uri_param(login)

        if user_profile['role'] != constant.ROLE_ADMIN:
            if user_profile["login"] != login:
                raise HTTP_403("access denied")

        cur_pwd = self.request.data.get("current-password")
        if cur_pwd is None:
            raise HTTP_400("Current password is expected")

        new_pwd = self.request.data.get("new-password")
        if new_pwd is None:
            raise HTTP_400("New password is expected")
        if not len(new_pwd):
            raise HTTP_400("password name cannot be empty")

        success, details = usersmanager.update_pwd(login=login,
                                                   new_pwd=new_pwd,
                                                   cur_pwd=cur_pwd)
        if success != constant.OK:
            raise HTTP_500(details)

        return {"cmd": self.request.path,
                "message": "password successfully updated"}
    def post(self):
        """add user"""
        user_profile = get_user(request=self.request)
        
        # checking level access to this ressource
        if not user_profile['role'] == constant.ROLE_ADMIN:
            raise HTTP_403("access refused")
        
        # checking query request 
        login = self.request.data.get("login")
        if login is None:
            raise HTTP_400("login is expected")
        if not len(login):
            raise HTTP_400("login name cannot be empty")

        password = self.request.data.get("password")
        if password is None:
            raise HTTP_400("password is expected")
        if not len(password):
            raise HTTP_400("password name cannot be empty")

        role = self.request.data.get("role")
        if role not in constant.ROLE_LIST:
            raise HTTP_400("bad role provided")
            
        success, details = usersmanager.add_user(role=role,
                                                 login=login,
                                                 password=password)
        if success != constant.OK:
            raise HTTP_500(details)

        return {"cmd": self.request.path,
                "message": "user successfully added"}
Exemplo n.º 6
0
    def get(self):
        code = self.request.args.get('code')

        # final stage
        if code:
            return self._final_stage(code)
        elif self.request.args.get('error'):
            self.logger.info('Error response from VK: %s', self.request.args)

            raise HTTP_403(
                self.request.args.get('error_description'),
                self.request.args.get('error_reason',
                                      self.request.args.get('error')))

        # first stage
        client_id = config.get('vk', 'client_id')

        return {
            'auth_url':
            'https://oauth.vk.com/authorize?display=page&v=5.92'
            '&scope=wall,photos,video,pages,docs,groups,offline'
            '&redirect_uri=https://api.vk.com/blank.html'
            '&response_type=code&revoke=1'
            f'&client_id={client_id}'
        }
    def delete(self, login):
        """delete user"""
        user_profile = get_user(request=self.request)

        if user_profile['role'] != constant.ROLE_ADMIN:
            raise HTTP_403("access refused")

        login = fix_encoding_uri_param(login)

        if user_profile["login"] == login:
            raise HTTP_403("deletion not authorized")

        success, details = usersmanager.delete_user(login=login)
        if success != constant.OK:
            raise HTTP_500(details)

        return {"cmd": self.request.path,
                "message": "user successfully removed"}
Exemplo n.º 8
0
        def wrapped(*args, **kwargs):
            remote_ip = args[0].request.environ['REMOTE_ADDR']
            #remote_ip = args[0].request.environ['gunicorn.socket'].getpeername()

            #if remote_ip[0] not in config.allowed_hosts:
            logger.info(f'Remote ip: {remote_ip}')
            if remote_ip not in config.allowed_hosts:
                raise HTTP_403('Forbidden.')
            return f(*args, **kwargs)
    def delete(self, login):
        """delete user"""
        user_profile = get_user(request=self.request)
        login = fix_encoding_uri_param(login)

        if user_profile['role'] != constant.ROLE_ADMIN:
            raise HTTP_403("access refused")
            
        success, details = usersmanager.reset_pwd(login=login)
        if success != constant.OK:
            raise HTTP_500(details)

        return {"cmd": self.request.path,
                "message": "password successfully reseted"} 
    def delete(self, name):
        """Delete a workpsace, only for administrator"""
        user_profile = get_user(request=self.request)
        name = fix_encoding_uri_param(name)

        # checking level access to this ressource
        if user_profile['role'] != constant.ROLE_ADMIN:
            raise HTTP_403("access refused")
            
        success, details = workspacesmanager.del_workspace(name=name)
        if success != constant.OK:
            raise HTTP_500(details)
        
        return {"cmd": self.request.path,
                "message": "project successfully removed"}
Exemplo n.º 11
0
def _check_project_permissions(user_login, project_id):
    """
    Look up project
    """
    try:
        project_id = int(project_id)
    except BaseException:
        raise HTTP_400(
            "Invalid workspace id (Id=%s) provided in request, int expected" %
            str(project_id))

    # get the project id according to the name and checking permissions
    project_authorized = ProjectsManager.instance().checkProjectsAuthorization(user=user_login,
                                                                               projectId=project_id)
    if not project_authorized:
        raise HTTP_403('Permission denied to this workspace')
    def post(self):
        """Add a new project, only for administrator"""
        user_profile = get_user(request=self.request)

        # checking level access to this ressource
        if user_profile['role'] != constant.ROLE_ADMIN:
            raise HTTP_403("access refused")
            
        # checking request
        name = self.request.data.get("name")
        if name is None:
            raise HTTP_400("workspace name is mandatory")
        if not len(name):
            raise HTTP_400("workspace name cannot be empty")

        success, details = workspacesmanager.add_workspace(name=name)
        if success != constant.OK:
            raise HTTP_500(details)
            
        return {"cmd": self.request.path,
                "message": "workspace successfully added",
                "project-id": details}
    def patch(self, login):
        """update user"""
        user_profile = get_user(request=self.request)
        
        # checking level access to this ressource
        if user_profile['role'] != constant.ROLE_ADMIN:
            raise HTTP_403("access refused")
        
        # checking query request
        login = fix_encoding_uri_param(login)
        role = self.request.data.get("role")

        if role not in constant.ROLE_LIST:
            raise HTTP_400("bad role provided")

        success, details = usersmanager.update_role(login=login,
                                                    role=role)
        if success != constant.OK:
            raise HTTP_500(details)

        return {"cmd": self.request.path,
                "message": "role successfully updated"}
Exemplo n.º 14
0
    def delete(self, file_path):
        """delete file"""
        user_profile = _get_user(request=self.request)

        if user_profile['monitor']:
            raise HTTP_403("Access refused")
            
        try:
            projectId = self.request.args.get("workspace", 1)
            file_path = fix_encoding_uri_param(file_path)
        except Exception as e:
            raise HTTP_400("Invalid request provided (%s ?)" % e)
            
        # avoid directory traversal
        filePath = os.path.normpath("/" + file_path)
        
        success = RepoTests.instance().delFile(pathFile=filePath,
                                               project=projectId,
                                               supportSnapshot=False)
        if success != Context.instance().CODE_OK:
            raise HTTP_500("Unable to delete file")
            
        return {"cmd": self.request.path,
                "message": "success"}                
Exemplo n.º 15
0
 def wrapped(*args, **kwargs):
     if not is_logged_in(args[0].request):
         raise HTTP_401("You must be logged in to do this.")
     if not is_admin(args[0].request):
         raise HTTP_403("You must be an admin to do this.")
     return f(*args, **kwargs)
Exemplo n.º 16
0
    def post(self):
        """create job"""
        user_profile = _get_user(request=self.request)

        projectId = self.request.args.get("workspace", 1)
        
        try:
            yamlFile = self.request.data.get("yaml-file")
            if yamlFile is None:
                raise EmptyValue("Please specify a yaml file")
            
            yamlContent = self.request.data.get("yaml-content", "") 

            scheduleId = self.request.data.get("schedule-id", 0)
            _scheduleAt = self.request.data.get("schedule-at")
            _scheduleRepeat = self.request.data.get("schedule-repeat", 0)
            _debugEnabled = self.request.data.get("debug-enabled")
            _fromTime = self.request.data.get("from-time")
            _toTime = self.request.data.get("to-time")

            _testInputs = self.request.data.get("file-parameters")

            projectId = int(projectId)
            scheduleId = int(scheduleId)
        except EmptyValue as e:
            raise HTTP_400("%s" % e)
        except Exception as e:
            raise HTTP_400("Invalid request provided (%s ?)" % e)

        # checking input
        if _testInputs is not None:
            if not isinstance(_testInputs, list):
                raise HTTP_400(
                    "Invalid parameters provided in request, list expected")
            for inp in _testInputs:
                if not isinstance(inp, dict):
                    raise HTTP_400(
                        "Invalid parameters provided in request, list of dict expected")
                if not ("name" in inp and "type" in inp and "value" in inp):
                    raise HTTP_400(
                        "Invalid parameters provided in request")

        # run a test not save; change the project id to the default
        if projectId == 0:
            projectId = ProjectsManager.instance().getDefaultProjectForUser(
                user=user_profile['login'])

        _check_project_permissions(
            user_login=user_profile['login'],
            project_id=projectId)

        try:
            if yamlFile.startswith("//"):
                yamlFile = yamlFile[1:]
            yamlFile = os.path.normpath(yamlFile)
            p  = pathlib.Path(yamlFile)
            
            fileExtension = p.suffix[1:]
            fileName = p.stem
            filePath = yamlFile.rsplit("%s%s" %(p.stem, p.suffix))[0]
        except Exception as e:
            raise HTTP_403('Invalid yaml file: %s' % e)
        
        if len(yamlContent):
            try:
                res = yaml.safe_load(yamlContent)
            except Exception as e:
                raise HTTP_403('Invalid yaml content: %s' % e)
        
        else:
            try:
                file_path = "%s/%s/%s/%s.%s" % (RepoTests.instance().testsPath,
                                                projectId,
                                                filePath,
                                                fileName,
                                                fileExtension)
                # read the file
                with open(file_path, "r") as f:
                    doc_yaml = f.read()
                    
                res = yaml.safe_load(doc_yaml)
            except Exception as e:
                raise HTTP_403('Invalid yaml file: %s' % e)   

        try:
            # just for backward compatibility
            if "testplan" in res:
                testextension = "tpx"
                testfile = res["testplan"]
            elif "testglobal" in res:
                testextension = "tgx"
                testfile = res["testglobal"]
            elif "testsuite" in res:
                testextension = "tsx"
            elif "testunit" in res:
                testextension = "tux"
            # end of backward compatibility
                
            elif "python" in res:
                testextension = "tsx"   
            elif "actions" in res:
                testextension = "tpx"
                testfile = res["actions"]                        
            else:
                raise Exception("invalid yaml format")
              
            # add default props if missing
            if "properties" not in res:
                res["properties"] = {}
                
            # add default descriptions if missing
            if "descriptions" not in res["properties"]:
                res["properties"]["descriptions"] = {}
                
            if "author" not in res["properties"]["descriptions"]:
                res["properties"]["descriptions"]["author"] = "undefined"
                
            if "name" not in res["properties"]["descriptions"]:
                res["properties"]["descriptions"]["name"] = "undefined"
                
            if "requirement" not in res["properties"]["descriptions"]:
                res["properties"]["descriptions"]["requirement"] = "undefined"
                
            if "summary" not in res["properties"]["descriptions"]:
                res["properties"]["descriptions"]["summary"] = "undefined"
            
            # add parameters if missing
            if "parameters" not in res["properties"]:
                res["properties"]["parameters"] = []
                
            # add default scope in main parameters
            for p in res["properties"]["parameters"]:
                if "scope" not in p:
                    p["scope"] = "local"
                if "value" not in p:
                    p["value"] = ""
                if "type" not in p:
                    if p["value"] is None:
                        p["type"] = "none"
                        p["value"] = ""
                    elif isinstance(p["value"], bool):
                        p["type"] = "bool"
                        p["value"] = "%s" % p["value"]
                    elif isinstance(p["value"], int):
                        p["type"] = "int"
                        p["value"] = "%s" % p["value"]
                    elif isinstance(p["value"], list) or isinstance(p["value"], dict):
                        p["type"] = "json"
                        p["value"] = json.dumps(p["value"])
                    else:
                        p["type"] = "text"
                    
            testprops = {}
            testprops["inputs-parameters"] = {}
            testprops["inputs-parameters"]["parameter"] = res["properties"]["parameters"]
            testprops["descriptions"] = {}
            testprops["descriptions"]["description"] = []

            for k,v in res["properties"]["descriptions"].items():
                s = { 'key': k, 'value': v }
                testprops["descriptions"]["description"].append(s)

            if testextension in ["tpx", "tgx"]:
                doc = TestPlan.DataModel()
            
                testplan = {}
                testplan['testplan'] = { 'testfile': [] }
                i = 1
                for tp in testfile:
                    # add parameters if missing
                    if "parameters" not in tp:
                        tp["parameters"] = []
                    # add default scope in main parameters
                    for p in tp["parameters"]:
                        if "scope" not in p:
                            p["scope"] = "local"
                        if "value" not in p:
                            p["value"] = ""
                        if "type" not in p:
                            if p["value"] is None:
                                p["type"] = "none"
                                p["value"] = ""
                            elif isinstance(p["value"], bool):
                                p["type"] = "bool"
                                p["value"] = "%s" % p["value"]
                            elif isinstance(p["value"], int):
                                p["type"] = "int"
                                p["value"] = "%s" % p["value"]
                            elif isinstance(p["value"], list) or isinstance(p["value"], dict):
                                p["type"] = "json"
                                p["value"] = json.dumps(p["value"])
                            else:
                                p["type"] = "text"
                            
                    if "id" not in tp:
                        tp["id"] = "%s" % i
                    if isinstance(tp["id"], int):
                        tp["id"] = str(tp["id"])
                    if "parent" not in tp:
                        tp["parent"] = "0"
                    if isinstance(tp["parent"], int):
                        tp["parent"] = str(tp["parent"])
                    
                    if "parent-condition" not in tp:
                        tp["parent-condition"] = "0"
                    else:
                        if tp["parent-condition"] == "success":
                            tp["parent-condition"] = "0"
                        else:
                            tp["parent-condition"] = "1"
                        tp["parent-condition"] = str(tp["parent-condition"])
                        
                    if "description" in tp:
                        tp["alias"] = tp["description"]
                        
                    i+=1
                        
                    tf_descr = [ {"key": "author", "value": "undefined"},
                                 {"key": "summary", "value": "undefined"}, 
                                 {"key": "name", "value": "undefined"},
                                 {"key": "requirement", "value": "undefined"}]
                    tf_prop = {"properties": {"descriptions": { "description": tf_descr},
                                              "inputs-parameters": {} }}
                    tf_prop["properties"]["inputs-parameters"]["parameter"] = tp["parameters"]
                    tp.update(tf_prop)
                    testplan['testplan']['testfile'].append(tp)
                
                doc.testplan = testplan
                tests = doc.getSorted()
                
                if testextension == "tpx":
                    success, error_msg = RepoTests.instance().addtf2tp(data_=tests)
                    if success != Context.instance().CODE_OK:
                        raise HTTP_500(
                            'Unable to prepare test plan: %s' %
                            error_msg)
                else:
                    success, error_msg, tests = RepoTests.instance().addtf2tg(data_=tests)
                    if success != Context.instance().CODE_OK:
                        raise HTTP_500(
                            'Unable to prepare test global: %s' %
                            error_msg)    
                            
                            
            testData = {'test-properties': testprops,
                        'test-extension': testextension}
            if testextension == "tsx":
                if "python" in res:
                    testData['test-definition'] = res["python"]
                else:
                    testData['test-definition'] = res["testsuite"]
                testData['test-execution'] = ""
            elif testextension == "tux":
                testData['test-definition'] = res["testunit"]
            else:
                testData['test-execution'] = tests
        except Exception as e:
            raise HTTP_500('Unable to decode yaml: %s' % e)
                

        # now we can create the task
        
        debugEnabled = False
        fromTime = (0, 0, 0, 0, 0, 0)
        toTime = (0, 0, 0, 0, 0, 0)
        message = "success"
        scheduleAt = (0, 0, 0, 0, 0, 0)

        if _debugEnabled is not None:
            debugEnabled = _debugEnabled
        if _fromTime is not None:
            fromTime = _fromTime
        if _toTime is not None:
            toTime = _toTime
        if _scheduleAt is not None:
            scheduleAt = _scheduleAt

        # personalize test description ?
        if _testInputs is not None:
            for newInp in _testInputs:
                if "scope" not in newInp:
                    newInp["scope"] = "local"
                for origInp in testData["test-properties"]['inputs-parameters']['parameter']:
                    if "scope" not in origInp:
                        origInp["scope"] = "local"

                    # if the param exist on the original test than overwrite
                    # them
                    if newInp["name"] == origInp["name"]:
                        origInp["value"] = newInp["value"]
                        origInp["type"] = newInp["type"]
                        origInp["scope"] = newInp["scope"]

        if not filePath.endswith(fileName):
            if len(filePath):
                _testPath = "%s/%s" % (filePath, fileName)
            else:
                _testPath = fileName
            _testPath = os.path.normpath(_testPath)
        else:
            _testPath = filePath

        task = TaskManager.instance().registerTask(
            testData=testData,
            testName=fileName,
            testPath=_testPath,
            testUserId=user_profile['id'],
            testUser=user_profile['login'],
            testId=0,
            testBackground=True,
            runAt=scheduleAt,
            runType=scheduleId,
            runNb=_scheduleRepeat,
            withoutProbes=False,
            debugActivated=debugEnabled,
            withoutNotif=False,
            noKeepTr=False,
            testProjectId=projectId,
            runFrom=fromTime,
            runTo=toTime,
            stepByStep=False,
            breakpoint=False,
            channelId=False
        )

        if task.lastError is not None:
            raise HTTP_500('ERROR: %s' % task.lastError)

        message = "success"
        if task.isRecursive():
            message = "recursive"
        if task.isPostponed():
            message = "postponed"
        if task.isSuccessive():
            message = "successive"
        return {"cmd": self.request.path,
                "message": message,
                "job-id": task.getId(),
                "execution-id": task.getTestID()}
Exemplo n.º 17
0
    def _final_stage(self, code):
        client_id = config.get('vk', 'client_id')
        client_secret = config.get('vk', 'client_secret')
        vksession = Session()
        try:
            resp = vksession.get(
                'https://oauth.vk.com/access_token?'
                'redirect_uri=https://api.vk.com/blank.html'
                f'&client_id={client_id}&client_secret={client_secret}&code={code}'
            )
            resp.raise_for_status()

            auth = resp.json()
            if not auth.get('access_token'):
                raise VKException(auth)

            resp = vksession.get('https://api.vk.com/method/users.get',
                                 params={
                                     'v': '5.92',
                                     'user_ids': auth['user_id'],
                                     'fields': 'photo_100',
                                     'access_token': auth['access_token']
                                 })
            resp.raise_for_status()
            user = resp.json()
            if user.get('error'):
                raise VKException(user)

            user = user.get('response', {})
            user = {
                'id': user[0]['id'],
                'fullname':\
                    (user[0].get('first_name', '') + ' ' + user[0].get('last_name', '')).strip(),
                'photo': user[0].get('photo_100'),
                'access_token': auth['access_token']
            } if user else {}

            rpc_call('set_vk_user', user)

            token = jwt_auth.create_token({
                'id': auth['user_id'],
                'aud': 'authorized'
            })

            self.logger.info('Issued JWT: %s', token)

            return {
                'token':
                'Bearer ' + token.decode("utf-8"),
                'tgauth':
                user.get('id') and rpc_call('is_tg_authorized', user['id'])
            }
        except exceptions.HTTPError as e:
            self.logger.info('Error authorizing user on VK: %s', e)
            if e.response.status_code == 401:
                raise HTTP_403('Error authorizing user on VK')
            raise HTTPError(e.response.status_code, e.response.text)
        except VKException as e:
            self.logger.warning('Error authorizing user on VK: %s', e)

            raise HTTP_403(e.message, e.code)
        except Exception as e:
            self.logger.exception('Error authorizing user on VK: %s', e)
        finally:
            vksession.close()

        raise HTTP_500('Internal error')