2018-09-20 02:56:17 +00:00
from __future__ import absolute_import
2018-11-22 03:15:21 +00:00
import logging , datetime
2018-09-20 02:56:17 +00:00
from django . contrib . auth . forms import PasswordChangeForm
from django . contrib . auth import update_session_auth_hash
from django . apps import apps
from django . conf import settings
from django . contrib . auth . models import User
from django . http import JsonResponse , HttpResponse
from django . utils import timezone
from django . views . generic import View
from django . forms import modelform_factory
2018-11-22 03:15:21 +00:00
import minecraft_manager . forms as mcm_forms
2018-12-13 21:18:29 +00:00
from minecraft_manager . models import Player , UserSettings , Application , IP , Ticket , Note
2018-09-20 02:56:17 +00:00
import minecraft_manager . api . api as mcm_api
2018-11-21 23:04:47 +00:00
from minecraft_manager . api . models import Token
2018-09-20 02:56:17 +00:00
import minecraft_manager . utils as mcm_utils
import minecraft_manager . external . stats as mcm_stats
logger = logging . getLogger ( __name__ )
2018-11-21 23:04:47 +00:00
def request_allowed ( request , permission ) :
2018-09-20 02:56:17 +00:00
is_authenticated = False
if hasattr ( request , ' user ' ) :
if hasattr ( request . user , ' is_authenticated ' ) :
is_authenticated = request . user . is_authenticated
get = request . GET
2018-11-21 23:04:47 +00:00
post = request . POST
2018-09-20 02:56:17 +00:00
request_password = None
if ' api ' in get :
request_password = get [ ' api ' ]
elif ' api ' in post :
request_password = post [ ' api ' ]
2018-11-21 23:04:47 +00:00
token_permission = False
if Token . objects . filter ( active = True , key = request_password ) . exists ( ) :
token = Token . objects . get ( active = True , key = request_password )
token_permission = getattr ( token , permission , False )
return is_authenticated or token_permission
2018-09-20 02:56:17 +00:00
def clean ( model , data ) :
cleaned = { }
for d in data :
attr = d
if ' __ ' in d :
attr = d . split ( ' __ ' ) [ 0 ]
2019-10-01 21:08:49 +00:00
if hasattr ( model , attr ) and attr != " api " :
2018-09-20 02:56:17 +00:00
cleaned [ d ] = data [ d ]
return cleaned
class WebAPI ( View ) :
def get ( self , request , keyword ) :
get = request . GET
data = { ' success ' : False , ' message ' : ' API failed ' }
2018-11-21 23:04:47 +00:00
if request_allowed ( request , ' web_get_permission ' ) :
2018-09-20 02:56:17 +00:00
keyword = keyword . lower ( )
if keyword == ' log ' :
html_global = " "
html_staff = " "
chats = mcm_api . get_chats ( request . user . usersettings . default_timezone )
if chats :
for g in chats [ ' global ' ] :
g [ ' text ' ] = g [ ' text ' ] . replace ( " < " , " < " ) . replace ( " > " , " > " )
if request . user . usersettings . show_timestamp_chat :
html_global + = " <div>[ {0} ] {1} </div> " . format ( g [ ' date ' ] , g [ ' text ' ] )
else :
html_global + = " <div data-toggle= ' tooltip ' title= ' {0} ' data-placement= ' left ' > {1} </div> " . format ( g [ ' date ' ] , g [ ' text ' ] )
for s in chats [ ' staff ' ] :
s [ ' text ' ] = s [ ' text ' ] . replace ( " < " , " < " ) . replace ( " > " , " > " )
if request . user . usersettings . show_timestamp_chat :
html_staff + = " <div>[ {0} ] {1} </div> " . format ( s [ ' date ' ] , s [ ' text ' ] )
else :
html_staff + = " <div data-toggle= ' tooltip ' title= ' {0} ' data-placement= ' left ' > {1} </div> " . format ( s [ ' date ' ] , s [ ' text ' ] )
html = { ' global ' : html_global , ' staff ' : html_staff }
data = { ' chats ' : chats , ' html ' : html }
elif keyword == ' online ' :
query = mcm_api . get_query ( )
html = " "
for p in query [ ' players ' ] :
html + = " <div class= ' label label-primary ' > {0} </div> " . format ( p )
html + = " <br/> "
data = { ' query ' : query , ' html ' : html }
elif keyword == " coreprotect " :
if ' username ' in get and ' ip ' in get :
user = User . objects . get ( username = get [ ' username ' ] )
if user . is_active and user . usersettings . last_ip == get [ ' ip ' ] :
data = { ' success ' : True , ' message ' : self . access_level ( user ) }
else :
data = { ' success ' : False , ' message ' : ' Parameters not set ' }
else :
data = { ' message ' : ' Not Authorized ' , ' success ' : False }
return JsonResponse ( data )
def post ( self , request , keyword ) :
post = request . POST
data = { }
2018-11-21 23:04:47 +00:00
if request_allowed ( request , ' web_post_permission ' ) :
2018-09-20 02:56:17 +00:00
keyword = keyword . lower ( )
if keyword == ' settings ' and request . user . usersettings :
for s in [ a for a in dir ( UserSettings ) if not a . startswith ( ' __ ' ) and not callable ( getattr ( UserSettings , a ) ) ] :
if s in post :
setattr ( request . user . usersettings , s , post [ s ] )
request . user . usersettings . save ( )
data = { ' success ' : True , ' message ' : ' User Settings saved ' }
elif keyword == ' password ' :
form = PasswordChangeForm ( request . user , post )
if form . is_valid ( ) :
user = form . save ( )
update_session_auth_hash ( request , user )
return HttpResponse ( " success " )
else :
return HttpResponse ( form . as_p ( ) )
elif keyword == ' alert ' :
2018-11-22 03:15:21 +00:00
form = mcm_forms . AlertForm ( request . POST )
2018-09-20 02:56:17 +00:00
if form . is_valid ( ) :
if mcm_api . create_alert ( form . cleaned_data [ ' message ' ] ) :
data = { ' success ' : True }
else :
data = { ' success ' : False , ' message ' : ' Could not create Alerts ' }
else :
data = { ' success ' : False , ' message ' : ' Invalid Message ' }
elif keyword == " discord " :
if ' message ' in post :
ping = post [ ' ping ' ] if ' ping ' in post else False
mcm_api . discord_notification ( post [ ' message ' ] , ping = ping )
data = { ' success ' : True , ' message ' : " Success " , ' extra ' : { ' message ' : post [ ' message ' ] , ' ping ' : ping } }
else :
data = { ' success ' : False , ' message ' : ' No message supplied ' }
else :
data = { ' success ' : True , ' message ' : ' Model set to " {0} " ' . format ( keyword ) }
else :
data = { ' message ' : ' Not Authorized ' , ' success ' : False }
return JsonResponse ( data )
def access_level ( self , user ) :
access = { ' cpp ' : False , ' cpf ' : False , ' cpa ' : False }
2019-08-27 20:44:20 +00:00
if user . has_perm ( ' minecraft_manager.coreprotect_partial ' ) :
2018-09-20 02:56:17 +00:00
access [ ' cpp ' ] = True
2019-08-27 20:44:20 +00:00
if user . has_perm ( ' minecraft_manager.coreprotect_full ' ) :
2018-09-20 02:56:17 +00:00
access [ ' cpf ' ] = True
2019-08-27 20:44:20 +00:00
if user . has_perm ( ' minecraft_manager.coreprotect_activity ' ) :
2018-09-20 02:56:17 +00:00
access [ ' cpa ' ] = True
return access
class PluginAPI ( View ) :
def get ( self , request , keyword ) :
json = { ' status ' : True , ' message ' : ' ' , ' extra ' : ' ' }
2018-11-21 23:04:47 +00:00
if request_allowed ( request , ' plugin_get_permission ' ) :
2018-09-20 02:56:17 +00:00
get = request . GET
keyword = keyword . lower ( )
return JsonResponse ( json )
def post ( self , request , keyword ) :
json = { ' status ' : True , ' message ' : ' ' , ' extra ' : ' ' }
2018-11-21 23:04:47 +00:00
if request_allowed ( request , ' plugin_post_permission ' ) :
2018-09-20 02:56:17 +00:00
post = request . POST
keyword = keyword . lower ( )
if " application " == keyword :
if Application . objects . filter ( username = post [ ' username ' ] ) . exists ( ) :
application = Application . objects . get ( username = post [ ' username ' ] )
if application . accepted is not None :
json [ ' status ' ] = False
json [ ' message ' ] = " An application for {0} has already been acted on. Please contact Staff. " . format (
post [ ' username ' ] )
return JsonResponse ( json )
else :
application . accepted = None
application . age = post [ ' age ' ]
application . player_type = post [ ' player_type ' ]
application . ever_banned = False if post [ ' ever_banned ' ] == " no " else True
application . ever_banned_explanation = post [ ' ever_banned_explanation ' ]
application . reference = post [ ' reference ' ]
application . read_rules = post [ ' read_rules ' ]
else :
application = Application ( username = post [ ' username ' ] , age = post [ ' age ' ] ,
player_type = post [ ' player_type ' ] ,
ever_banned = False if post [ ' ever_banned ' ] == " no " else True ,
ever_banned_explanation = post [ ' ever_banned_explanation ' ] ,
reference = post [ ' reference ' ] , read_rules = post [ ' read_rules ' ] )
application . save ( )
if Player . objects . filter ( username__iexact = post [ ' username ' ] ) . exists ( ) :
player = Player . objects . get ( username__iexact = post [ ' username ' ] )
player . application_id = application . id
player . save ( )
json [ ' message ' ] = " {0} ' s application was submitted. " . format ( application . username )
json [ ' extra ' ] = application . id
msg = mcm_utils . build_application ( application )
2019-08-30 18:03:12 +00:00
mcm_api . discord_mcm ( message = ' New Application! ' , embed = msg )
2018-09-20 02:56:17 +00:00
elif " application_action " == keyword :
if Application . objects . filter ( id = post [ ' application_id ' ] ) . exists ( ) :
application = Application . objects . get ( id = post [ ' application_id ' ] )
if application . accepted is not None :
json [ ' status ' ] = False
json [ ' message ' ] = " Application was already {0} . " . format (
" accepted " if post [ ' action ' ] == " True " else " denied " )
else :
application . accepted = True if post [ ' action ' ] == " True " else False
application . save ( )
json [ ' message ' ] = " Application was successfully {0} . " . format (
" accepted " if post [ ' action ' ] == " True " else " denied " )
mcm_api . discord_mcm ( " {0} ' s application (# {1} ) was {2} by {3} " . format ( application . username ,
application . id ,
" accepted " if post [ ' action ' ] == " True " else " denied " ,
post [ ' username ' ] ) )
mcm_api . plugin ( " accept " if post [ ' action ' ] == " True " else " deny " , application . username )
else :
json [ ' status ' ] = False
json [ ' message ' ] = " No application found. "
return JsonResponse ( json )
elif " application_clear " == keyword :
if Application . objects . filter ( id = post [ ' application_id ' ] ) . exists ( ) :
application = Application . objects . get ( id = post [ ' application_id ' ] )
if application . accepted is True :
json [ ' status ' ] = False
json [ ' message ' ] = " An accepted application can ' t be cleared. "
else :
application . accepted = None
application . save ( )
json [ ' message ' ] = " Application was successfully cleared. "
else :
json [ ' status ' ] = False
json [ ' message ' ] = " No application found. "
return JsonResponse ( json )
elif " login " == keyword :
player = Player . objects . filter ( uuid = post [ ' uuid ' ] ) . exists ( )
new_player = False
if not player :
player = Player ( uuid = post [ ' uuid ' ] , username = post [ ' username ' ] )
new_player = True
player . first_seen = timezone . now ( ) . strftime ( " % Y- % m- %d " )
test_app = Application . objects . filter ( username__iexact = post [ ' username ' ] ) . exists ( )
if test_app :
test_app = Application . objects . get ( username__iexact = post [ ' username ' ] )
player . application = test_app
player . save ( )
else :
player = Player . objects . get ( uuid = post [ ' uuid ' ] )
if player . username != post [ ' username ' ] :
user = User . objects . filter ( username__iexact = player . username ) . exists ( )
if user :
user = User . objects . get ( username__iexact = player . username )
user . username = post [ ' username ' ] . lower ( )
user . save ( )
mcm_api . create_alert ( " Name Change: {0} to {1} . " . format ( player . username , post [ ' username ' ] ) )
player . username = post [ ' username ' ]
if not player . application :
test_app = Application . objects . filter ( username__iexact = post [ ' username ' ] ) . exists ( )
if test_app :
test_app = Application . objects . get ( username__iexact = player . username )
player . application = test_app
player . save ( )
test_ip = IP . objects . filter ( ip = post [ ' ip ' ] , player = player ) . exists ( )
2018-09-22 04:35:51 +00:00
last_used = datetime . date . today ( )
2018-09-20 02:56:17 +00:00
if not test_ip :
ip = IP ( ip = post [ ' ip ' ] , player = player )
else :
ip = IP . objects . get ( ip = post [ ' ip ' ] , player = player )
2018-09-22 04:35:51 +00:00
ip . last_used = last_used
ip . save ( )
2018-09-20 02:56:17 +00:00
player = Player . objects . get ( uuid = post [ ' uuid ' ] )
player . last_seen = timezone . now ( ) . strftime ( " % Y- % m- %d " )
player . save ( )
if new_player and ip . associated :
2018-12-05 18:16:36 +00:00
associated = [ ]
2018-09-20 02:56:17 +00:00
for assoc in ip . associated :
if assoc . uuid is not player . uuid and assoc . is_banned :
2018-12-05 18:16:36 +00:00
associated . append ( assoc )
if associated :
mcm_api . plugin ( " staff " , " Server {0} ' s IP matches the banned player(s) {1} " . format ( player . username , " , " . join ( [ assoc . username for assoc in associated ] ) ) )
mcm_api . discord_notification ( " {0} ' s IP matches the banned player(s) {1} " . format ( player . username , " , " . join ( [ assoc . username for assoc in associated ] ) ) , ping = True )
2018-09-20 02:56:17 +00:00
json [ ' status ' ] = True
json [ ' message ' ] = " Updated {0} " . format ( post [ ' username ' ] )
elif " register " == keyword :
player = Player . objects . get ( uuid = post [ ' uuid ' ] )
2019-09-30 19:43:13 +00:00
password = mcm_api . generate_password ( )
2018-09-20 02:56:17 +00:00
if player . auth_user :
2019-09-30 19:43:13 +00:00
player . auth_user . password = password
player . auth_user . is_active = True
player . auth_user . save ( )
json [ ' message ' ] = password
2018-09-20 02:56:17 +00:00
else :
user = User . objects . create_user ( username = player . username . lower ( ) , password = password )
user . save ( )
player . auth_user = user
player . save ( )
json [ ' message ' ] = password
elif " ticket " == keyword :
player = Player . objects . get ( uuid = post [ ' uuid ' ] )
try :
ticket = Ticket ( player = player , message = post [ ' message ' ] , x = post [ ' x ' ] , y = post [ ' y ' ] , z = post [ ' z ' ] , world = post [ ' world ' ] )
ticket . save ( )
json [ ' message ' ] = " Ticket submitted. "
link = " {} " . format ( mcm_utils . url_path ( settings . MCM_BASE_LINK , ' dashboard/ticket ' , ticket . id ) )
msg = mcm_utils . build_ticket ( ticket , link )
json [ ' extra ' ] = { ' id ' : ticket . id , ' link ' : link }
2019-08-30 18:03:12 +00:00
mcm_api . discord_mcm ( embed = msg , ping = True )
2018-09-20 02:56:17 +00:00
except :
json [ ' status ' ] = False
json [ ' message ' ] = " Error while submitting ticket. "
elif " warning " == keyword :
player = Player . objects . get ( uuid = post [ ' player ' ] )
staff = Player . objects . get ( uuid = post [ ' staff ' ] )
try :
2018-12-13 21:18:29 +00:00
warning = Note ( player = player , message = post [ ' message ' ] , importance = post [ ' severity ' ] , staff = staff . auth_user )
2018-09-20 02:56:17 +00:00
warning . save ( )
json [ ' message ' ] = " Warning issued. "
2018-12-13 21:18:29 +00:00
link = " {} " . format ( mcm_utils . url_path ( settings . MCM_BASE_LINK , ' dashboard/note ' , warning . id ) )
2018-09-20 02:56:17 +00:00
msg = mcm_utils . build_warning ( warning , link )
2019-08-30 18:03:12 +00:00
mcm_api . discord_mcm ( embed = msg )
2018-09-20 02:56:17 +00:00
except Exception as ex :
json [ ' status ' ] = False
json [ ' message ' ] = " Error while issuing warning. "
return JsonResponse ( json )
class FormAPI ( View ) :
def get ( self , request , request_model ) :
html = " "
2018-11-21 23:04:47 +00:00
if request_allowed ( request , ' form_get_permission ' ) :
2018-09-20 02:56:17 +00:00
get = request . GET
model = None
for m in apps . get_app_config ( ' minecraft_manager ' ) . get_models ( ) :
if m . _meta . model_name . upper ( ) == request_model . upper ( ) :
model = m
break
if model :
form = None
2018-11-22 03:15:21 +00:00
for modelform in mcm_forms . __all__ ( ) :
2018-09-20 02:56:17 +00:00
if modelform . Meta . model == model :
form = modelform ( )
break
if not form :
form = modelform_factory ( model , exclude = ( ' id ' , ) ) ( )
if ' as ' in get :
html = getattr ( form , ' as_ {0} ' . format ( get [ ' as ' ] ) ) ( )
else :
html = form . as_p ( )
return HttpResponse ( html )
def post ( self , request , request_model ) :
html = " "
2018-11-21 23:04:47 +00:00
if request_allowed ( request , ' form_post_permission ' ) :
2018-09-20 02:56:17 +00:00
post = request . POST
model = None
for m in apps . get_app_config ( ' minecraft_manager ' ) . get_models ( ) :
if m . _meta . model_name . upper ( ) == request_model . upper ( ) :
model = m
break
if model :
form = None
2018-11-22 03:15:21 +00:00
for modelform in mcm_forms . __all__ ( ) :
2018-09-20 02:56:17 +00:00
if modelform . Meta . model == model :
form = modelform ( post )
break
if not form :
form = modelform_factory ( model , exclude = ( ' id ' , ) ) ( post )
if form . is_valid ( ) :
form . save ( )
html = " Saved "
else :
if ' as ' in post :
html = getattr ( form , ' as_ {0} ' . format ( post [ ' as ' ] ) ) ( )
else :
html = form . as_p ( )
return HttpResponse ( html )
class ModelAPI ( View ) :
def get ( self , request , request_model ) :
json = [ ]
2018-11-21 23:04:47 +00:00
if request_allowed ( request , ' model_get_permission ' ) :
2018-09-20 02:56:17 +00:00
get = request . GET
model = None
for m in apps . get_app_config ( ' minecraft_manager ' ) . get_models ( ) :
if m . _meta . model_name . upper ( ) == request_model . upper ( ) :
model = m
break
if model :
keywords = clean ( model , get )
2018-10-17 03:22:28 +00:00
objects = model . api . filter ( * * keywords ) . values ( ) if getattr ( model , ' api ' , False ) else model . objects . filter ( * * keywords ) . values ( )
2018-09-20 02:56:17 +00:00
json = [ ]
for value in objects :
try :
link = " {} " . format ( mcm_utils . url_path ( settings . MCM_BASE_LINK , ' dashboard ' , request_model , value [ ' id ' ] ) )
value [ ' link ' ] = link
except :
pass
json . append ( value )
return JsonResponse ( json , safe = False )
def post ( self , request , request_model ) :
2019-11-22 02:28:05 +00:00
json = { " success " : False , " message " : " " }
print ( request . POST )
if request_allowed ( request , ' model_post_permission ' ) :
post = request . POST
model = None
for m in apps . get_app_config ( ' minecraft_manager ' ) . get_models ( ) :
if m . _meta . model_name . upper ( ) == request_model . upper ( ) :
model = m
break
if model :
keywords = clean ( model , post )
if " id " in keywords :
try :
obj = model . objects . get ( id = keywords [ " id " ] )
for key in keywords . keys ( ) :
setattr ( obj , key , keywords [ key ] )
obj . save ( )
json [ " success " ] = True
json [ " message " ] = " Model updated "
except Exception as ex :
print ( ex )
json [ " message " ] = " Could not update model "
else :
json [ " message " ] = " Must provide an ID "
return JsonResponse ( json )
2018-09-20 02:56:17 +00:00
class StatsAPI ( View ) :
def get ( self , request ) :
json = [ ]
2018-11-21 23:04:47 +00:00
if request_allowed ( request , ' stats_get_permission ' ) :
2018-09-20 02:56:17 +00:00
get = request . GET
if ' stat ' in get :
if ' uuid ' in get :
json = mcm_stats . one_single ( get [ ' uuid ' ] , get [ ' stat ' ] )
elif ' username ' in get and Player . objects . filter ( username__iexact = get [ ' username ' ] ) . exists ( ) :
uuid = Player . objects . get ( username__iexact = get [ ' username ' ] ) . uuid
json = mcm_stats . one_single ( uuid , get [ ' stat ' ] )
else :
json = mcm_stats . top_ten_stat ( get [ ' stat ' ] )
elif ' uuid ' in get :
json = mcm_stats . top_ten_player ( get [ ' uuid ' ] )
elif ' username ' in get :
uuid = Player . objects . get ( username__iexact = get [ ' username ' ] ) . uuid
json = mcm_stats . top_ten_player ( uuid )
return JsonResponse ( json , safe = False )
def post ( self , request ) :
pass