예제 #1
0
def login():
    
    if request.method == 'POST':
        username = request.form.get('username', '')
        password = request.form.get('password', '')
        user = PocketChangeUser(None, username, password)
        User = sqlalchemy_db.models['User']
        db_session = sqlalchemy_db.create_scoped_session()
        try:
            db_user = (db_session.query(User)
                       .filter(User.name==user.name).one())
        except:
            db_user = None
            user = PocketChangeUser(None, username, password)
        else:
            user = PocketChangeUser(db_user, password=password)
        if user.is_authenticated():
            User = sqlalchemy_db.models['User']
            if db_user:
                user.populate_name_from_database()
            else:
                db_user = User(name=user.name)
                db_user.password = password
                db_session.add(db_user)
                db_session.commit()
            user.token = db_user.get_new_token(current_app.secret_key[:16],
                                               expires=datetime.now() + login_lifetime)
            db_session.commit()
            session['username'] = user.name
            login_user(user)
            return 'logged in'
        else:
            return 'login failed'
    else:
        return render_template('login.html')
예제 #2
0
def complete_link():
    
        token = request.args.get('oauth_token', None)
        if not token or current_user.user.jira.oauth_token != token:
            return 'Linking failed'
        with open(current_app.config['JIRA_RSA_KEY_FILE'], 'r') as rsa_file:
            rsa_data = rsa_file.read()
        oauth_session = OAuth1Session(current_app.config['JIRA_APP_KEY'],
                                      signature_method=SIGNATURE_RSA,
                                      rsa_key=rsa_data,
                                      resource_owner_key=current_user.user.jira.oauth_token,
                                      resource_owner_secret=current_user.user.jira.oauth_secret)
        jira_host = current_app.config['JIRA_HOST'].rstrip('/')
        token_response = oauth_session.fetch_access_token(jira_host + '/plugins/servlet/oauth/access-token')
        db_session = sqlalchemy_db.create_scoped_session()
        db_user = db_session.merge(current_user.user)
        db_user.jira.oauth_token = token_response['oauth_token']
        db_user.jira.oauth_secret = token_response['oauth_token_secret']
        db_user.jira.expires = datetime.now() + timedelta(seconds=int(token_response['oauth_expires_in']))
        db_session.commit()
        g.jira._session.auth = OAuth1(current_app.config['JIRA_APP_KEY'],
                                      signature_method=SIGNATURE_RSA,
                                      rsa_key=rsa_data,
                                      resource_owner_key=db_user.jira.oauth_token,
                                      resource_owner_secret=db_user.jira.oauth_secret)
        g.jira.priorities()
        return redirect(url_for('core_ui.cycle_listing'))
def case_execution_details(case_execution_id):
    
    CaseExecution = sqlalchemy_db.models['CaseExecution']
    execution = (sqlalchemy_db.create_scoped_session().query(CaseExecution)
                 .filter(CaseExecution.id==case_execution_id)
                 .one())
    return render_template('case_execution_details.html',
                           case_execution=execution)
예제 #4
0
 def __init__(self, db_entity, name=None, password=None, populate_name_from_database=False):
     
     if db_entity:
         self.session = sqlalchemy_db.create_scoped_session()
         db_entity = self.session.merge(db_entity)
     try:
         self.token = db_entity.get_new_token(current_app.secret_key[:16],
                                              expires=login_timeout)
     except AttributeError:
         self.token = db_entity
     else:
         self.session.commit()
     self.last_refresh = datetime.now()
     if name is None and populate_name_from_database:
         self.populate_name_from_database()
     else:
         self.name = name
     self.password = password
예제 #5
0
def cycle_listing(filter=None, offset=1):
    
    TestCycle = sqlalchemy_db.models['TestCycle']
    query = sqlalchemy_db.create_scoped_session().query(TestCycle)
    if request.method == 'POST':
        filter = request.form.get('filter', None)
        offset = 1
    if filter:
        query = query.filter(or_(TestCycle.name.contains(filter),
                                 TestCycle.description.contains(filter)))
    query = query.order_by(TestCycle.id.desc())
    if offset == 1:
        query = query.limit(21)
        cycles = query.all()
        cycle_list = cycles[:20]
        has_next = (len(cycles) == 21)
    else:
        query = query.limit(22).offset(((offset - 1) * 20) - 1)
        cycles = query.all()
        cycle_list = cycles[1:22]
        has_next = (len(cycles) == 22)
    cycle_issues = {}
    use_jira = bool(current_app.config['KAICHU_ENABLED']
                    and current_user and current_user.is_authenticated()
                    and hasattr(current_user, 'user') and current_user.user
                    and hasattr(current_user.user, 'jira') and current_user.user.jira
                    and current_user.user.jira.active)
    if use_jira:
        for cycle in cycle_list:
            if cycle.jira_issue and cycle.jira_issue.issue_id:
                cycle_issues[cycle.id] = g.jira.issue(str(cycle.jira_issue.issue_id))
    return render_template('cycle_listing.html',
                           filter=filter,
                           offset=offset,
                           cycle_list=cycle_list,
                           has_next=has_next,
                           use_jira=use_jira,
                           jira_host=current_app.config.get('JIRA_HOST', ''),
                           cycle_issues=cycle_issues)
예제 #6
0
def start_linking():
    
    if (hasattr(current_user.user, 'jira') and current_user.user.jira
        and current_user.user.jira.active and current_user.user.jira.expires is not None):
        # TODO: Correct manually revoked jira oauth token
        return 'link already active'
    if request.method == 'POST':
        with open(current_app.config['JIRA_RSA_KEY_FILE'], 'r') as rsa_file:
            rsa_data = rsa_file.read()
        username = request.form.get('username', '')
        password = request.form.get('password', '')
        jira_host = current_app.config['JIRA_HOST'].rstrip('/')
        if g.jira.verify_credentials(username, password):
            oauth_session = OAuth1Session(current_app.config['JIRA_APP_KEY'],
                                          signature_method=SIGNATURE_RSA,
                                          rsa_key=rsa_data)
            token_response = oauth_session.fetch_request_token(jira_host + '/plugins/servlet/oauth/request-token')
            db_session = sqlalchemy_db.create_scoped_session()
            db_user = db_session.merge(current_user.user)
            if hasattr(db_user, 'jira') and db_user.jira and db_user.jira is not None:
                db_user.jira.name = username
                db_user.jira.oauth_token = token_response['oauth_token']
                db_user.jira.oauth_secret = token_response['oauth_token_secret']
                db_user.jira.expires=None
                db_user.jira.revoked=False
            else:
                db_user.jira = sqlalchemy_db.models['UserJiraData'](name=username,
                                                                    oauth_token=token_response['oauth_token'],
                                                                    oauth_secret=token_response['oauth_token_secret'],
                                                                    expires=None,
                                                                    revoked=False)
            db_session.commit()
            auth_url = oauth_session.authorization_url(jira_host + '/plugins/servlet/oauth/authorize')
            return redirect(auth_url + '&redirect_uri=' + current_app.config['APP_HOST'] + ':' + current_app.config['APP_PORT'] + url_for('kaichu_ui.complete_link'))
        else:
            return 'Bad username/password'
    else:
        return render_template('jira_linking.html', user=current_user)
예제 #7
0
def cycle_cases(test_cycle_id):

    CaseExecution = sqlalchemy_db.models["CaseExecution"]
    TestCycle = sqlalchemy_db.models["TestCycle"]
    db_session = sqlalchemy_db.create_scoped_session()
    test_cycle = db_session.query(TestCycle).filter(TestCycle.id == test_cycle_id).one()
    executions_by_case = defaultdict(list)
    cases = []
    case_ids = set()
    case_issues = defaultdict(lambda: {"issue_ids": set(), "issues": list()})
    cycle_issue = None
    # TODO: The hasattr jira_issue and jira_issue trueish tests are are flakey hack
    # to fix displaying PASS status for executions not linked in Jira.  Need to fix
    # this in a better way.  Right now, a case with an execution reported in to a
    # cycle will show a Jira status whether or not that case had any executions run
    # while linked to Jira as long as the cycle itself is linked to Jira.  Conversely,
    # an execution with a Jira issue being displayed as part of a cycle without an
    # issue will not show its issue.  This may not actually be a problem though.
    use_jira = bool(
        current_app.config["KAICHU_ENABLED"]
        and current_user
        and current_user.is_authenticated()
        and hasattr(current_user, "user")
        and current_user.user
        and hasattr(current_user.user, "jira")
        and current_user.user.jira
        and current_user.user.jira.active
        and hasattr(test_cycle, "jira_issue")
        and test_cycle.jira_issue
    )
    for case_execution in (
        db_session.query(CaseExecution)
        .filter(CaseExecution.test_cycles.contains(test_cycle))
        .order_by(CaseExecution.id)
    ):
        if "Out of case scope :" not in case_execution.case.label:
            if case_execution.case_id not in case_ids:
                case_ids.add(case_execution.case_id)
                cases.append(case_execution.case)
            executions_by_case[case_execution.case_id].append(case_execution)
            if use_jira:
                try:
                    issue_id = case_execution.jira_issue.issue_id
                except:
                    pass
                else:
                    if issue_id:
                        case_issues[case_execution.case_id]["issue_ids"].add(issue_id)
    if use_jira:
        if test_cycle.jira_issue and test_cycle.jira_issue.issue_id:
            cycle_issue = g.jira.issue(str(test_cycle.jira_issue.issue_id))
        for case_id in case_ids:
            statuses = set()
            resolutions = set()
            if case_issues[case_id]["issue_ids"]:
                for issue_id in case_issues[case_id]["issue_ids"]:
                    issue = g.jira.issue(str(issue_id))
                    statuses.add(issue.fields.status.name)
                    if issue.fields.status.name == "Closed":
                        resolutions.add(issue.fields.resolution.name)
                    case_issues[case_id]["issues"].append(issue)
                if len(statuses) > 1 or next(iter(statuses)) != "Closed":
                    case_issues[case_id]["rollup_result"] = "FAIL - UNDER REVIEW"
                else:
                    if len(resolutions) > 1:
                        case_issues[case_id]["rollup_result"] = "FAIL - REVIEWED"
                    else:
                        resolution = next(iter(resolutions))
                        if resolution == "Cannot Reproduce":
                            case_issues[case_id]["rollup_result"] = "PASS - %s" % resolution.upper()
                        else:
                            case_issues[case_id]["rollup_result"] = "FAIL - %s" % resolution.upper()
            else:
                execution_statuses = set(execution.result for execution in executions_by_case[case_id])
                if "PENDING" in execution_statuses:
                    case_issues[case_id]["rollup_result"] = "PENDING"
                else:
                    case_issues[case_id]["rollup_result"] = "PASS"

    return render_template(
        "cycle_case_rollup.html",
        cycle=test_cycle,
        cycle_issue=cycle_issue,
        cases=cases,
        executions_by_case=executions_by_case,
        use_jira=use_jira,
        jira_host=current_app.config.get("JIRA_HOST", ""),
        case_issues=case_issues,
    )
예제 #8
0
 def refresh(self, force=False):
     
     if force or datetime.now() > self.last_refresh + user_data_timeout:
         self.session = sqlalchemy_db.create_scoped_session()
         self.token = self.session.merge(self.token)
         self.last_refresh = datetime.now()