def process(self, db, user, service_name): if not user.hasRole(db, "administrator"): raise OperationFailure( code="notallowed", title="Not allowed!", message="Only a system administrator can restart services.") if service_name == "wsgi": for pid in os.listdir(configuration.paths.WSGI_PIDFILE_DIR): try: os.kill(int(pid), signal.SIGINT) except: pass return OperationResult() else: connection = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) connection.connect( configuration.services.SERVICEMANAGER["address"]) connection.send( textutils.json_encode({ "command": "restart", "service": service_name })) connection.shutdown(socket.SHUT_WR) data = "" while True: received = connection.recv(4096) if not received: break data += received result = textutils.json_decode(data) if result["status"] == "ok": return OperationResult() else: raise OperationError, result["error"]
def process(self, db, user, review_id, new_head_sha1, new_upstream_sha1): review = dbutils.Review.fromId(db, review_id) upstreams = log.commitset.CommitSet( review.branch.getCommits(db)).getFilteredTails(review.repository) if len(upstreams) > 1: return OperationResult(rebase_supported=False) old_head = review.branch.getHead(db) old_upstream = gitutils.Commit.fromSHA1(db, review.repository, upstreams.pop()) new_head = gitutils.Commit.fromSHA1(db, review.repository, new_head_sha1) new_upstream = gitutils.Commit.fromSHA1(db, review.repository, new_upstream_sha1) equivalent_merge = reviewing.rebase.createEquivalentMergeCommit( db, review, user, old_head, old_upstream, new_head, new_upstream) changesets = changeset_utils.createChangeset(db, user, review.repository, equivalent_merge, do_highlight=False) for changeset in changesets: if changeset.files: has_conflicts = True break else: has_conflicts = False return OperationResult(rebase_supported=True, has_conflicts=has_conflicts, merge_sha1=equivalent_merge.sha1)
def process(self, db, user, req): if not auth.deleteSessionId(db, req, user): raise OperationFailure(code="notsignedout", title="Not signed out", message="You were not signed out.") if not configuration.base.ALLOW_ANONYMOUS_USER: return OperationResult(target_url="/") return OperationResult()
def process(self, db, user, single=None, multiple=None, user_id=None): if user_id is None: user_id = user.id try: if single: repository = gitutils.Repository.fromName( db, single["repository_name"]) path = reviewing.filters.sanitizePath(single["path"]) cursor = db.cursor() cursor.execute( """SELECT path FROM filters WHERE repository=%s AND uid=%s""", ( repository.id, user_id, )) paths = set(filter_path for (filter_path, ) in cursor) paths.add(path) return OperationResult( count=reviewing.filters.countMatchedFiles( repository, list(paths))[path]) cursor = db.cursor() cursor.execute( """SELECT repository, id, path FROM filters WHERE id=ANY (%s) ORDER BY repository""", (multiple, )) per_repository = {} result = [] for repository_id, filter_id, filter_path in cursor: per_repository.setdefault(repository_id, []).append( (filter_id, filter_path)) for repository_id, filters in per_repository.items(): repository = gitutils.Repository.fromId(db, repository_id) counts = reviewing.filters.countMatchedFiles( repository, [filter_path for (filter_id, filter_path) in filters]) for filter_id, filter_path in filters: result.append({ "id": filter_id, "count": counts[filter_path] }) return OperationResult(filters=result) except reviewing.filters.PatternError as error: return OperationFailure(code="invalidpattern", title="Invalid pattern!", message=str(error))
def process(self, db, user, review_id, serial): cursor = db.readonly_cursor() cursor.execute("SELECT serial FROM reviews WHERE id=%s", (review_id, )) current_serial, = cursor.fetchone() if serial == current_serial: interval = user.getPreference(db, "review.updateCheckInterval") return OperationResult(stale=False, interval=interval) return OperationResult(stale=True)
def process(self, db, user, repository_id, changeset_id, files): repository = gitutils.Repository.fromId(db, repository_id) cursor = db.cursor() cursor.execute("SELECT parent, child FROM changesets WHERE id=%s", (changeset_id, )) parent_id, child_id = cursor.fetchone() parent = gitutils.Commit.fromId(db, repository, parent_id) child = gitutils.Commit.fromId(db, repository, child_id) try: annotator = LineAnnotator(db, parent, child) for file in files: for block in file["blocks"]: lines = annotator.annotate(file["id"], block["first"], block["last"]) block["lines"] = [{ "offset": offset, "commit": commit } for offset, commit in lines] return OperationResult(commits=[{ "sha1": commit.sha1, "author_name": commit.author.name, "author_email": commit.author.email, "summary": commit.niceSummary(), "message": commit.message, "original": commit == parent, "current": commit == child } for commit in annotator.commits], files=files) except LineAnnotator.NotSupported: blame = gitutils.Blame(parent, child) paths = {} commits = {} for file in files: file_id = file["id"] path = paths.get(file_id) if not path: path = paths[file_id] = dbutils.describe_file(db, file_id) for block in file["blocks"]: block["lines"] = blame.blame(db, path, block["first"], block["last"]) return OperationResult(commits=blame.commits, files=files)
def process(self, db, user, req, fields): if not user.isAnonymous(): return OperationResult() try: auth.DATABASE.authenticate(db, fields) except auth.AuthenticationFailed as error: return OperationResult(message=error.message) except auth.WrongPassword: return OperationResult(message="Wrong password!") auth.createSessionId(db, req, db.user, db.authentication_labels) return OperationResult()
def process(self, db, user, prefix, repository_id=None, repository_name=None): if reviewing.filters.hasWildcard(prefix): return OperationResult(paths={}) prefix = reviewing.filters.sanitizePath(prefix) if repository_id is not None: repository = gitutils.Repository.fromId(db, repository_id) else: repository = gitutils.Repository.fromName(db, repository_name) if repository.isEmpty(): return OperationResult(paths={}) paths = {} use_prefix = prefix.rpartition("/")[0] if use_prefix: names = repository.run("ls-tree", "-r", "--name-only", "HEAD", use_prefix).splitlines() else: names = repository.run("ls-tree", "-r", "--name-only", "HEAD").splitlines() def add(path): if path.endswith("/"): if path not in paths: paths[path] = { "files": 0 } paths[path]["files"] += 1 else: paths[path] = {} for name in names: if not name.startswith(prefix): continue relname = name[len(prefix):] use_prefix = prefix if prefix.endswith("/"): add(prefix) elif relname.startswith("/"): add(prefix + "/") use_prefix = prefix + "/" relname = relname[1:] localname, pathsep, _ = relname.partition("/") add(use_prefix + localname + pathsep) return OperationResult(paths=paths)
def process(self, db, user, subject, value): if user != subject: Operation.requireRole(db, "administrator", user) for address in value: if not address.strip(): raise OperationError("empty email address is not allowed") if address.count("@") != 1: raise OperationError("invalid email address") cursor = db.cursor() cursor.execute("SELECT email FROM usergitemails WHERE uid=%s", (subject.id, )) current_addresses = set(address for (address, ) in cursor) new_addresses = set(address.strip() for address in value) for address in (current_addresses - new_addresses): cursor.execute( "DELETE FROM usergitemails WHERE uid=%s AND email=%s", (subject.id, address)) for address in (new_addresses - current_addresses): cursor.execute( "INSERT INTO usergitemails (uid, email) VALUES (%s, %s)", (subject.id, address)) db.commit() return OperationResult()
def process(self, db, user, email_id): cursor = db.cursor() cursor.execute( """SELECT uid FROM useremails WHERE id=%s""", (email_id, )) row = cursor.fetchone() if not row: raise OperationFailure( code="invalidemailid", title="No such email address", message="The address might have been deleted already.") user_id, = row if user != user_id: Operation.requireRole(db, "administrator", user) cursor.execute( """UPDATE users SET email=%s WHERE id=%s""", (email_id, user_id)) db.commit() return OperationResult()
def process(self, db, user, email_id): cursor = db.cursor() cursor.execute( """SELECT uid, email, verified FROM useremails WHERE id=%s""", (email_id, )) row = cursor.fetchone() if not row: raise OperationFailure( code="invalidemailid", title="No such email address", message="The address might have been deleted already.") user_id, email, verified = row if verified is True: raise OperationFailure( code="alreadyverified", title="Address already verified", message="This address has already been verified.") if user != user_id: Operation.requireRole(db, "administrator", user) user = dbutils.User.fromId(db, user_id) sendVerificationMail(db, user, email_id) db.commit() return OperationResult()
def process(self, db, user, filter_id): cursor = db.cursor() cursor.execute("DELETE FROM reviewfilters WHERE id=%s", (filter_id, )) db.commit() return OperationResult()
def process(self, db, user, comment_id): comment = Comment.fromId(db, comment_id, user) if user != comment.user: raise OperationError, "can't delete comment written by another user" if comment.state != "draft": raise OperationError, "can't delete comment that has been submitted" cursor = db.cursor() cursor.execute( """UPDATE comments SET state='deleted' WHERE id=%s""", (comment.id, )) if comment.chain.state == "draft": # If the comment chain was a draft, then delete it as well. cursor.execute( """UPDATE commentchains SET state='empty' WHERE id=%s""", (comment.chain.id, )) db.commit() return OperationResult( draft_status=comment.chain.review.getDraftStatus(db, user))
def process(self, db, user, review_id, note): review = dbutils.Review.fromId(db, review_id) cursor = db.cursor() cursor.execute( """SELECT DISTINCT uid FROM reviewuserfiles JOIN reviewfiles ON (reviewfiles.id=reviewuserfiles.file) JOIN users ON (users.id=reviewuserfiles.uid) WHERE reviewfiles.review=%s AND reviewfiles.state='pending' AND users.status!='retired'""", (review.id, )) user_ids = set([user_id for (user_id, ) in cursor.fetchall()]) # Add the pinging user and the owners (they are usually the same.) user_ids.add(user.id) for owner in review.owners: user_ids.add(owner.id) recipients = [dbutils.User.fromId(db, user_id) for user_id in user_ids] pending_mails = [] for recipient in recipients: pending_mails.extend( review_mail.sendPing(db, user, recipient, recipients, review, note)) mailutils.sendPendingMails(pending_mails) return OperationResult()
def process(self, db, user, subject, filter_id): if user != subject: Operation.requireRole(db, "administrator", user) cursor = db.cursor() cursor.execute( """SELECT 1 FROM extensionhookfilters WHERE id=%s AND uid=%s""", (filter_id, subject.id)) if not cursor.fetchone(): raise OperationFailure( code="invalidoperation", title="Invalid operation", message= "Filter to delete does not exist or belongs to another user!") cursor.execute( """DELETE FROM extensionhookfilters WHERE id=%s""", (filter_id, )) db.commit() return OperationResult()
def apply(self, line, state): result = OperationResult(line, False) if not state.args.anticrap: return result #trimmed = stripComments(line) output = line self.strings = scanForStrings(line) slashmatch = regex['backslash'].finditer(line) dotmatch = regex['typedot'].finditer(line) for m in slashmatch: if checkIfInsideString(m.start('backslash'), self.strings): continue substitution = "." output = output[:m.start('backslash')] + substitution + output[ m.end('backslash'):] for m in dotmatch: if checkIfInsideString(m.start('dot'), self.strings): continue substitution = "\\" output = output[:m.start('dot' )] + substitution + output[m.end('dot'):] result.line = output return result
def process(self, db, user, chain_ids=None, review_ids=None): cursor = db.cursor() if chain_ids: cursor.execute( """DELETE FROM commentstoread USING comments WHERE commentstoread.uid=%s AND commentstoread.comment=comments.id AND comments.chain=ANY (%s)""", (user.id, chain_ids)) if review_ids: cursor.execute( """DELETE FROM commentstoread USING comments, commentchains WHERE commentstoread.uid=%s AND commentstoread.comment=comments.id AND comments.chain=commentchains.id AND commentchains.review=ANY (%s)""", (user.id, review_ids)) db.commit() return OperationResult()
def process(req, db, user, repository_id, commit_ids, reviewfilters, applyfilters, applyparentfilters): reviewfilters = parseReviewFilters(db, reviewfilters) repository = gitutils.Repository.fromId(db, repository_id) commits = [ gitutils.Commit.fromId(db, repository, commit_id) for commit_id in commit_ids ] all_reviewers, all_watchers = getReviewersAndWatchers( db, repository, commits, reviewfilters=reviewfilters, applyfilters=applyfilters, applyparentfilters=applyparentfilters) document = htmlutils.Document(req) generateReviewersAndWatchersTable( db, repository, document, all_reviewers, all_watchers, applyfilters=applyfilters, applyparentfilters=applyparentfilters) return OperationResult(html=document.render(plain=True))
def process(self, db, user, item_id, text): Operation.requireRole(db, "newswriter", user) db.cursor().execute("UPDATE newsitems SET text=%s WHERE id=%s", (text, item_id)) db.commit() return OperationResult()
def process(self, db, user, review_id): review = dbutils.Review.fromId(db, review_id) tails = review.getFilteredTails() if len(tails) > 1: raise OperationError("Multiple tail commits.") try: from customization.filtertags import getUpstreamPattern except ImportError: def getUpstreamTagPattern(review): pass tail = tails.pop() tags = review.branch.repository.run("tag", "-l", "--contains", tail, getUpstreamTagPattern(review) or "*").splitlines() cursor = db.cursor() upstreams = [] for tag in tags: cursor.execute("SELECT sha1 FROM tags WHERE repository=%s AND name=%s", (review.branch.repository.id, tag)) row = cursor.fetchone() if row and row[0] != tail: upstreams.append(tag) return OperationResult(upstreams=upstreams)
def process(self, db, user, new_pw, subject=None, current_pw=None): if subject is None: subject = user cursor = db.cursor() if not auth.DATABASE.supportsPasswordChange(): raise OperationFailure( code="notsupported", title="Not supported!", message="Changing password is not supported via this system.") if not new_pw: raise OperationFailure( code="emptypassword", title="Empty password!", message="Setting an empty password is not allowed.") if user != subject: Operation.requireRole(db, "administrator", user) if current_pw is None: # Signal that it doesn't need to be checked. current_pw = True try: auth.DATABASE.changePassword(db, subject, current_pw, new_pw) except auth.WrongPassword: raise OperationFailure( code="wrongpassword", title="Wrong password!", message="The provided current password is not correct.") return OperationResult()
def process(self, db, user, user_id, new_pw, current_pw=None): import auth if (user.id != user_id or current_pw is None) and not user.hasRole(db, "administrator"): raise OperationFailure(code="notallowed", title="Not allowed!", message="Operation not permitted.") subject = dbutils.User.fromId(db, user_id) if current_pw is not None: try: auth.checkPassword(db, subject.name, current_pw) except auth.WrongPassword: raise OperationFailure(code="wrongpassword", title="Wrong password!", message="The provided current password is not correct.") if not new_pw: raise OperationFailure(code="emptypassword", title="Empty password!", message="Setting an empty password is not allowed.") cursor = db.cursor() cursor.execute("UPDATE users SET password=%s WHERE id=%s", (auth.hashPassword(new_pw), user_id)) db.commit() return OperationResult()
def process(self, db, user, extension_name, author_name=None, version=None, universal=False): if universal: if not user.hasRole(db, "administrator"): raise OperationFailure(code="notallowed", title="Not allowed!", message="Operation not permitted.") user = None if version is not None: if version == "live": version = None elif version.startswith("version/"): version = version[8:] else: raise OperationError( "invalid version, got '%s', expected 'live' or 'version/*'" % version) try: self.perform(db, user, author_name, extension_name, version) except InstallationError as error: raise OperationFailure(code="installationerror", title=error.title, message=error.message, is_html=error.is_html) return OperationResult()
def process(self, db, user, review, chain_type, text, commit_context=None, file_context=None): checkComment(text) if commit_context: chain_id = createCommentChain(db, user, review, chain_type, **commit_context) elif file_context: chain_id = createCommentChain(db, user, review, chain_type, **file_context) else: chain_id = createCommentChain(db, user, review, chain_type) comment_id = createComment(db, user, chain_id, text, first=True) db.commit() return OperationResult(chain_id=chain_id, comment_id=comment_id, draft_status=review.getDraftStatus(db, user))
def process(self, db, user, review_id, new_summary=None, new_description=None, new_owners=None): review = dbutils.Review.fromId(db, review_id) if new_summary is not None: if not new_summary: raise OperationError("invalid new summary") review.setSummary(db, new_summary) if new_description is not None: review.setDescription(db, new_description if new_description else None) if new_owners is not None: remove_owners = set(review.owners) for user_name in new_owners: owner = dbutils.User.fromName(db, user_name) if owner in remove_owners: remove_owners.remove(owner) else: review.addOwner(db, owner) for owner in remove_owners: review.removeOwner(db, owner) db.commit() return OperationResult()
def apply(self, line, state): result = OperationResult(line, False) if not state.args.cull: return result trimmedLine = line.strip() words = trimmedLine.split() if (len(words) > 0): if (words[0].upper() == "REMSTART" or words[0].upper() == "REMEND"): self.inMultilineComment = not self.inMultilineComment result.discard = True return result if self.inMultilineComment: result.discard = True return result result.line = stripComments(line) stripped = result.line.strip() if stripped == "" or stripped == "\n" or stripped == "\r\n": result.discard = True if state.lastline: result.line = result.line.rstrip("\r\n") return result
def process(self, db, user, branch_id): cursor = db.cursor() if not user.hasRole(db, "administrator"): cursor.execute( """SELECT 1 FROM trackedbranchusers WHERE branch=%s AND uid=%s""", (branch_id, user.id)) if not cursor.fetchone(): raise OperationFailure(code="notallowed", title="Not allowed!", message="Operation not permitted.") cursor.execute( """UPDATE trackedbranches SET disabled=FALSE, next=NULL WHERE id=%s""", (branch_id, )) db.commit() pid = int( open(configuration.services.BRANCHTRACKER["pidfile_path"]).read(). strip()) os.kill(pid, signal.SIGHUP) return OperationResult()
def apply(self, line, state): result = OperationResult(line, False) if not state.args.dumb_debug: return result trimmed = stripComments(line) addition = ": " if isEmptyLine(trimmed): addition = "" if trimmed is not line: # there's a comment on this line #print("left: " + line[len(trimmed)-1:]) if isEmptyLine(trimmed): trimmed = line[:len(trimmed) - 1] + self.macrostring + addition + line[ len(trimmed) - 1:] else: trimmed = self.macrostring + addition + line else: trimmed = self.macrostring + addition + line result.line = trimmed return result
def process(self, db, user, review_id, sha1, branch): review = dbutils.Review.fromId(db, review_id) commit = gitutils.Commit.fromSHA1(db, review.repository, sha1) cursor = db.cursor() if review.state == 'closed': cursor.execute("SELECT closed_by FROM reviews WHERE id=%s", (review.id,)) closed_by = cursor.fetchone()[0] review.serial += 1 cursor.execute("UPDATE reviews SET state='open', serial=%s, closed_by=NULL WHERE id=%s", (review.serial, review.id)) else: closed_by = None doPrepareRebase(db, user, review, "0" * 40, branch) try: review.repository.run("update-ref", "refs/commit/%s" % commit.sha1, commit.sha1) review.repository.runRelay("fetch", "origin", "refs/commit/%s:refs/commit/%s" % (commit.sha1, commit.sha1)) review.repository.runRelay("push", "-f", "origin", "%s:refs/heads/%s" % (commit.sha1, review.branch.name)) if closed_by is not None: db.commit() state = review.getReviewState(db) if state.accepted: review.serial += 1 cursor.execute("UPDATE reviews SET state='closed', serial=%s, closed_by=%s WHERE id=%s", (review.serial, closed_by, review.id)) except: doCancelRebase(db, user, review) raise return OperationResult()
def process(self, db, user, user_id, value): if user.id != user_id and not user.hasRole(db, "administrator"): raise OperationFailure(code="notallowed", title="Not allowed!", message="Operation not permitted.") for address in value: if not address.strip(): raise OperationError("empty email address is not allowed") if address.count("@") != 1: raise OperationError("invalid email address") cursor = db.cursor() cursor.execute("SELECT email FROM usergitemails WHERE uid=%s", (user_id,)) current_addresses = set(address for (address,) in cursor) new_addresses = set(address.strip() for address in value) for address in (current_addresses - new_addresses): cursor.execute("DELETE FROM usergitemails WHERE uid=%s AND email=%s", (user_id, address)) for address in (new_addresses - current_addresses): cursor.execute("INSERT INTO usergitemails (uid, email) VALUES (%s, %s)", (user_id, address)) db.commit() return OperationResult()