Commit a2eb451d authored by David Libeau's avatar David Libeau

Add Activity Pub craft for User (webfinger + APub json view)

parent 8ff47070
......@@ -2,4 +2,4 @@ DirectoryIndex core/app.php?q=index
RewriteEngine On
RewriteRule ^(.*)$ core/app.php?q=$1 [L,QSA]
\ No newline at end of file
RewriteRule "^(.*)$" "core/app.php?q=$1" [L,QSA]
\ No newline at end of file
<?php
require("autoload.php");
if(isset($_GET["q"]) && $_GET["q"]!=""){
$query=explode("/",$_GET["q"]);
$qPos=0;
$xmlroutes=simplexml_load_file("routes/core.xml");
$route=$xmlroutes;
foreach($query as $q){
$qPos++;
$foundRoute=false;
foreach($route->route as $currentRoute) {
if(preg_match("/^".$currentRoute->content."$/", $q)){
$foundRoute=true;
$route=$currentRoute;
}
}
if(!$foundRoute){
foreach($route->route as $currentRoute) {
if(substr($currentRoute->content,0,1)==":"){
$foundRoute=true;
$route=$currentRoute;
}
}
}
}
$className=explode("->",$route->return->function)[0];
//var_dump(explode("->",$route->return->function));
$functionName=explode("->",$route->return->function)[1];
$class=new $className();
if(isset($route->return->params)){
$params=array();
if(count($route->return->params->children())!=0){
foreach ($route->return->params->children() as $param) {
if($route->return->params==":this"){
$params[]=$query[$qPos-1];
}else{
$params[]=$param;
}
}
}else{
if($route->return->params==":this"){
$params[]=$query[$qPos-1];
}else{
$params[]=$route->return->params;
}
}
//var_dump($class);
call_user_func_array(array($class,$functionName),$params);
}else{
//var_dump($route->return);
call_user_func("".$route->return->function);
}
if(isset($_GET["q"]) && $_GET["q"]!=""){
$core=new Core();
$core->welcome($_GET["q"]);
}
?>
\ No newline at end of file
<?php
class Core{
protected $domain="dev.fedi.blog";
public function welcome($query) {
$query=explode("/",$query);
$qPos=0;
//.well-known/webfinger?resource=acct:david@fedi.blog
if($query[0]==".well-known"){
if($query[1]=="webfinger"){
if(isset($_GET["resource"]) && $_GET["resource"]!=""){
$this->webfinger($_GET["resource"]);
}
}
}else{
$xmlroutes=simplexml_load_file("routes/core.xml");
$route=$xmlroutes;
foreach($query as $q){
if($q!=""){
$qPos++;
$foundRoute=false;
foreach($route->route as $currentRoute) {
if(preg_match("/^".$currentRoute->content."$/", $q)){
$foundRoute=true;
$route=$currentRoute;
}
}
if(!$foundRoute){
foreach($route->route as $currentRoute) {
if(substr($currentRoute->content,0,1)==":"){ // :this :parent
$foundRoute=true;
$route=$currentRoute;
}
}
}
}
}
foreach($currentRoute->route as $subRoute) {
if($subRoute->content==""){
foreach($subRoute->content->attributes() as $attr => $attrvalue) {
if($attr=="type"){
$contentTypes=explode(";",$_SERVER["HTTP_ACCEPT"])[0];
$contentTypes=explode(",",$contentTypes);
foreach($contentTypes as $contentType){
if($contentType==$attrvalue){
$foundRoute=true;
$route=$subRoute;
}
}
}
}
}
}
if($foundRoute){
$className=explode("->",$route->return->function)[0];
//var_dump(explode("->",$route->return->function));
$functionName=explode("->",$route->return->function)[1];
$class=new $className();
if(isset($route->return->params)){
$params=array();
if(count($route->return->params->children())!=0){
foreach ($route->return->params->children() as $param) {
if($param==":this"){
$params[]=$query[$qPos-1];
}else if($param==":parent"){
$params[]=$query[$qPos-2];
}else{
$params[]=$param;
}
}
}else{
if($route->return->params==":this"){
$params[]=$query[$qPos-1];
}else if($route->return->params==":parent"){
$params[]=$query[$qPos-2];
}else{
$params[]=$route->return->params;
}
}
//var_dump($class);
call_user_func_array(array($class,$functionName),$params);
}else{
//var_dump($route->return);
call_user_func("".$route->return->function);
}
}else{
$this->error("404");
}
}
}
public static function error($code=200,$message="") {
if($code!=200 && $message!=""){
http_response_code($code);
echo("Error ".$code.": ".$message);
}else if($code!=200){
http_response_code($code);
echo("Error ".$code);
}else{
echo("Error : ".$message);
}
exit;
}
public function get($var){
return($this->$var);
}
public function webfinger($query){
$query=explode(":",$query);
if($query[0]=="acct"){
$account=explode("@",$query[1]);
$username=$account[0];
$domain=$account[1];
if(User::isInDatabase($username) && $domain==$this->get("domain")){
header('Content-type: application/json;charset=utf-8');
echo(json_encode(array(
"subject" => join(":", $query),
"links" => array(
"rel" => "self",
"href" => "https://".$this->get("domain")."/account/".$username,
"type" => "application/activity+json",
),
"aliases" => "https://".$this->get("domain")."/account/".$username,
)));
}else{
$this->error("404");
}
}
}
}
?>
\ No newline at end of file
......@@ -10,8 +10,12 @@ class User{
//return(1);
}
public function init($id){
global $core;
if(!$this->initDone){
$this->data=simplexml_load_file("../data/user/".$id.".xml");
if(!$this->data){
//$core->error("404");
}
$this->id=$id;
$this->name=$this->data->name;
$this->description=$this->data->description;
......@@ -25,5 +29,71 @@ class User{
$this->init($id);
View::render("user",$this);
}
public function image($id,$type) {
global $core;
$this->init($id);
$image=file_get_contents("../data/user/".$this->id."-".$type);
if(!$image){
$core->error("404");
}
View::render("image",$image);
}
public function viewJson($id) {
$this->init($id);
View::render("json",$this->toJson());
}
public function viewActivityJson($id) {
global $core;
$this->init($id);
$activityjson=array(
"@context" => array(
"https://www.w3.org/ns/activitystreams",
),
"id" => "https://".$core->get("domain")."/account/".$this->id,
"type" => "Person",
"following" => "https://".$core->get("domain")."/account/".$this->id."/following",
"followers" => "https://".$core->get("domain")."/account/".$this->id."/followers",
"inbox" => "https://".$core->get("domain")."/account/".$this->id."/inbox",
"outbox" => "https://".$core->get("domain")."/account/".$this->id."/outbox",
"preferredUsername" => "David",
"name" => "".$this->name,
"summary" => "<p>".$this->description."</p>",
"url" => "https://".$core->get("domain")."/account/".$this->id,
"icon" => array(
"type" => "Image",
"mediaType" => "image/jpeg",
"url" => "https://".$core->get("domain")."/account/".$this->id."/avatar.jpg",
),
"image" => array(
"type" => "Image",
"mediaType" => "image/jpeg",
"url" => "https://".$core->get("domain")."/account/".$this->id."/header.jpg",
),
);
View::render("json",$activityjson);
}
public function dump($id) {
$this->init($id);
View::render("dump",$this);
}
public static function isInDatabase($id){
$data=simplexml_load_file("../data/user/".$id.".xml");
if($data){
return true;
}else{
return false;
}
}
public function toJson(){
return array(
"id" => "".$this->id,
"name" => "".$this->name,
"description" => "".$this->description,
);
}
}
?>
\ No newline at end of file
<?php
class View{
public static function render($viewName,$object) {
$view=file_get_contents("views/".$viewName.".xml");
//Transform xml to html via the base template here
preg_match_all("/\{\{([^\}]*)\}\}/", $view, $matches);
foreach($matches[1] as $i=>$m){
if($m[0]=="$"){
$view=str_replace($matches[0][$i],Secure::that($object->get(substr($m,1))),$view);
if($viewName=="raw"){
echo($object);
}else if($viewName=="dump"){
var_dump($object);
}else if($viewName=="json"){
header('Content-type: application/json;charset=utf-8');
echo(json_encode($object));
}else if($viewName=="image"){
header('Content-type: image/jpeg;charset=utf-8');
echo($object);
}else{
$view=file_get_contents("views/".$viewName.".xml");
//Transform xml to html via the base template here
preg_match_all("/\{\{([^\}]*)\}\}/", $view, $matches);
foreach($matches[1] as $i=>$m){
if($m[0]=="$"){
$view=str_replace($matches[0][$i],Secure::that($object->get(substr($m,1))),$view);
}
}
echo($view);
}
echo($view);
}
}
?>
\ No newline at end of file
......@@ -63,14 +63,20 @@
<function>User->view</function>
<params>:this</params>
</return>
<return method="get" application="json">
<function>User->viewJson</function>
<params>:this</params>
</return>
<return method="get" application="activity+json">
<function>User->viewActivityJson</function>
<params>:this</params>
</return>
<route>
<content type="application/json"></content>
<return method="get">
<function>User->viewActivityJson</function>
<params>:this</params>
</return>
</route>
<route>
<content type="application/activity+json"></content>
<return method="get">
<function>User->viewActivityJson</function>
<params>:this</params>
</return>
</route>
<route>
<content>json</content>
<return method="get">
......@@ -78,6 +84,20 @@
<params>:parent</params>
</return>
</route>
<route>
<content>activityjson</content>
<return method="get">
<function>User->viewActivityJson</function>
<params>:parent</params>
</return>
</route>
<route>
<content>dump</content>
<return method="get">
<function>User->dump</function>
<params>:parent</params>
</return>
</route>
<route>
<content>inbox</content>
<return method="get">
......@@ -106,6 +126,26 @@
<params>:parent</params>
</return>
</route>
<route>
<content>avatar.jpg</content>
<return method="get">
<function>User->image</function>
<params>
<param>:parent</param>
<param>avatar.jpg</param>
</params>
</return>
</route>
<route>
<content>header.jpg</content>
<return method="get">
<function>User->image</function>
<params>
<param>:parent</param>
<param>header.jpg</param>
</params>
</return>
</route>
</route>
</route>
</routes>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<html lang="{{$lang}}">
<head>
<meta charset="utf-8" />
<title>{{$title}}</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
<meta name="theme-color" content="#0070C0">
</head>
<body>
</body>
</html>
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment