Esempio n. 1
0
class ConfigFileTableToolbar(renderers.TemplateRenderer):
  """A navigation enhancing toolbar.

  Internal State:
    - aff4_path: The path we are viewing now in the table.
  """
  post_parameters = ["aff4_path"]
  event_queue = "file_select"

  layout_template = renderers.Template("""
<ul id="toolbar_{{unique|escape}}" class="breadcrumb">
  <li>
    <button id='{{unique|escape}}_upload' class="btn btn-default"
      title='Upload Binary' data-toggle="modal"
      data-target="#upload_dialog_{{unique|escape}}">
      <img src='/static/images/upload.png' class='toolbar_icon'>
    </button>

    <button id='{{unique|escape}}_download' title='Download Binary'
      class="btn btn-default">
      <img src='/static/images/download.png' class='toolbar_icon'>
    </button>
  </li>
</ul>

<div id="upload_dialog_{{unique|escape}}" class="modal" tabindex="-1"
  role="dialog" aria-hidden="true">
  <div class="modal-dialog">
    <div class="modal-content">
      <div class="modal-header">
        <button type="button" class="close" data-dismiss="modal"
          aria-hidden="true">
          x
        </button>
        <h3>Upload File</h3>
      </div>
      <div class="modal-body" id="upload_dialog_body_{{unique|escape}}"></div>
      <div class="modal-footer">
        <button class="btn btn-default" data-dismiss="modal" aria-hidden="true">
          Close
        </button>
      </div>
    </div>
  </div>
</div>
""")

  def Layout(self, request, response):
    response = super(ConfigFileTableToolbar, self).Layout(request, response)
    return self.CallJavascript(response, "ConfigFileTableToolbar.Layout")
Esempio n. 2
0
class RWeOwned(renderers.TemplateRenderer):
  """A magic 8 ball reply to the question - Are we Owned?"""

  layout_template = renderers.Template("""
<div class="modal-dialog">
  <div class="modal-content">
    <div class="modal-header">
    <button type="button" class="close" data-dismiss="modal" aria-hidden="true">
       x
    </button>
    <h3>Are we owned?</h3>
    </div>
      <div class="modal-body">
        <p class="text-info">
    {{this.choice|escape}}
    </div>
  </div>
</div>
""")

  def Layout(self, request, response):
    """Render a magic 8 ball easter-egg."""
    options = u"""It is certain
You were eaten by a Grue!
中国 got you!!
All your bases are belong to us!
Maybe it was the Russians?
It is decidedly so
Without a doubt
Yes - definitely
You may rely on it
As I see it, yes
Most likely
Outlook good
Signs point to yes
Yes
Reply hazy, try again
Ask again later
Better not tell you now
Cannot predict now
Concentrate and ask again
Don't count on it
My reply is no
My sources say no
Outlook not so good
Very doubtful""".splitlines()

    self.choice = options[random.randint(0, len(options) - 1)]

    return super(RWeOwned, self).Layout(request, response)
Esempio n. 3
0
class DeleteArtifactsConfirmationDialog(renderers.ConfirmationDialogRenderer):
    """Dialog that asks for confirmation to delete uploaded artifacts.

  Note that this only deletes artifacts that have been uploaded via the
  ArtifactManager.  Artifacts loaded from the artifacts directory are
  unaffected.
  """

    content_template = renderers.Template("""
<p>Are you sure you want to <strong>delete all</strong>
uploaded artifacts?</p>
""")

    ajax_template = renderers.Template("""
<p class="text-info">Uploaded artifacts were deleted successfully.</p>
""")

    def RenderAjax(self, request, response):
        aff4.FACTORY.Delete("aff4:/artifact_store", token=request.token)
        return self.RenderFromTemplate(self.ajax_template,
                                       response,
                                       unique=self.unique,
                                       this=self)
Esempio n. 4
0
class EventMessageRenderer(semantic.RDFValueRenderer):
  """Render a special message to describe the event based on its type."""

  # If the type is unknown we just say what it is.
  default_template = renderers.Template("""
Event of type {{this.type|escape}}
""")

  event_template_dispatcher = {
      "file.mtime": renderers.Template(
          "<div><pre class='inline'>M--</pre> File modified.</div>"),
      "file.atime": renderers.Template(
          "<div><pre class='inline'>-A-</pre> File access.</div>"),
      "file.ctime": renderers.Template(
          "<div><pre class='inline'>--C</pre> File metadata changed.</div>"),
  }

  def Layout(self, request, response):
    self.type = self.proxy.type
    self.layout_template = self.event_template_dispatcher.get(
        self.type, self.default_template)

    return super(EventMessageRenderer, self).Layout(request, response)
Esempio n. 5
0
class GlobalNotificationBar(renderers.TemplateRenderer):
  """Renders global notification bar on top of the admin UI."""

  POLL_TIME = 5 * 60 * 1000

  layout_template = renderers.Template("""
{% for notification in this.notifications %}
<div class="alert alert-block alert-{{notification.type_name|lower|escape}}">
  <button type="button" notification-hash="{{notification.hash|escape}}"
    class="close">&times;</button>
  <h4>{{notification.header|escape}}</h4>
  <p>{{notification.content|escape}}</h4>
  {% if notification.link %}
    <p><a href="{{notification.link|escape}}" target="_blank">More...</a></p>
  {% endif %}
</div>
{% endfor %}
""")

  def Layout(self, request, response):
    try:
      user_record = aff4.FACTORY.Open(
          aff4.ROOT_URN.Add("users").Add(request.user), "GRRUser",
          token=request.token)

      self.notifications = user_record.GetPendingGlobalNotifications()
    except IOError:
      self.notifications = []

    return super(GlobalNotificationBar, self).Layout(request, response)

  def RenderAjax(self, request, response):
    # If notification_hash is part of request, remove notification with a
    # given hash, otherwise just render list of notifications as usual.
    if "notification_hash" in request.REQ:
      hash_to_remove = int(request.REQ["notification_hash"])

      user_record = aff4.FACTORY.Create(
          aff4.ROOT_URN.Add("users").Add(request.user), "GRRUser",
          mode="r", token=request.token)

      notifications = user_record.GetPendingGlobalNotifications()
      for notification in notifications:
        if notification.hash == hash_to_remove:
          flow.GRRFlow.StartFlow(flow_name="MarkGlobalNotificationAsShown",
                                 args=notification, token=request.token)
          break
    else:
      return self.Layout(request, response)
Esempio n. 6
0
class AuditTable(statistics.Report, renderers.TableRenderer):
    """Parent class for audit event tabular reports."""
    layout_template = renderers.Template("""
<div class="padded">
  <h3>{{this.title|escape}}</h3>
</div>
""") + renderers.TableRenderer.layout_template
    time_offset = rdfvalue.Duration("7d")
    column_map = {
        "Timestamp": "timestamp",
        "Action": "action",
        "User": "******",
        "Client": "client",
        "Flow Name": "flow_name",
        "URN": "urn",
        "Description": "description"
    }

    # To be set by subclass
    TYPES = []

    def __init__(self, **kwargs):
        super(AuditTable, self).__init__(**kwargs)
        for column_name in sorted(self.column_map):
            self.AddColumn(semantic.RDFValueColumn(column_name))

    def BuildTable(self, start_row, end_row, request):
        try:
            now = rdfvalue.RDFDatetime().Now()
            start = now - self.time_offset
            fd = aff4.FACTORY.Open("aff4:/audit/log",
                                   aff4_type="RDFValueCollection",
                                   token=request.token)

            rows = []
            for event in fd.GenerateItems(
                    timestamp=(start.AsMicroSecondsFromEpoch(),
                               now.AsMicroSecondsFromEpoch())):
                if event.action in self.TYPES:
                    row_dict = {}
                    for column_name, attribute in self.column_map.iteritems():
                        row_dict[column_name] = event.Get(attribute)
                    rows.append(row_dict)

            for row in sorted(rows, key=lambda x: x["Timestamp"]):
                self.AddRow(row)

        except IOError:
            pass
Esempio n. 7
0
class RequestRenderer(renderers.TemplateRenderer):
    """Display details of the request packet.

  Post Parameters:
    - task_id: The id of the request to display.
    - client_id: The client to show requests for.
  """

    layout_template = renderers.Template("""
{%if this.msg %}
<div id="{{unique|escape}}" class="{{this.css_class}}">
 <h3>Request {{this.msg.task_id|escape}}</h3>

<table id='{{ unique|escape }}' class="table table-condensed table-bordered">
<thead>
<tr>
  <th class="ui-state-default">Task</th>
</tr>
</thead>
<tbody>
 <tr>
   <td>
     <div class="default_view">{{ this.view|safe }}</div>
   </td>
 </tr>
</tbody>
</table>

</div>
{% endif %}
""")

    def Layout(self, request, response):
        """Layout."""
        if request.REQ.get("task_id") is None:
            return

        client_id = rdf_client.ClientURN(request.REQ.get("client_id"))
        task_id = "task:" + request.REQ.get("task_id")

        # Make a local QueueManager.
        manager = queue_manager.QueueManager(token=request.token)
        msgs = manager.Query(client_id, task_id=task_id)
        if msgs:
            self.msg = msgs[0]
            self.view = semantic.FindRendererForObject(
                self.msg).RawHTML(request)

        return super(RequestRenderer, self).Layout(request, response)
Esempio n. 8
0
class SectionHeader(renderers.TemplateRenderer):
    """Renders a section header."""

    layout_template = renderers.Template("""
<h3>{{this.header|escape}}</h3>
""")

    def __init__(self,
                 header=None,
                 name=None,
                 width=50,
                 keep_sort=False,
                 **kwargs):
        super(SectionHeader, self).__init__(**kwargs)
        self.header = header or name or ""
Esempio n. 9
0
class RunHuntConfirmationDialog(renderers.ConfirmationDialogRenderer):
  """Dialog that asks confirmation to run a hunt and actually runs it."""
  post_parameters = ["hunt_id"]

  inner_dialog_only = True
  header = "Run a hunt?"

  content_template = renderers.Template("""
<p>Are you sure you want to <strong>run</strong> this hunt?</p>
""")

  ajax_template = renderers.Template("""
<p class="text-info">Hunt started successfully!</p>
""")

  def Layout(self, request, response):
    self.check_access_subject = rdfvalue.RDFURN(request.REQ.get("hunt_id"))
    return super(RunHuntConfirmationDialog, self).Layout(request, response)

  def RenderAjax(self, request, response):
    flow.GRRFlow.StartFlow(flow_name="StartHuntFlow", token=request.token,
                           hunt_urn=rdfvalue.RDFURN(request.REQ.get("hunt_id")))
    return self.RenderFromTemplate(self.ajax_template, response,
                                   unique=self.unique)
Esempio n. 10
0
class SearchHostView(renderers.Renderer):
  """Show a search screen for the host."""

  title = "Search Client"

  context_help_url = "user_manual.html#searching-for-a-client"
  template = renderers.Template("""
<abbr title="Type label: to open a list of possible labels completions.">
  {% if this.context_help_url %}
    <a href="/help/{{this.context_help_url|escape}}" target="_blank"
      class="pull-right">
      <i class="glyphicon glyphicon-question-sign input-append"></i>
    </a>
  {% endif %}
  <form id="search_host" class="navbar-form pull-right no-right-padding">
    <div class="form-group">
      <div class="input-group">
        <input type="text" id="client_query" name="q"
          class="form-control search-query"
          placeholder="Search Box"/>
        <span class="input-group-btn">
          <button type="submit" id="client_query_submit"
            class="btn btn-default search-query">
            <span class="glyphicon glyphicon-search"></span>
          </button>
        </span>
      </div>
    </div>
  </form>
</abbr>
""")

  def Layout(self, request, response):
    """Display a search screen for the host."""
    response = super(SearchHostView, self).Layout(request, response)

    response = self.RenderFromTemplate(
        self.template, response, title=self.title,
        id=self.id)

    labels_index = aff4.FACTORY.Create(
        aff4.VFSGRRClient.labels_index_urn, "AFF4LabelsIndex",
        mode="rw", token=request.token)
    used_labels = sorted(list(
        set([label.name for label in labels_index.ListUsedLabels()])))

    return self.CallJavascript(response, "SearchHostView.Layout",
                               labels=used_labels)
Esempio n. 11
0
class GRREProcessObjectRenderer(GRRRekallViewerObjectRenderer):
    """Special rendering for _EPROCESS objects."""
    renders_type = "_EPROCESS"

    layout = renderers.Template("""

<div id="{{unique|escape}}" class="modal fade" role="dialog"
     aria-hidden="true">
  <div class="modal-dialog">
   <div class="modal-content">
    <div class="modal-header">
     <button type="button" class="close"
       aria-hidden="true" data-dismiss="modal">
      &times;
     </button>
     <h4 class="modal-title">Process {{this.Cybox.Name|escape}}</h4>
    </div>
      <div id="ClientInfoContent_{{unique|escape}}" class="modal-body">
        <table class="table table-hover">
         <tr><th>Key</th><th>Value</th></tr>
         {% for k, v in data %}
           <tr><td>{{k|escape}}</td><td>{{v|escape}}</td></tr>
         {% endfor %}
        </table>
      </div>
    </div>
  </div>
</div>

<a href=# data-toggle="modal" data-target="#{{unique|escape}}">
 {{this.Cybox.Name|escape}} ({{this.Cybox.PID|escape}})
</a>
""")

    def _Flatten(self, prefix, item):
        result = []
        for k, v in item.items():
            next_prefix = "%s.%s" % (prefix, k)

            if isinstance(v, dict):
                result.extend(self._Flatten(next_prefix, v))
            else:
                result.append((next_prefix, v))

        return result

    def RawHTML(self, item, **_):
        return self.layout.RawHTML(this=item, data=self._Flatten("", item))
Esempio n. 12
0
class NotificationBar(renderers.TemplateRenderer):
  """Render a notification bar for the user."""

  layout_template = renderers.Template("""
<div id="notification_dialog" class="modal wide-modal" tabindex="-1"
  role="dialog" aria-hidden="true">
  <div class="modal-dialog">
    <div class="modal-content">
      <div class="modal-header">
        <button type="button" class="close" data-dismiss="modal"
          aria-hidden="true">x</button>
        <h3>Notifications for {{this.user|escape}}</h3>
      </div>
      <div class="modal-body" id="notification_dialog_body">
      </div>
      <div class="modal-footer">
        <button class="btn btn-default" data-dismiss="modal" aria-hidden="true">
          Close
        </button>
      </div>
    </div>
  </div>
</div>

<div id="user_settings_dialog" class="modal" tabindex="-1"
  role="dialog" aria-hidden="true">
</div>

<ul class="nav pull-left">
  <li><p class="navbar-text">User: {{this.user|escape}}</p></li>
</ul>

<div id="notifications_and_settings" class="pull-right navbar-form">
  <button id="notification_button" class="btn btn-info"
         data-toggle="modal" data-target="#notification_dialog"
         style="margin-right: 10px" />
  <button id="user_settings_button" class="btn btn-default" data-toggle="modal"
    data-target="#user_settings_dialog">
     <img src="static/images/modify.png" style="height: 17px; margin-top: -2px">
  </button>
</div>
""")

  def Layout(self, request, response):
    """Show the number of notifications outstanding for the user."""
    self.user = request.user
    response = super(NotificationBar, self).Layout(request, response)
    return self.CallJavascript(response, "Layout")
Esempio n. 13
0
class TimelineMain(renderers.TemplateRenderer):
  """This is the main view to the timeline.

  Internal State (from hash value):
    - container: The container name for the timeline.
    - query: The query to filter.
  """

  layout_template = renderers.Template("""
<div id='toolbar_{{id|escape}}' class="navbar navbar-default"></div>
<div id='{{unique|escape}}' class="fill-parent no-margins toolbar-margin"></div>
""")

  def Layout(self, request, response):
    response = super(TimelineMain, self).Layout(request, response)
    return self.CallJavascript(response, "TimelineMain.Layout")
Esempio n. 14
0
class CollectionRenderer(StatEntryRenderer):
  """Nicely format a Collection."""
  classname = "CollectionList"
  name = "Collection Listing"

  layout_template = renderers.Template("""
<table class='proto_table'>
<thead>
<tr><th>Mode</th><th>Name</th><th>Size</th><th>Modified</th></tr>
</thead>
<tbody>
  {% for row in this.result %}
    <tr>
    {% for value in row %}
      <td class="proto_value">
        {{value|safe}}
      </td>
    {% endfor %}
    </tr>
  {% endfor %}
</tbody>
</table>
""")

  def Layout(self, request, response):
    """Render collections as a table."""
    self.result = []
    fields = "st_mode pathspec st_size st_mtime".split()
    items = self.proxy.items
    for item in items:
      row = []
      for name in fields:
        value = getattr(item, name)
        try:
          value = self.translator[name](self, request, value)

        # Regardless of what the error is, we need to escape the value.
        except StandardError:  # pylint: disable=broad-except
          value = self.FormatFromTemplate(self.translator_error_template,
                                          value=value)

        row.append(value)

      self.result.append(row)

    return renderers.TemplateRenderer.Layout(self, request, response)
Esempio n. 15
0
class ProtoBoolFormRenderer(TypeDescriptorFormRenderer):
  """Render a checkbox for boolean values."""
  type_descriptor = type_info.ProtoBoolean

  layout_template = renderers.Template("""
<div class="form-group">
<div class="controls">

<label class="checkbox">
  <input id='{{this.prefix}}' type=checkbox class="unset"
      {% if this.value %}checked {% endif %}
      onchange="grr.forms.checkboxOnChange(this)"
      value='{{ this.value|escape }}'/>

  <abbr title='{{this.descriptor.description|escape}}'>
    {{this.friendly_name}}
  </abbr>
</label>

</div>
</div>
""")

  def Layout(self, request, response):
    super(ProtoBoolFormRenderer, self).Layout(request, response)
    if self.default is not None:
      self.default = bool(self.default)
    if self.value is not None:
      self.value = bool(self.default)

    return self.CallJavascript(
        response,
        "Layout",
        default=self.default,
        value=self.value,
        prefix=self.prefix)

  def ParseArgs(self, request):
    value = request.REQ.get(self.prefix)
    if value is None:
      return

    if value.lower() in ["yes", "true"]:
      return True

    return False
Esempio n. 16
0
class ArtifactRDFValueRenderer(semantic.RDFValueRenderer):
  """A special renderer for ArtifactRDFValues."""

  classname = "Artifact"

  layout_template = renderers.Template(
      """
<div id={{unique|escape}}_artifact_description>"""
      + ArtifactListRenderer.artifact_template + """
</div>
""")

  def Layout(self, request, response):
    self.artifact_str = self.proxy.ToPrettyJson()
    response = super(ArtifactRDFValueRenderer, self).Layout(request, response)
    return self.CallJavascript(response, "ArtifactRDFValueRenderer.Layout",
                               artifact_str=self.artifact_str)
Esempio n. 17
0
class StringListRenderer(renderers.TemplateRenderer):
  """Renders a list of strings as a proto table."""
  layout_template = renderers.Template("""
<table class='proto_table'>
<tbody>
{% for string in this.strings %}
<tr><td>
{{string|escape}}
</td></tr>
{% endfor %}
</tbody>
</table>
""")

  def __init__(self, strings, **kwargs):
    self.strings = strings
    super(StringListRenderer, self).__init__(**kwargs)
Esempio n. 18
0
class CronReview(new_hunt.HuntInformation):
  """Shows generic hunt information plus its' cron scheduling settings."""

  ajax_template = renderers.Template("""
<h3>Hunt Periodicity</h3>
<div class="HuntPeriodicity">
  <p>Hunt will run <strong>{{this.cron_arg.periodicity|escape}}</strong>.</p>
</div>
""") + new_hunt.HuntInformation.ajax_template

  def RenderAjax(self, request, response):
    """Renders review page of a hunt cron scheduling wizard."""
    parser = CronHuntParser(request)

    self.cron_arg = parser.ParseCronParameters()

    return super(CronReview, self).RenderAjax(request, response)
Esempio n. 19
0
class IPStatusIcon(semantic.RDFValueRenderer):
  """Renders the ip status (internal, external) icon."""

  cls = "vertical_aligned"

  layout_template = renderers.Template("""
<img class="grr-icon-small {{this.cls|escape}}"
     src="/static/images/{{this.ip_icon|escape}}"/>""")

  icons = {utils.IPInfo.UNKNOWN: "ip_unknown.png",
           utils.IPInfo.INTERNAL: "ip_internal.png",
           utils.IPInfo.EXTERNAL: "ip_external.png",
           utils.IPInfo.VPN: "ip_unknown.png"}

  def Layout(self, request, response):
    self.ip_icon = self.icons.setdefault(int(self.proxy), "ip_unknown.png")
    return super(IPStatusIcon, self).Layout(request, response)
Esempio n. 20
0
class CronJobManagementTabs(renderers.TabLayout):
  """Tab renderer for cron job management."""
  names = ["Details", "Flows"]
  delegated_renderers = ["CronJobInformation", "CronJobView"]

  tab_hash = "cjt"

  empty_template = renderers.Template("""
<div class="padded">Please select a cron job to see the details.</div>
""")

  def Layout(self, request, response):
    if not request.REQ.get("cron_job_urn"):
      return self.RenderFromTemplate(self.empty_template, response)
    else:
      self.state = dict(cron_job_urn=request.REQ.get("cron_job_urn"))
      return super(CronJobManagementTabs, self).Layout(request, response)
Esempio n. 21
0
class AbstractLogRenderer(renderers.TemplateRenderer):
    """Render a page for view a Log file.

  Implements a very simple view. That will be extended with filtering
  capabilities.

  Implementations should implement the GetLog function.
  """
    show_total_count = False
    layout_template = renderers.Template("""
<table class="proto_table">
{% if this.log|length > 0 %}
  {% if this.show_total_count %}
    <h5>{{this.log|length}} Entries</h5>
  {% endif %}
{% endif %}
{% for line in this.log %}
  <tr>
  {% for val in line %}
    <td class="proto_key">{{ val|safe }}</td>
  {% endfor %}
  </tr>
{% empty %}
<tr><td>No entries</tr></td>
{% endfor %}
<table>
""")

    def GetLog(self, request):
        """Take a request and return a list of tuples for a log."""
        _ = request
        return []

    def Layout(self, request, response):
        """Fill in the form with the specific fields for the flow requested."""
        self.log = []
        for row in self.GetLog(request):
            rendered_row = []
            for item in row:
                item_renderer = semantic.FindRendererForObject(item)
                rendered_row.append(item_renderer.RawHTML(request))

            self.log.append(rendered_row)

        return super(AbstractLogRenderer, self).Layout(request, response)
Esempio n. 22
0
class FlowFormCancelAction(renderers.TemplateRenderer):
  """Handle submission of a Cancel Flow button press.

  Post Parameters:
    - flow_id: The flow to cancel.
  """
  layout_template = renderers.Template("")

  def Layout(self, request, response):
    # We can't terminate flow directly through flow.GRRFlow.TerminateFlow as
    # it requires writing to the datastore. We're not allowed to do it from
    # the GUI. Therefore we use dedicated TerminateFlow flow.
    flow.GRRFlow.StartFlow(
        flow_name="TerminateFlow",
        flow_urn=rdfvalue.RDFURN(request.REQ.get("flow_id")),
        reason="Cancelled in GUI", token=request.token)

    super(FlowFormCancelAction, self).Layout(request, response)
Esempio n. 23
0
class Report(renderers.TemplateRenderer):
    """This is the base of all Statistic Reports."""
    category = None

    layout_template = renderers.Template("""
<div class="padded">
{% if this.data %}
  <h3>{{this.title|escape}}</h3>
  <div>
  {{this.description|escape}}
  </div>
  <div id="hover_{{unique|escape}}">Hover to show exact numbers.</div>
  <div id="graph_{{unique|escape}}" class="grr_graph"></div>
{% else %}
  <h3>No data Available</h3>
{% endif %}
</div>
""")
Esempio n. 24
0
class ProgressButtonRenderer(RDFValueRenderer):
  """Renders a button that shows a progress graph."""

  # This specifies the name of the RDFValue object we will render.
  classname = "ProgressGraph"

  layout_template = renderers.Template("""
Open a graph showing the download progress in a new window:
<button id="{{ unique|escape }}">
 Generate
</button>
""")

  def Layout(self, request, response):
    self.flow_id = request.REQ.get("flow")
    response = super(ProgressButtonRenderer, self).Layout(request, response)
    return self.CallJavascript(response, "ProgressButtonRenderer.Layout",
                               flow_id=self.flow_id)
Esempio n. 25
0
class ShowFlowInformation(fileview.AFF4Stats):
    """Display information about the flow.

  Post Parameters:
    - flow: The flow id we will display.

  Internal State:
    - client_id, flow
  """

    selection_publish_queue = "flow_table_select"
    historical_renderer = "HistoricalFlowView"

    # Embed the regular AFF4Stats inside a container to allow scrolling
    layout_template = renderers.Template("""
<div id="container_{{unique|escapejs}}">
{% if this.path %}
""" + str(fileview.AFF4Stats.layout_template) + """
<br/>
{% else %}
Please select a flow to manage from the above table.
{% endif %}
</div>
""")

    def Layout(self, request, response):
        """Introspect the Schema for flow objects."""
        try:
            self.state["flow"] = session_id = request.REQ["flow"]
            self.fd = aff4.FACTORY.Open(session_id,
                                        token=request.token,
                                        age=aff4.ALL_TIMES)
            self.classes = self.RenderAFF4Attributes(self.fd, request)
            self.path = self.fd.urn
        except (KeyError, IOError):
            self.path = None

        # Skip our parent's Layout method and install parent's javascript code.
        response = super(fileview.AFF4Stats, self).Layout(request, response)
        return self.CallJavascript(
            response,
            "AFF4Stats.Layout",
            historical_renderer=self.historical_renderer,
            historical_renderer_state=self.state)
Esempio n. 26
0
class CollectionExportView(renderers.TemplateRenderer):
  """Displays export command to be used to export collection."""

  layout_template = renderers.Template("""
<p>To download all the files referenced in the collection, you can use
this command:</p>
<pre>
{{ this.export_command_str|escape }}
</pre>
<p><em>NOTE: You can optionally add <tt>--dump_client_info</tt> flag to
dump client info in YAML format.</em></p>
""")

  @staticmethod
  def IsCollectionExportable(collection_urn_or_obj,
                             token=None):
    if isinstance(collection_urn_or_obj, aff4.RDFValueCollection):
      collection = collection_urn_or_obj
    else:
      collection = aff4.FACTORY.Create(
          collection_urn_or_obj, "RDFValueCollection", mode="r", token=token)

    if not collection:
      return False

    try:
      export.CollectionItemToAff4Path(collection[0])
    except export.ItemNotExportableError:
      return False

    return True

  def Layout(self, request, response, aff4_path=None):
    aff4_path = aff4_path or request.REQ.get("aff4_path")

    self.export_command_str = " ".join([
        config_lib.CONFIG["AdminUI.export_command"],
        "--username", utils.ShellQuote(request.token.username),
        "--reason", utils.ShellQuote(request.token.reason),
        "collection_files",
        "--path", utils.ShellQuote(aff4_path),
        "--output", "."])

    return super(CollectionExportView, self).Layout(request, response)
Esempio n. 27
0
class ArtifactManagerToolbar(renderers.TemplateRenderer):
  """A navigation enhancing toolbar.

  Internal State:
    - aff4_path: The path we are viewing now in the table.
  """
  post_parameters = ["aff4_path"]
  event_queue = "file_select"

  layout_template = renderers.Template("""
<ul id="toolbar_{{unique|escape}}" class="breadcrumb">
  <li>
    <button id='{{unique|escape}}_upload' class="btn"
      title="Upload Artifacts as JSON or YAML"
      data-toggle="modal" data-target="#upload_dialog_{{unique|escape}}">
      <img src='/static/images/upload.png' class='toolbar_icon'>
    </button>
  </li>
</ul>

<div id="upload_dialog_{{unique|escape}}" class="modal hide" tabindex="-1"
  role="dialog" aria-hidden="true">
  <div class="modal-header">
    <button id="upload_artifact_btn_{{unique|escape}}" type="button"
    class="close" data-dismiss="modal" aria-hidden="true">
      x</button>
    <h3>Upload File</h3>
  </div>
  <div class="modal-body" id="upload_dialog_body_{{unique|escape}}"></div>
  <div class="modal-footer">
    <button id="upload_artifact_close_btn_{{unique|escape}}" class="btn"
    data-dismiss="modal" aria-hidden="true">Close</button>
  </div>
</div>

<script>

$("#upload_dialog_{{unique|escapejs}}").on("show", function () {
  grr.layout("ArtifactJsonUploadView",
    "upload_dialog_body_{{unique|escapejs}}");
});

</script>
""")
Esempio n. 28
0
class ClientCrashDetailsRenderer(semantic.RDFValueRenderer):
    """Renders details about a single client crash."""

    layout_template = renderers.Template("""
<dl class="dl-horizontal">
  <dt>Timestamp</dt><dd>{{this.proxy.timestamp}}</dd>
  <dt>Crash Type</dt><dd>{{this.proxy.crash_type}}</dd>

  {% if this.proxy.crash_message %}
  <dt>Crash Message</dt><dd>{{this.proxy.crash_message}}</dd>
  {% endif %}

  {% if this.proxy.backtrace %}
  <dt>Backtrace</dt><dd>{{this.proxy.backtrace}}</dd>
  {% endif %}

  {% if this.proxy.session_id %}
  <dt>Session Id</dt>
  <dd>
     <a href="/#{{this.hash|escape}}"
        onclick='grr.loadFromHash("{{this.hash|escapejs}}")'>
        {{this.proxy.session_id|escape}}
     </a>
  </dd>
  {% endif %}

  <dt>Client Information</dt>
  <dd>{{this.client_info|safe}}</dd>
</dl>
""") + renderers.TemplateRenderer.help_template

    context_help_url = "admin.html#_crashes"

    def Layout(self, request, response):
        if self.proxy.session_id:
            self.hash = urllib.urlencode(
                dict(c=self.proxy.client_id,
                     flow=self.proxy.session_id,
                     main="ManageFlows"))
        client_info_renderer = semantic.FindRendererForObject(
            self.proxy.client_info)
        self.client_info = client_info_renderer.RawHTML(request)
        super(ClientCrashDetailsRenderer, self).Layout(request, response)
Esempio n. 29
0
class ValueRenderer(RDFValueRenderer):
    """A renderer which renders an RDFValue in machine readable format."""

    layout_template = renderers.Template("""
<span type='{{this.rdfvalue_type|escape}}' rdfvalue='{{this.value|escape}}'>
  {{this.rendered_value|safe}}
</span>
""")

    def Layout(self, request, response):
        self.rdfvalue_type = self.proxy.__class__.__name__
        try:
            self.value = self.proxy.SerializeToString()
        except AttributeError:
            self.value = utils.SmartStr(self.proxy)

        renderer = FindRendererForObject(self.proxy)
        self.rendered_value = renderer.RawHTML(request)
        return super(ValueRenderer, self).Layout(request, response)
Esempio n. 30
0
class HuntContextView(renderers.TemplateRenderer):
    """Render the hunt context."""

    layout_template = renderers.Template("""
{{this.args_str|safe}}
""")

    def Layout(self, request, response):
        """Display hunt's context presented as dict."""
        if not hasattr(self, "hunt_id"):
            self.hunt_id = request.REQ.get("hunt_id")
        self.hunt = aff4.FACTORY.Open(self.hunt_id,
                                      aff4_type=implementation.GRRHunt,
                                      token=request.token)

        self.args_str = renderers.DictRenderer(
            self.hunt.context).RawHTML(request)

        return super(HuntContextView, self).Layout(request, response)