mirror of https://gitlab.com/bashrc2/epicyon
Terms of service
parent
13dc4e889b
commit
ed46de3709
21
daemon.py
21
daemon.py
|
@ -22,6 +22,7 @@ from session import createSession
|
|||
from webfinger import webfingerMeta
|
||||
from webfinger import webfingerLookup
|
||||
from webfinger import webfingerHandle
|
||||
from person import registerAccount
|
||||
from person import personLookup
|
||||
from person import personBoxJson
|
||||
from person import createSharedInbox
|
||||
|
@ -74,6 +75,7 @@ from webinterface import htmlSearch
|
|||
from webinterface import htmlUnfollowConfirm
|
||||
from webinterface import htmlProfileAfterSearch
|
||||
from webinterface import htmlEditProfile
|
||||
from webinterface import htmlTermsOfService
|
||||
from shares import getSharesFeedForPerson
|
||||
from shares import outboxShareUpload
|
||||
from shares import outboxUndoShareUpload
|
||||
|
@ -429,7 +431,7 @@ class PubServer(BaseHTTPRequestHandler):
|
|||
|
||||
# if not authorized then show the login screen
|
||||
if self.headers.get('Accept'):
|
||||
if 'text/html' in self.headers['Accept'] and self.path!='/login':
|
||||
if 'text/html' in self.headers['Accept'] and self.path!='/login' and self.path!='/terms':
|
||||
if '/media/' not in self.path and \
|
||||
'/sharefiles/' not in self.path and \
|
||||
'/statuses/' not in self.path and \
|
||||
|
@ -602,7 +604,13 @@ class PubServer(BaseHTTPRequestHandler):
|
|||
if self._webfinger():
|
||||
self.server.GETbusy=False
|
||||
return
|
||||
|
||||
|
||||
if self.path.startswith('/terms'):
|
||||
self._login_headers('text/html')
|
||||
self.wfile.write(htmlTermsOfService(self.server.baseDir).encode())
|
||||
self.server.GETbusy=False
|
||||
return
|
||||
|
||||
if self.path.startswith('/login'):
|
||||
# request basic auth
|
||||
self._login_headers('text/html')
|
||||
|
@ -1654,9 +1662,16 @@ class PubServer(BaseHTTPRequestHandler):
|
|||
self.server.POSTbusy=False
|
||||
return
|
||||
loginParams=self.rfile.read(length).decode('utf-8')
|
||||
loginNickname,loginPassword=htmlGetLoginCredentials(loginParams,self.server.lastLoginTime)
|
||||
loginNickname,loginPassword,register=htmlGetLoginCredentials(loginParams,self.server.lastLoginTime)
|
||||
if loginNickname:
|
||||
self.server.lastLoginTime=int(time.time())
|
||||
if register:
|
||||
if not registerAccount(self.server.baseDir,self.server.httpPrefix, \
|
||||
self.server.domain,self.server.port, \
|
||||
loginNickname,loginPassword):
|
||||
self.server.POSTbusy=False
|
||||
self._redirect_headers('/login',cookie)
|
||||
return
|
||||
authHeader=createBasicAuthHeader(loginNickname,loginPassword)
|
||||
if not authorizeBasic(self.server.baseDir,'/users/'+loginNickname+'/outbox',authHeader,False):
|
||||
print('Login failed: '+loginNickname)
|
||||
|
|
|
@ -0,0 +1,25 @@
|
|||
<h1>Terms of Service</h1>
|
||||
|
||||
<h3>Data Collected</h3>
|
||||
|
||||
<p>Your username and a hash of your password, any posts you make and a list of accounts which you follow. The admin of the site does not know your password and it is not stored in plaintext anywhere.</p>
|
||||
|
||||
<p>There is a quota on the number of posts retained by this instance for each account. Older posts will be removed when the limit is reached. Anything you post here should be considered ephemeral and you should keep a separate personal copy of them if you wish to retain a permanent archive.</p>
|
||||
|
||||
<p>No IP addresses are logged.</p>
|
||||
|
||||
<p>Posts can be removed on request if there is sufficient justification, but the nature of ActivityPub means that deletion of data federated to other instances cannot be guaranteed.</p>
|
||||
|
||||
<h3>Content Policy</h3>
|
||||
|
||||
<p>This instance will not host content containing sexism, racism, homophobia, transphobia, misogyny, antisemitism or other forms of bigotry or discrimination on the basis of nationality. Claims that transgressions of this type were intended to be "ironic" will be treated as a terms of service violation.</p>
|
||||
|
||||
<p>Violent or abusive content will be subject to moderation and is likely to be removed.</p>
|
||||
|
||||
<p>Content found to be non-compliant with this policy will be removed and any accounts on this instance producing, repeating or linking to such content will be deleted typically without prior notification.</p>
|
||||
|
||||
<h3>No Commercial Use</h3>
|
||||
|
||||
<p>Commercial use of original content on this instance is strictly forbidden without the prior written permission of the account holder. Publication or federation of content does not imply permission for commercial use.</p>
|
||||
|
||||
<p>Commercial use includes the harvesting of data to create products which are then sold, such as statistics, business reports or machine learning models.</p>
|
17
person.py
17
person.py
|
@ -218,6 +218,23 @@ def createPersonBase(baseDir: str,nickname: str,domain: str,port: int, \
|
|||
|
||||
return privateKeyPem,publicKeyPem,newPerson,webfingerEndpoint
|
||||
|
||||
def registerAccount(baseDir: str,httpPrefix: str,domain: str,port: int, \
|
||||
nickname: str,password: str) -> bool:
|
||||
"""Registers a new account from the web interface
|
||||
"""
|
||||
if not validNickname(nickname):
|
||||
print('REGISTER: Nickname '+nickname+' is invalid')
|
||||
return False
|
||||
if len(password)<8:
|
||||
print('REGISTER: Password should be at least 8 characters')
|
||||
return False
|
||||
privateKeyPem,publicKeyPem,newPerson,webfingerEndpoint= \
|
||||
createPerson(baseDir,nickname,domain,port, \
|
||||
httpPrefix,True,password)
|
||||
if privateKeyPem:
|
||||
return True
|
||||
return False
|
||||
|
||||
def createPerson(baseDir: str,nickname: str,domain: str,port: int, \
|
||||
httpPrefix: str, saveToFile: bool,password=None) -> (str,str,{},{}):
|
||||
"""Returns the private key, public key, actor and webfinger endpoint
|
||||
|
|
|
@ -129,27 +129,30 @@ def htmlEditProfile(baseDir: str,path: str,domain: str,port: int) -> str:
|
|||
editProfileForm+=htmlFooter()
|
||||
return editProfileForm
|
||||
|
||||
def htmlGetLoginCredentials(loginParams: str,lastLoginTime: int) -> (str,str):
|
||||
def htmlGetLoginCredentials(loginParams: str,lastLoginTime: int) -> (str,str,bool):
|
||||
"""Receives login credentials via HTTPServer POST
|
||||
"""
|
||||
if not loginParams.startswith('username='):
|
||||
return None,None
|
||||
return None,None,None
|
||||
# minimum time between login attempts
|
||||
currTime=int(time.time())
|
||||
if currTime<lastLoginTime+5:
|
||||
return None,None
|
||||
if currTime<lastLoginTime+10:
|
||||
return None,None,None
|
||||
if '&' not in loginParams:
|
||||
return None,None
|
||||
return None,None,None
|
||||
loginArgs=loginParams.split('&')
|
||||
nickname=None
|
||||
password=None
|
||||
register=False
|
||||
for arg in loginArgs:
|
||||
if '=' in arg:
|
||||
if arg.split('=',1)[0]=='username':
|
||||
nickname=arg.split('=',1)[1]
|
||||
elif arg.split('=',1)[0]=='password':
|
||||
password=arg.split('=',1)[1]
|
||||
return nickname,password
|
||||
elif arg.split('=',1)[0]=='register':
|
||||
register=True
|
||||
return nickname,password,register
|
||||
|
||||
def htmlLogin(baseDir: str) -> str:
|
||||
accounts=noOfAccounts(baseDir)
|
||||
|
@ -175,8 +178,12 @@ def htmlLogin(baseDir: str) -> str:
|
|||
registerButtonStr=''
|
||||
if getConfigParam(baseDir,'registration')=='open':
|
||||
if int(getConfigParam(baseDir,'registrationsRemaining'))>0:
|
||||
if accounts>0:
|
||||
loginText='<p class="login-text">Welcome. Please login or register a new account.</p>'
|
||||
registerButtonStr='<button type="submit" name="register">Register</button>'
|
||||
|
||||
TOSstr='<p class="login-text"><a href="/terms">Terms of Service</a></p>'
|
||||
|
||||
loginButtonStr=''
|
||||
if accounts>0:
|
||||
loginButtonStr='<button type="submit" name="submit">Login</button>'
|
||||
|
@ -186,7 +193,7 @@ def htmlLogin(baseDir: str) -> str:
|
|||
'<form method="POST" action="/login">' \
|
||||
' <div class="imgcontainer">' \
|
||||
' <img src="login.png" alt="login image" class="loginimage">'+ \
|
||||
loginText+ \
|
||||
loginText+TOSstr+ \
|
||||
' </div>' \
|
||||
'' \
|
||||
' <div class="container">' \
|
||||
|
@ -201,6 +208,27 @@ def htmlLogin(baseDir: str) -> str:
|
|||
loginForm+=htmlFooter()
|
||||
return loginForm
|
||||
|
||||
def htmlTermsOfService(baseDir: str) -> str:
|
||||
if not os.path.isfile(baseDir+'/accounts/tos.txt'):
|
||||
copyfile(baseDir+'/default_tos.txt',baseDir+'/accounts/tos.txt')
|
||||
if os.path.isfile(baseDir+'/img/login-background.png'):
|
||||
if not os.path.isfile(baseDir+'/accounts/login-background.png'):
|
||||
copyfile(baseDir+'/img/login-background.png',baseDir+'/accounts/login-background.png')
|
||||
|
||||
TOSText='Terms of Service go here.'
|
||||
if os.path.isfile(baseDir+'/accounts/tos.txt'):
|
||||
with open(baseDir+'/accounts/tos.txt', 'r') as file:
|
||||
TOSText = file.read()
|
||||
|
||||
TOSForm=''
|
||||
with open(baseDir+'/epicyon-profile.css', 'r') as cssFile:
|
||||
termsCSS = cssFile.read()
|
||||
|
||||
TOSForm=htmlHeader(termsCSS)
|
||||
TOSForm+='<div class="container">'+TOSText+'</div>'
|
||||
TOSForm+=htmlFooter()
|
||||
return TOSForm
|
||||
|
||||
def htmlNewPost(baseDir: str,path: str,inReplyTo: str,mentions: []) -> str:
|
||||
replyStr=''
|
||||
if not path.endswith('/newshare'):
|
||||
|
|
Loading…
Reference in New Issue