Skip to content

Commit

Permalink
Merge pull request #23 from dolevf/directives
Browse files Browse the repository at this point in the history
1.3.3
  • Loading branch information
dolevf authored Mar 25, 2022
2 parents 6844b83 + 5f82337 commit a325d76
Show file tree
Hide file tree
Showing 8 changed files with 87 additions and 38 deletions.
19 changes: 19 additions & 0 deletions core/directives.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
from unicodedata import name
from graphql import GraphQLArgument, GraphQLNonNull, GraphQLString
from graphql.type.directives import GraphQLDirective, DirectiveLocation

GraphQLNetworkDirective = GraphQLDirective(
name="show_network",
locations=[
DirectiveLocation.FIELD,
DirectiveLocation.FRAGMENT_SPREAD,
DirectiveLocation.INLINE_FRAGMENT,
],
args={
"style": GraphQLArgument(
GraphQLNonNull(GraphQLString)
)
},
description="Displays the network associated with an IP Address (CIDR or Net)."
)

14 changes: 12 additions & 2 deletions core/models.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import datetime

from app import db
from core import helpers

# Models
class User(db.Model):
Expand All @@ -12,11 +14,18 @@ class Audit(db.Model):
__tablename__ = 'audits'
id = db.Column(db.Integer, primary_key=True)
gqloperation = db.Column(db.String)
gqlquery = db.Column(db.String)
timestamp = db.Column(db.DateTime, default=datetime.datetime.utcnow)

@classmethod
def create_audit_entry(cls, **kw):
obj = cls(**kw)
def create_audit_entry(cls, info):
gql_operation = helpers.get_opname(info.operation)
gql_query = '{}'

if info.context.json:
gql_query = info.context.json.get("query")

obj = cls(**{"gqloperation":gql_operation, "gqlquery":gql_query})
db.session.add(obj)
db.session.commit()
return obj
Expand Down Expand Up @@ -48,3 +57,4 @@ def create_paste(cls, **kw):
db.session.add(obj)
db.session.commit()
return obj

10 changes: 10 additions & 0 deletions core/security.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import config
import random
import ipaddress
import time

from core import helpers
Expand All @@ -14,6 +15,15 @@ def simulate_load():
if count > limit:
return

def get_network(addr, style='cidr'):
try:
if style == 'cidr':
return str(ipaddress.ip_network(addr))
else:
return str(ipaddress.ip_network(addr).netmask)
except:
return 'Could not identify network'

def is_port(port):
if isinstance(port, int):
if port >= 0 and port <= 65535:
Expand Down
67 changes: 39 additions & 28 deletions core/views.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import graphene

from core.directives import GraphQLNetworkDirective
from db.solutions import solutions as list_of_solutions

from flask import (
Expand Down Expand Up @@ -37,9 +39,16 @@ class Meta:
model = User

class PasteObject(SQLAlchemyObjectType):
p_id = graphene.String(source='id')
class Meta:
model = Paste

def resolve_ip_addr(self, info):
for field_ast in info.field_asts:
for i in field_ast.directives:
if i.name.value == 'show_network':
if i.arguments[0].name.value == 'style':
return security.get_network(self.ip_addr, style=i.arguments[0].value.value)
return self.ip_addr

class OwnerObject(SQLAlchemyObjectType):
class Meta:
Expand Down Expand Up @@ -68,23 +77,27 @@ def mutate(self, info, title, content, public, burn):
user_agent=request.headers.get('User-Agent', '')
)

Audit.create_audit_entry(gqloperation=helpers.get_opname(info.operation))
Audit.create_audit_entry(info)

return CreatePaste(paste=paste_obj)

class DeletePaste(graphene.Mutation):
ok = graphene.Boolean()
result = graphene.Boolean()

class Arguments:
title = graphene.String()
id = graphene.Int()

def mutate(self, info, title):
Paste.query.filter_by(title=title).delete()
db.session.commit()

Audit.create_audit_entry(gqloperation=helpers.get_opname(info.operation))
def mutate(self, info, id):
result = False

if Paste.query.filter_by(id=id).delete():
result = True
db.session.commit()

return DeletePaste(ok=True)
Audit.create_audit_entry(info)

return DeletePaste(result=result)

class UploadPaste(graphene.Mutation):
content = graphene.String()
Expand All @@ -107,7 +120,7 @@ def mutate(self, info, filename, content):
user_agent=request.headers.get('User-Agent', '')
)

Audit.create_audit_entry(gqloperation=helpers.get_opname(info.operation))
Audit.create_audit_entry(info)

return UploadPaste(result=result)

Expand All @@ -132,7 +145,7 @@ def mutate(self, info, host='pastebin.com', port=443, path='/', scheme="http"):
user_agent=request.headers.get('User-Agent', '')
)

Audit.create_audit_entry(gqloperation=helpers.get_opname(info.operation))
Audit.create_audit_entry(info)

return ImportPaste(result=cmd)

Expand All @@ -144,48 +157,48 @@ class Mutations(graphene.ObjectType):

class Query(graphene.ObjectType):
pastes = graphene.List(PasteObject, public=graphene.Boolean(), limit=graphene.Int())
paste = graphene.Field(PasteObject, p_id=graphene.String())
paste = graphene.Field(PasteObject, id=graphene.Int())
system_update = graphene.String()
system_diagnostics = graphene.String(username=graphene.String(), password=graphene.String(), cmd=graphene.String())
system_health = graphene.String()
read_and_burn = graphene.Field(PasteObject, p_id=graphene.Int())
read_and_burn = graphene.Field(PasteObject, id=graphene.Int())

def resolve_pastes(self, info, public=False, limit=1000):
query = PasteObject.get_query(info)
Audit.create_audit_entry(gqloperation=helpers.get_opname(info.operation))
Audit.create_audit_entry(info)
return query.filter_by(public=public, burn=False).order_by(Paste.id.desc()).limit(limit)

def resolve_paste(self, info, p_id):
def resolve_paste(self, info, id):
query = PasteObject.get_query(info)
Audit.create_audit_entry(gqloperation=helpers.get_opname(info.operation))
return query.filter_by(id=p_id, burn=False).first()
Audit.create_audit_entry(info)
return query.filter_by(id=id, burn=False).first()

def resolve_system_update(self, info):
security.simulate_load()
Audit.create_audit_entry(gqloperation=helpers.get_opname(info.operation))
Audit.create_audit_entry(info)
return 'no updates available'

def resolve_system_diagnostics(self, info, username, password, cmd='whoami'):
q = User.query.filter_by(username='admin').first()
real_passw = q.password
res, msg = security.check_creds(username, password, real_passw)
Audit.create_audit_entry(gqloperation=helpers.get_opname(info.operation))
Audit.create_audit_entry(info)
if res:
output = f'{cmd}: command not found'
if security.allowed_cmds(cmd):
output = helpers.run_cmd(cmd)
return output
return msg

def resolve_read_and_burn(self, info, p_id):
result = Paste.query.filter_by(id=p_id, burn=True).first()
Paste.query.filter_by(id=p_id, burn=True).delete()
def resolve_read_and_burn(self, info, id):
result = Paste.query.filter_by(id=id, burn=True).first()
Paste.query.filter_by(id=id, burn=True).delete()
db.session.commit()
Audit.create_audit_entry(gqloperation=helpers.get_opname(info.operation))
Audit.create_audit_entry(info)
return result

def resolve_system_health(self, info):
Audit.create_audit_entry(gqloperation=helpers.get_opname(info.operation))
Audit.create_audit_entry(info)
return 'System Load: {}'.format(
helpers.run_cmd("uptime | awk '{print $10, $11, $12}'")
)
Expand Down Expand Up @@ -230,7 +243,6 @@ def audit():
audit = Audit.query.all()
return render_template("audit.html", audit=audit)


@app.route('/start_over')
def start_over():
msg = "Restored to default state."
Expand Down Expand Up @@ -270,7 +282,7 @@ def set_difficulty():
if session.get('difficulty') == None:
helpers.set_mode('easy')

schema = graphene.Schema(query=Query, mutation = Mutations)
schema = graphene.Schema(query=Query, mutation=Mutations, directives=[GraphQLNetworkDirective])

gql_middlew = [
middleware.CostProtectionMiddleware(),
Expand All @@ -295,8 +307,7 @@ def set_difficulty():
'graphiql',
schema = schema,
graphiql = True,
middleware = igql_middlew,
batch=True
middleware = igql_middlew
))


5 changes: 1 addition & 4 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
from ipaddress import IPv4Network

from app import db
from core.models import Paste, Owner, User, Audit
from core.models import Paste, Owner, User

from db.agents import agents
from db.owners import owners
Expand Down Expand Up @@ -59,7 +59,6 @@ def pump_db():
db.create_all()
admin = User(username="admin", password=random_password())
owner = Owner(name='DVGAUser')
audit = Audit()
paste = Paste()
paste.title = random_title()
paste.content = "My First Paste"
Expand All @@ -68,11 +67,9 @@ def pump_db():
paste.owner = owner
paste.ip_addr = '127.0.0.1'
paste.user_agent = 'User-Agent not set'
audit.gqloperation = 'CreatePaste'
db.session.add(admin)
db.session.add(owner)
db.session.add(paste)
db.session.add(audit)

for _ in range(0, 10 ):
owner = Owner(name=random_owner())
Expand Down
2 changes: 2 additions & 0 deletions templates/audit.html
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ <h4>Recent Audit Log Activity</h4>
<th scope="col">#</th>
<th scope="col">Name</th>
<th scope="col">GraphQL Operation</th>
<th scope="col">GraphQL Query</th>
<th scope="col">Date</th>
</tr>
</thead>
Expand All @@ -29,6 +30,7 @@ <h4>Recent Audit Log Activity</h4>
<th scope="row">{{loop.index}}. </th>
<td>DVGAUser</td>
<td>{{i.gqloperation}}</td>
<td>{{i.gqlquery}}</td>
<td>{{i.timestamp.strftime('%Y-%m-%d %H:%M:%S')}}</td>
</tr>
</tbody>
Expand Down
6 changes: 3 additions & 3 deletions templates/paste.html
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@
var query = `mutation CreatePaste ($title: String!, $content: String!, $public: Boolean!, $burn: Boolean!) {
createPaste(title:$title, content:$content, public:$public, burn: $burn) {
paste {
pId
id
content
title
burn
Expand All @@ -124,8 +124,8 @@
(data => {
if (data.data.createPaste.paste.burn == true) {
var host = window.location.protocol + "//" + window.location.host;
var p_id = parseInt(data.data.createPaste.paste.pId)
url = host + `/graphql?query=query%20readAndBurn%20%7B%0A%20%20readAndBurn(pId%3A${p_id})%7B%0A%20%20%20%20title%0A%20%20%20%20content%0A%20%20%20%20burn%0A%20%20%7D%0A%7D%0A`
var id = parseInt(data.data.createPaste.paste.id)
url = host + `/graphql?query=query%20readAndBurn%20%7B%0A%20%20readAndBurn(id %3A${id})%7B%0A%20%20%20%20title%0A%20%20%20%20content%0A%20%20%20%20burn%0A%20%20%7D%0A%7D%0A`
$("#result").append(
`<div class="alert alert-success">
<h4 class="alert-heading">Well done!</h4>
Expand Down
2 changes: 1 addition & 1 deletion version.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
VERSION = '1.3.2'
VERSION = '1.3.3'

0 comments on commit a325d76

Please sign in to comment.