overwork most of how api works
dont transmit handler within payload don't use oauth to gen token -- jwt instead
This commit is contained in:
		| @@ -2,6 +2,7 @@ package api | ||||
|  | ||||
| import ( | ||||
| 	"fmt" | ||||
| 	"openmediacenter/apiGo/api/api" | ||||
| 	"openmediacenter/apiGo/api/types" | ||||
| 	"openmediacenter/apiGo/database" | ||||
| ) | ||||
| @@ -23,9 +24,9 @@ func getActorsFromDB() { | ||||
| 	 * @apiSuccess {string} .Name Actor Name | ||||
| 	 * @apiSuccess {string} .Thumbnail Portrait Thumbnail | ||||
| 	 */ | ||||
| 	AddHandler("getAllActors", ActorNode, func(info *HandlerInfo) []byte { | ||||
| 	api.AddHandler("getAllActors", api.ActorNode, api.PermUser, func(context api.Context) { | ||||
| 		query := "SELECT actor_id, name, thumbnail FROM actors" | ||||
| 		return jsonify(readActorsFromResultset(database.Query(query))) | ||||
| 		context.Json(readActorsFromResultset(database.Query(query))) | ||||
| 	}) | ||||
|  | ||||
| 	/** | ||||
| @@ -41,20 +42,21 @@ func getActorsFromDB() { | ||||
| 	 * @apiSuccess {string} .Name Actor Name | ||||
| 	 * @apiSuccess {string} .Thumbnail Portrait Thumbnail | ||||
| 	 */ | ||||
| 	AddHandler("getActorsOfVideo", ActorNode, func(info *HandlerInfo) []byte { | ||||
| 	api.AddHandler("getActorsOfVideo", api.ActorNode, api.PermUser, func(context api.Context) { | ||||
| 		var args struct { | ||||
| 			MovieId int | ||||
| 		} | ||||
| 		if err := FillStruct(&args, info.Data); err != nil { | ||||
| 			fmt.Println(err.Error()) | ||||
| 			return nil | ||||
| 		err := api.DecodeRequest(context.GetRequest(), &args) | ||||
| 		if err != nil { | ||||
| 			context.Text("failed to decode request") | ||||
| 			return | ||||
| 		} | ||||
|  | ||||
| 		query := fmt.Sprintf(`SELECT a.actor_id, name, thumbnail FROM actors_videos | ||||
| 									JOIN actors a on actors_videos.actor_id = a.actor_id | ||||
| 									WHERE actors_videos.video_id=%d`, args.MovieId) | ||||
|  | ||||
| 		return jsonify(readActorsFromResultset(database.Query(query))) | ||||
| 		context.Json(readActorsFromResultset(database.Query(query))) | ||||
| 	}) | ||||
|  | ||||
| 	/** | ||||
| @@ -74,13 +76,15 @@ func getActorsFromDB() { | ||||
| 	 * @apiSuccess {string} Info.Name Actor Name | ||||
| 	 * @apiSuccess {string} Info.Thumbnail Actor Thumbnail | ||||
| 	 */ | ||||
| 	AddHandler("getActorInfo", ActorNode, func(info *HandlerInfo) []byte { | ||||
| 	api.AddHandler("getActorInfo", api.ActorNode, api.PermUser, func(context api.Context) { | ||||
| 		var args struct { | ||||
| 			ActorId int | ||||
| 		} | ||||
| 		if err := FillStruct(&args, info.Data); err != nil { | ||||
| 			fmt.Println(err.Error()) | ||||
| 			return nil | ||||
|  | ||||
| 		err := api.DecodeRequest(context.GetRequest(), &args) | ||||
| 		if err != nil { | ||||
| 			context.Error("unable to decode request") | ||||
| 			return | ||||
| 		} | ||||
|  | ||||
| 		query := fmt.Sprintf(`SELECT movie_id, movie_name FROM actors_videos | ||||
| @@ -99,7 +103,7 @@ func getActorsFromDB() { | ||||
| 			Info:   actor, | ||||
| 		} | ||||
|  | ||||
| 		return jsonify(result) | ||||
| 		context.Json(result) | ||||
| 	}) | ||||
| } | ||||
|  | ||||
| @@ -112,19 +116,17 @@ func saveActorsToDB() { | ||||
| 	 * | ||||
| 	 * @apiParam {string} ActorName Name of new Actor | ||||
| 	 * | ||||
| 	 * @apiSuccess {string} result 'success' if successfully or error message if not | ||||
| 	 * @apiSuccess {string} result 'success' if successfully or Error message if not | ||||
| 	 */ | ||||
| 	AddHandler("createActor", ActorNode, func(info *HandlerInfo) []byte { | ||||
| 	api.AddHandler("createActor", api.ActorNode, api.PermUser, func(context api.Context) { | ||||
| 		var args struct { | ||||
| 			ActorName string | ||||
| 		} | ||||
| 		if err := FillStruct(&args, info.Data); err != nil { | ||||
| 			fmt.Println(err.Error()) | ||||
| 			return nil | ||||
| 		} | ||||
| 		api.DecodeRequest(context.GetRequest(), &args) | ||||
|  | ||||
| 		query := "INSERT IGNORE INTO actors (name) VALUES (?)" | ||||
| 		return database.SuccessQuery(query, args.ActorName) | ||||
| 		// todo bit ugly | ||||
| 		context.Text(string(database.SuccessQuery(query, args.ActorName))) | ||||
| 	}) | ||||
|  | ||||
| 	/** | ||||
| @@ -136,19 +138,20 @@ func saveActorsToDB() { | ||||
| 	 * @apiParam {int} ActorId Id of Actor | ||||
| 	 * @apiParam {int} MovieId Id of Movie to add to | ||||
| 	 * | ||||
| 	 * @apiSuccess {string} result 'success' if successfully or error message if not | ||||
| 	 * @apiSuccess {string} result 'success' if successfully or Error message if not | ||||
| 	 */ | ||||
| 	AddHandler("addActorToVideo", ActorNode, func(info *HandlerInfo) []byte { | ||||
| 	api.AddHandler("addActorToVideo", api.ActorNode, api.PermUser, func(context api.Context) { | ||||
| 		var args struct { | ||||
| 			ActorId int | ||||
| 			MovieId int | ||||
| 		} | ||||
| 		if err := FillStruct(&args, info.Data); err != nil { | ||||
| 			fmt.Println(err.Error()) | ||||
| 			return nil | ||||
| 		err := api.DecodeRequest(context.GetRequest(), &args) | ||||
| 		if err != nil { | ||||
| 			context.Error("unable to decode request") | ||||
| 			return | ||||
| 		} | ||||
|  | ||||
| 		query := fmt.Sprintf("INSERT IGNORE INTO actors_videos (actor_id, video_id) VALUES (%d,%d)", args.ActorId, args.MovieId) | ||||
| 		return database.SuccessQuery(query) | ||||
| 		context.Text(string(database.SuccessQuery(query))) | ||||
| 	}) | ||||
| } | ||||
|   | ||||
| @@ -1,113 +0,0 @@ | ||||
| package api | ||||
|  | ||||
| import ( | ||||
| 	"bytes" | ||||
| 	"encoding/json" | ||||
| 	"fmt" | ||||
| 	"gopkg.in/oauth2.v3" | ||||
| 	"net/http" | ||||
| 	"openmediacenter/apiGo/api/oauth" | ||||
| ) | ||||
|  | ||||
| const APIPREFIX = "/api" | ||||
|  | ||||
| const ( | ||||
| 	VideoNode    = iota | ||||
| 	TagNode      = iota | ||||
| 	SettingsNode = iota | ||||
| 	ActorNode    = iota | ||||
| 	TVShowNode   = iota | ||||
| ) | ||||
|  | ||||
| type HandlerInfo struct { | ||||
| 	ID    string | ||||
| 	Token string | ||||
| 	Data  map[string]interface{} | ||||
| } | ||||
|  | ||||
| type actionStruct struct { | ||||
| 	Action string | ||||
| } | ||||
|  | ||||
| type Handler struct { | ||||
| 	action  string | ||||
| 	handler func(info *HandlerInfo) []byte | ||||
| 	apiNode int | ||||
| } | ||||
|  | ||||
| var handlers = make(map[string]Handler) | ||||
|  | ||||
| func AddHandler(action string, apiNode int, h func(info *HandlerInfo) []byte) { | ||||
| 	// append new handler to the handlers | ||||
| 	handlers[fmt.Sprintf("%s/%d", action, apiNode)] = Handler{action, h, apiNode} | ||||
| } | ||||
|  | ||||
| func ServerInit() { | ||||
| 	http.Handle(APIPREFIX+"/video", oauth.ValidateToken(handlefunc, VideoNode)) | ||||
| 	http.Handle(APIPREFIX+"/tags", oauth.ValidateToken(handlefunc, TagNode)) | ||||
| 	http.Handle(APIPREFIX+"/settings", oauth.ValidateToken(handlefunc, SettingsNode)) | ||||
| 	http.Handle(APIPREFIX+"/actor", oauth.ValidateToken(handlefunc, ActorNode)) | ||||
| 	http.Handle(APIPREFIX+"/tvshow", oauth.ValidateToken(handlefunc, TVShowNode)) | ||||
|  | ||||
| 	// initialize oauth service and add corresponding auth routes | ||||
| 	oauth.InitOAuth() | ||||
| } | ||||
|  | ||||
| func handleAPICall(action string, requestBody string, apiNode int, info *HandlerInfo) []byte { | ||||
| 	handler, ok := handlers[fmt.Sprintf("%s/%d", action, apiNode)] | ||||
| 	if !ok { | ||||
| 		// handler doesn't exist! | ||||
| 		fmt.Printf("no handler found for Action: %d/%s\n", apiNode, action) | ||||
| 		return nil | ||||
| 	} | ||||
|  | ||||
| 	// check if info even exists | ||||
| 	if info == nil { | ||||
| 		info = &HandlerInfo{} | ||||
| 	} | ||||
|  | ||||
| 	// parse the arguments | ||||
| 	var args map[string]interface{} | ||||
| 	err := json.Unmarshal([]byte(requestBody), &args) | ||||
|  | ||||
| 	if err != nil { | ||||
| 		fmt.Printf("failed to decode arguments of action %s :: %s\n", action, requestBody) | ||||
| 	} else { | ||||
| 		// check if map has an action | ||||
| 		if _, ok := args["action"]; ok { | ||||
| 			delete(args, "action") | ||||
| 		} | ||||
|  | ||||
| 		info.Data = args | ||||
| 	} | ||||
|  | ||||
| 	// call the handler | ||||
| 	return handler.handler(info) | ||||
| } | ||||
|  | ||||
| func handlefunc(rw http.ResponseWriter, req *http.Request, node int, tokenInfo *oauth2.TokenInfo) { | ||||
| 	// only allow post requests | ||||
| 	if req.Method != "POST" { | ||||
| 		return | ||||
| 	} | ||||
|  | ||||
| 	buf := new(bytes.Buffer) | ||||
| 	buf.ReadFrom(req.Body) | ||||
| 	body := buf.String() | ||||
|  | ||||
| 	var t actionStruct | ||||
| 	err := json.Unmarshal([]byte(body), &t) | ||||
| 	if err != nil { | ||||
| 		fmt.Println("failed to read action from request! :: " + body) | ||||
| 	} | ||||
|  | ||||
| 	// load userid from received token object | ||||
| 	id := (*tokenInfo).GetClientID() | ||||
|  | ||||
| 	userinfo := &HandlerInfo{ | ||||
| 		ID:    id, | ||||
| 		Token: (*tokenInfo).GetCode(), | ||||
| 	} | ||||
|  | ||||
| 	rw.Write(handleAPICall(t.Action, body, node, userinfo)) | ||||
| } | ||||
| @@ -2,10 +2,8 @@ package api | ||||
|  | ||||
| import ( | ||||
| 	"database/sql" | ||||
| 	"encoding/json" | ||||
| 	"fmt" | ||||
| 	"openmediacenter/apiGo/api/types" | ||||
| 	"reflect" | ||||
| ) | ||||
|  | ||||
| // MovieId - MovieName : pay attention to the order! | ||||
| @@ -33,7 +31,7 @@ func readTagsFromResultset(rows *sql.Rows) []types.Tag { | ||||
| 		var tag types.Tag | ||||
| 		err := rows.Scan(&tag.TagId, &tag.TagName) | ||||
| 		if err != nil { | ||||
| 			panic(err.Error()) // proper error handling instead of panic in your app | ||||
| 			panic(err.Error()) // proper Error handling instead of panic in your app | ||||
| 		} | ||||
| 		result = append(result, tag) | ||||
| 	} | ||||
| @@ -54,7 +52,7 @@ func readActorsFromResultset(rows *sql.Rows) []types.Actor { | ||||
| 			actor.Thumbnail = string(thumbnail) | ||||
| 		} | ||||
| 		if err != nil { | ||||
| 			panic(err.Error()) // proper error handling instead of panic in your app | ||||
| 			panic(err.Error()) // proper Error handling instead of panic in your app | ||||
| 		} | ||||
| 		result = append(result, actor) | ||||
| 	} | ||||
| @@ -70,7 +68,7 @@ func readTVshowsFromResultset(rows *sql.Rows) []types.TVShow { | ||||
| 		var vid types.TVShow | ||||
| 		err := rows.Scan(&vid.Id, &vid.Name) | ||||
| 		if err != nil { | ||||
| 			panic(err.Error()) // proper error handling instead of panic in your app | ||||
| 			panic(err.Error()) // proper Error handling instead of panic in your app | ||||
| 		} | ||||
| 		result = append(result, vid) | ||||
| 	} | ||||
| @@ -78,54 +76,3 @@ func readTVshowsFromResultset(rows *sql.Rows) []types.TVShow { | ||||
|  | ||||
| 	return result | ||||
| } | ||||
|  | ||||
| func jsonify(v interface{}) []byte { | ||||
| 	// jsonify results | ||||
| 	str, err := json.Marshal(v) | ||||
| 	if err != nil { | ||||
| 		fmt.Println("Error while Jsonifying return object: " + err.Error()) | ||||
| 	} | ||||
| 	return str | ||||
| } | ||||
|  | ||||
| // setField set a specific field of an object with an object provided | ||||
| func setField(obj interface{}, name string, value interface{}) error { | ||||
| 	structValue := reflect.ValueOf(obj).Elem() | ||||
| 	structFieldValue := structValue.FieldByName(name) | ||||
|  | ||||
| 	if !structFieldValue.IsValid() { | ||||
| 		return fmt.Errorf("no such field: %s in obj", name) | ||||
| 	} | ||||
|  | ||||
| 	if !structFieldValue.CanSet() { | ||||
| 		return fmt.Errorf("cannot set %s field value", name) | ||||
| 	} | ||||
|  | ||||
| 	structFieldType := structFieldValue.Type() | ||||
| 	val := reflect.ValueOf(value) | ||||
|  | ||||
| 	if structFieldType != val.Type() { | ||||
| 		if val.Type().ConvertibleTo(structFieldType) { | ||||
| 			// if type is convertible - convert and set | ||||
| 			structFieldValue.Set(val.Convert(structFieldType)) | ||||
| 		} else { | ||||
| 			return fmt.Errorf("provided value %s type didn't match obj field type and isn't convertible", name) | ||||
| 		} | ||||
| 	} else { | ||||
| 		// set value if type is the same | ||||
| 		structFieldValue.Set(val) | ||||
| 	} | ||||
|  | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| // FillStruct fill a custom struct with objects of a map | ||||
| func FillStruct(i interface{}, m map[string]interface{}) error { | ||||
| 	for k, v := range m { | ||||
| 		err := setField(i, k, v) | ||||
| 		if err != nil { | ||||
| 			return err | ||||
| 		} | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
|   | ||||
| @@ -1,8 +1,7 @@ | ||||
| package api | ||||
|  | ||||
| import ( | ||||
| 	"encoding/json" | ||||
| 	"fmt" | ||||
| 	"openmediacenter/apiGo/api/api" | ||||
| 	"openmediacenter/apiGo/api/types" | ||||
| 	"openmediacenter/apiGo/config" | ||||
| 	"openmediacenter/apiGo/database" | ||||
| @@ -38,7 +37,7 @@ func getSettingsFromDB() { | ||||
| 	 * @apiSuccess {uint32} Sizes.DifferentTags number of different tags available | ||||
| 	 * @apiSuccess {uint32} Sizes.TagsAdded number of different tags added to videos | ||||
| 	 */ | ||||
| 	AddHandler("loadGeneralSettings", SettingsNode, func(info *HandlerInfo) []byte { | ||||
| 	api.AddHandler("loadGeneralSettings", api.SettingsNode, api.PermUser, func(context api.Context) { | ||||
| 		result, _, sizes := database.GetSettings() | ||||
|  | ||||
| 		var ret = struct { | ||||
| @@ -48,7 +47,7 @@ func getSettingsFromDB() { | ||||
| 			Settings: &result, | ||||
| 			Sizes:    &sizes, | ||||
| 		} | ||||
| 		return jsonify(ret) | ||||
| 		context.Json(ret) | ||||
| 	}) | ||||
|  | ||||
| 	/** | ||||
| @@ -64,7 +63,7 @@ func getSettingsFromDB() { | ||||
| 	 * @apiSuccess {bool} DarkMode Darkmode enabled? | ||||
| 	 * @apiSuccess {bool} TVShowEnabled is are TVShows enabled | ||||
| 	 */ | ||||
| 	AddHandler("loadInitialData", SettingsNode, func(info *HandlerInfo) []byte { | ||||
| 	api.AddHandler("loadInitialData", api.SettingsNode, api.PermUser, func(context api.Context) { | ||||
| 		sett := settings.LoadSettings() | ||||
|  | ||||
| 		type InitialDataTypeResponse struct { | ||||
| @@ -93,8 +92,7 @@ func getSettingsFromDB() { | ||||
| 			FullDeleteEnabled: config.GetConfig().Features.FullyDeletableVideos, | ||||
| 		} | ||||
|  | ||||
| 		str, _ := json.Marshal(res) | ||||
| 		return str | ||||
| 		context.Json(res) | ||||
| 	}) | ||||
| } | ||||
|  | ||||
| @@ -112,13 +110,14 @@ func saveSettingsToDB() { | ||||
| 	 * @apiParam {bool} TMDBGrabbing TMDB grabbing support to grab tag info and thumbnails | ||||
| 	 * @apiParam {bool} DarkMode Darkmode enabled? | ||||
| 	 * | ||||
| 	 * @apiSuccess {string} result 'success' if successfully or error message if not | ||||
| 	 * @apiSuccess {string} result 'success' if successfully or Error message if not | ||||
| 	 */ | ||||
| 	AddHandler("saveGeneralSettings", SettingsNode, func(info *HandlerInfo) []byte { | ||||
| 	api.AddHandler("saveGeneralSettings", api.SettingsNode, api.PermUser, func(context api.Context) { | ||||
| 		var args types.SettingsType | ||||
| 		if err := FillStruct(&args, info.Data); err != nil { | ||||
| 			fmt.Println(err.Error()) | ||||
| 			return nil | ||||
| 		err := api.DecodeRequest(context.GetRequest(), &args) | ||||
| 		if err != nil { | ||||
| 			context.Error("unable to decode arguments") | ||||
| 			return | ||||
| 		} | ||||
|  | ||||
| 		query := ` | ||||
| @@ -130,9 +129,10 @@ func saveSettingsToDB() { | ||||
|                         TMDB_grabbing=?,  | ||||
|                         DarkMode=? | ||||
|                     WHERE 1` | ||||
| 		return database.SuccessQuery(query, | ||||
| 		// todo avoid conversion | ||||
| 		context.Text(string(database.SuccessQuery(query, | ||||
| 			args.VideoPath, args.EpisodePath, args.Password, | ||||
| 			args.MediacenterName, args.TMDBGrabbing, args.DarkMode) | ||||
| 			args.MediacenterName, args.TMDBGrabbing, args.DarkMode))) | ||||
| 	}) | ||||
| } | ||||
|  | ||||
| @@ -144,11 +144,11 @@ func reIndexHandling() { | ||||
| 	 * @apiName startReindex | ||||
| 	 * @apiGroup Settings | ||||
| 	 * | ||||
| 	 * @apiSuccess {string} result 'success' if successfully or error message if not | ||||
| 	 * @apiSuccess {string} result 'success' if successfully or Error message if not | ||||
| 	 */ | ||||
| 	AddHandler("startReindex", SettingsNode, func(info *HandlerInfo) []byte { | ||||
| 	api.AddHandler("startReindex", api.SettingsNode, api.PermUser, func(context api.Context) { | ||||
| 		videoparser.StartReindex() | ||||
| 		return database.ManualSuccessResponse(nil) | ||||
| 		context.Text(string(database.ManualSuccessResponse(nil))) | ||||
| 	}) | ||||
|  | ||||
| 	/** | ||||
| @@ -157,11 +157,11 @@ func reIndexHandling() { | ||||
| 	 * @apiName startTVShowReindex | ||||
| 	 * @apiGroup Settings | ||||
| 	 * | ||||
| 	 * @apiSuccess {string} result 'success' if successfully or error message if not | ||||
| 	 * @apiSuccess {string} result 'success' if successfully or Error message if not | ||||
| 	 */ | ||||
| 	AddHandler("startTVShowReindex", SettingsNode, func(info *HandlerInfo) []byte { | ||||
| 	api.AddHandler("startTVShowReindex", api.SettingsNode, api.PermUser, func(context api.Context) { | ||||
| 		videoparser.StartTVShowReindex() | ||||
| 		return database.ManualSuccessResponse(nil) | ||||
| 		context.Text(string(database.ManualSuccessResponse(nil))) | ||||
| 	}) | ||||
|  | ||||
| 	/** | ||||
| @@ -170,8 +170,7 @@ func reIndexHandling() { | ||||
| 	 * @apiName cleanupGravity | ||||
| 	 * @apiGroup Settings | ||||
| 	 */ | ||||
| 	AddHandler("cleanupGravity", SettingsNode, func(info *HandlerInfo) []byte { | ||||
| 	api.AddHandler("cleanupGravity", api.SettingsNode, api.PermUser, func(context api.Context) { | ||||
| 		videoparser.StartCleanup() | ||||
| 		return nil | ||||
| 	}) | ||||
| } | ||||
|   | ||||
| @@ -2,6 +2,7 @@ package api | ||||
|  | ||||
| import ( | ||||
| 	"fmt" | ||||
| 	"openmediacenter/apiGo/api/api" | ||||
| 	"openmediacenter/apiGo/config" | ||||
| 	"openmediacenter/apiGo/database" | ||||
| ) | ||||
| @@ -22,10 +23,10 @@ func AddTvshowHandlers() { | ||||
| 	 * @apiSuccess {uint32} .Id tvshow id | ||||
| 	 * @apiSuccess {string} .Name tvshow name | ||||
| 	 */ | ||||
| 	AddHandler("getTVShows", TVShowNode, func(info *HandlerInfo) []byte { | ||||
| 	api.AddHandler("getTVShows", api.TVShowNode, api.PermUser, func(context api.Context) { | ||||
| 		query := "SELECT id, name FROM tvshow" | ||||
| 		rows := database.Query(query) | ||||
| 		return jsonify(readTVshowsFromResultset(rows)) | ||||
| 		context.Json(readTVshowsFromResultset(rows)) | ||||
| 	}) | ||||
|  | ||||
| 	/** | ||||
| @@ -42,13 +43,14 @@ func AddTvshowHandlers() { | ||||
| 	 * @apiSuccess {uint8} .Season Season number | ||||
| 	 * @apiSuccess {uint8} .Episode Episode number | ||||
| 	 */ | ||||
| 	AddHandler("getEpisodes", TVShowNode, func(info *HandlerInfo) []byte { | ||||
| 	api.AddHandler("getEpisodes", api.TVShowNode, api.PermUser, func(context api.Context) { | ||||
| 		var args struct { | ||||
| 			ShowID uint32 | ||||
| 		} | ||||
| 		if err := FillStruct(&args, info.Data); err != nil { | ||||
| 			fmt.Println(err.Error()) | ||||
| 			return nil | ||||
| 		err := api.DecodeRequest(context.GetRequest(), &args) | ||||
| 		if err != nil { | ||||
| 			context.Text("unable to decode request") | ||||
| 			return | ||||
| 		} | ||||
|  | ||||
| 		query := fmt.Sprintf("SELECT id, name, season, episode FROM tvshow_episodes WHERE tvshow_id=%d", args.ShowID) | ||||
| @@ -73,7 +75,7 @@ func AddTvshowHandlers() { | ||||
| 			episodes = append(episodes, ep) | ||||
| 		} | ||||
|  | ||||
| 		return jsonify(episodes) | ||||
| 		context.Json(episodes) | ||||
| 	}) | ||||
|  | ||||
| 	/** | ||||
| @@ -90,13 +92,14 @@ func AddTvshowHandlers() { | ||||
| 	 * @apiSuccess {uint8} Episode Episode number | ||||
| 	 * @apiSuccess {string} Path webserver path of video file | ||||
| 	 */ | ||||
| 	AddHandler("loadEpisode", TVShowNode, func(info *HandlerInfo) []byte { | ||||
| 	api.AddHandler("loadEpisode", api.TVShowNode, api.PermUser, func(context api.Context) { | ||||
| 		var args struct { | ||||
| 			ID uint32 | ||||
| 		} | ||||
| 		if err := FillStruct(&args, info.Data); err != nil { | ||||
| 			fmt.Println(err.Error()) | ||||
| 			return nil | ||||
| 		err := api.DecodeRequest(context.GetRequest(), &args) | ||||
| 		if err != nil { | ||||
| 			context.Text("unable to decode argument") | ||||
| 			return | ||||
| 		} | ||||
|  | ||||
| 		query := fmt.Sprintf(` | ||||
| @@ -116,15 +119,16 @@ WHERE tvshow_episodes.id=%d`, args.ID) | ||||
| 		var filename string | ||||
| 		var foldername string | ||||
|  | ||||
| 		err := row.Scan(&ret.Name, &ret.Season, &ret.TVShowID, &ret.Episode, &filename, &foldername) | ||||
| 		err = row.Scan(&ret.Name, &ret.Season, &ret.TVShowID, &ret.Episode, &filename, &foldername) | ||||
| 		if err != nil { | ||||
| 			fmt.Println(err.Error()) | ||||
| 			return nil | ||||
| 			context.Error(err.Error()) | ||||
| 			return | ||||
| 		} | ||||
|  | ||||
| 		ret.Path = foldername + "/" + filename | ||||
|  | ||||
| 		return jsonify(ret) | ||||
| 		context.Json(ret) | ||||
| 	}) | ||||
|  | ||||
| 	/** | ||||
| @@ -137,25 +141,26 @@ WHERE tvshow_episodes.id=%d`, args.ID) | ||||
| 	 * | ||||
| 	 * @apiSuccess {string} . Base64 encoded Thubnail | ||||
| 	 */ | ||||
| 	AddHandler("readThumbnail", TVShowNode, func(info *HandlerInfo) []byte { | ||||
| 	api.AddHandler("readThumbnail", api.TVShowNode, api.PermUser, func(context api.Context) { | ||||
| 		var args struct { | ||||
| 			Id int | ||||
| 		} | ||||
| 		if err := FillStruct(&args, info.Data); err != nil { | ||||
| 			fmt.Println(err.Error()) | ||||
| 			return nil | ||||
| 		err := api.DecodeRequest(context.GetRequest(), &args) | ||||
| 		if err != nil { | ||||
| 			context.Text("unable to decode request") | ||||
| 			return | ||||
| 		} | ||||
|  | ||||
| 		var pic []byte | ||||
|  | ||||
| 		query := fmt.Sprintf("SELECT thumbnail FROM tvshow WHERE id=%d", args.Id) | ||||
|  | ||||
| 		err := database.QueryRow(query).Scan(&pic) | ||||
| 		err = database.QueryRow(query).Scan(&pic) | ||||
| 		if err != nil { | ||||
| 			fmt.Printf("the thumbnail of movie id %d couldn't be found", args.Id) | ||||
| 			return nil | ||||
| 			return | ||||
| 		} | ||||
|  | ||||
| 		return pic | ||||
| 		context.Text(string(pic)) | ||||
| 	}) | ||||
| } | ||||
|   | ||||
| @@ -2,6 +2,7 @@ package api | ||||
|  | ||||
| import ( | ||||
| 	"fmt" | ||||
| 	"openmediacenter/apiGo/api/api" | ||||
| 	"openmediacenter/apiGo/database" | ||||
| 	"regexp" | ||||
| ) | ||||
| @@ -22,16 +23,17 @@ func deleteFromDB() { | ||||
| 	 * @apiParam {bool} [Force] force delete tag with its constraints | ||||
| 	 * @apiParam {int} TagId id of tag to delete | ||||
| 	 * | ||||
| 	 * @apiSuccess {string} result 'success' if successfully or error message if not | ||||
| 	 * @apiSuccess {string} result 'success' if successfully or Error message if not | ||||
| 	 */ | ||||
| 	AddHandler("deleteTag", TagNode, func(info *HandlerInfo) []byte { | ||||
| 	api.AddHandler("deleteTag", api.TagNode, api.PermUser, func(context api.Context) { | ||||
| 		var args struct { | ||||
| 			TagId int | ||||
| 			Force bool | ||||
| 		} | ||||
| 		if err := FillStruct(&args, info.Data); err != nil { | ||||
| 			fmt.Println(err.Error()) | ||||
| 			return nil | ||||
| 		err := api.DecodeRequest(context.GetRequest(), &args) | ||||
| 		if err != nil { | ||||
| 			context.Text("unable to decode request") | ||||
| 			return | ||||
| 		} | ||||
|  | ||||
| 		// delete key constraints first | ||||
| @@ -41,23 +43,24 @@ func deleteFromDB() { | ||||
|  | ||||
| 			// respond only if result not successful | ||||
| 			if err != nil { | ||||
| 				return database.ManualSuccessResponse(err) | ||||
| 				context.Text(string(database.ManualSuccessResponse(err))) | ||||
| 				return | ||||
| 			} | ||||
| 		} | ||||
|  | ||||
| 		query := fmt.Sprintf("DELETE FROM tags WHERE tag_id=%d", args.TagId) | ||||
| 		err := database.Edit(query) | ||||
| 		err = database.Edit(query) | ||||
|  | ||||
| 		if err == nil { | ||||
| 			// return if successful | ||||
| 			return database.ManualSuccessResponse(err) | ||||
| 			context.Text(string(database.ManualSuccessResponse(err))) | ||||
| 		} else { | ||||
| 			// check with regex if its the key constraint error | ||||
| 			// check with regex if its the key constraint Error | ||||
| 			r := regexp.MustCompile("^.*a foreign key constraint fails.*$") | ||||
| 			if r.MatchString(err.Error()) { | ||||
| 				return database.ManualSuccessResponse(fmt.Errorf("not empty tag")) | ||||
| 				context.Text(string(database.ManualSuccessResponse(fmt.Errorf("not empty tag")))) | ||||
| 			} else { | ||||
| 				return database.ManualSuccessResponse(err) | ||||
| 				context.Text(string(database.ManualSuccessResponse(err))) | ||||
| 			} | ||||
| 		} | ||||
| 	}) | ||||
| @@ -74,9 +77,9 @@ func getFromDB() { | ||||
| 	 * @apiSuccess {uint32} TagId | ||||
| 	 * @apiSuccess {string} TagName name of the Tag | ||||
| 	 */ | ||||
| 	AddHandler("getAllTags", TagNode, func(info *HandlerInfo) []byte { | ||||
| 	api.AddHandler("getAllTags", api.TagNode, api.PermUser, func(context api.Context) { | ||||
| 		query := "SELECT tag_id,tag_name from tags" | ||||
| 		return jsonify(readTagsFromResultset(database.Query(query))) | ||||
| 		context.Json(readTagsFromResultset(database.Query(query))) | ||||
| 	}) | ||||
| } | ||||
|  | ||||
| @@ -89,19 +92,20 @@ func addToDB() { | ||||
| 	 * | ||||
| 	 * @apiParam {string} TagName name of the tag | ||||
| 	 * | ||||
| 	 * @apiSuccess {string} result 'success' if successfully or error message if not | ||||
| 	 * @apiSuccess {string} result 'success' if successfully or Error message if not | ||||
| 	 */ | ||||
| 	AddHandler("createTag", TagNode, func(info *HandlerInfo) []byte { | ||||
| 	api.AddHandler("createTag", api.TagNode, api.PermUser, func(context api.Context) { | ||||
| 		var args struct { | ||||
| 			TagName string | ||||
| 		} | ||||
| 		if err := FillStruct(&args, info.Data); err != nil { | ||||
| 			fmt.Println(err.Error()) | ||||
| 			return nil | ||||
| 		err := api.DecodeRequest(context.GetRequest(), &args) | ||||
| 		if err != nil { | ||||
| 			context.Text("unable to decode request") | ||||
| 			return | ||||
| 		} | ||||
|  | ||||
| 		query := "INSERT IGNORE INTO tags (tag_name) VALUES (?)" | ||||
| 		return database.SuccessQuery(query, args.TagName) | ||||
| 		context.Text(string(database.SuccessQuery(query, args.TagName))) | ||||
| 	}) | ||||
|  | ||||
| 	/** | ||||
| @@ -113,19 +117,20 @@ func addToDB() { | ||||
| 	 * @apiParam {int} TagId Tag id to add to video | ||||
| 	 * @apiParam {int} MovieId Video Id of video to add tag to | ||||
| 	 * | ||||
| 	 * @apiSuccess {string} result 'success' if successfully or error message if not | ||||
| 	 * @apiSuccess {string} result 'success' if successfully or Error message if not | ||||
| 	 */ | ||||
| 	AddHandler("addTag", TagNode, func(info *HandlerInfo) []byte { | ||||
| 	api.AddHandler("addTag", api.TagNode, api.PermUser, func(context api.Context) { | ||||
| 		var args struct { | ||||
| 			MovieId int | ||||
| 			TagId   int | ||||
| 		} | ||||
| 		if err := FillStruct(&args, info.Data); err != nil { | ||||
| 			fmt.Println(err.Error()) | ||||
| 			return nil | ||||
| 		err := api.DecodeRequest(context.GetRequest(), &args) | ||||
| 		if err != nil { | ||||
| 			context.Text("unable to decode request") | ||||
| 			return | ||||
| 		} | ||||
|  | ||||
| 		query := "INSERT IGNORE INTO video_tags(tag_id, video_id) VALUES (?,?)" | ||||
| 		return database.SuccessQuery(query, args.TagId, args.MovieId) | ||||
| 		context.Text(string(database.SuccessQuery(query, args.TagId, args.MovieId))) | ||||
| 	}) | ||||
| } | ||||
|   | ||||
| @@ -1,9 +1,9 @@ | ||||
| package api | ||||
|  | ||||
| import ( | ||||
| 	"encoding/json" | ||||
| 	"fmt" | ||||
| 	"net/url" | ||||
| 	"openmediacenter/apiGo/api/api" | ||||
| 	"openmediacenter/apiGo/api/types" | ||||
| 	"openmediacenter/apiGo/config" | ||||
| 	"openmediacenter/apiGo/database" | ||||
| @@ -31,14 +31,15 @@ func getVideoHandlers() { | ||||
| 	 * @apiSuccess {String} Videos.MovieName  Name of video | ||||
| 	 * @apiSuccess {String} TagName Name of the Tag returned | ||||
| 	 */ | ||||
| 	AddHandler("getMovies", VideoNode, func(info *HandlerInfo) []byte { | ||||
| 	api.AddHandler("getMovies", api.VideoNode, api.PermUser, func(context api.Context) { | ||||
| 		var args struct { | ||||
| 			Tag  uint32 | ||||
| 			Sort uint8 | ||||
| 		} | ||||
| 		if err := FillStruct(&args, info.Data); err != nil { | ||||
| 			fmt.Println(err.Error()) | ||||
| 			return nil | ||||
| 		err := api.DecodeRequest(context.GetRequest(), &args) | ||||
| 		if err != nil { | ||||
| 			context.Text("unable to decode request") | ||||
| 			return | ||||
| 		} | ||||
|  | ||||
| 		const ( | ||||
| @@ -92,24 +93,22 @@ func getVideoHandlers() { | ||||
| 			var vid types.VideoUnloadedType | ||||
| 			err := rows.Scan(&vid.MovieId, &vid.MovieName, &name) | ||||
| 			if err != nil { | ||||
| 				return nil | ||||
| 				return | ||||
| 			} | ||||
| 			vids = append(vids, vid) | ||||
| 		} | ||||
| 		if rows.Close() != nil { | ||||
| 			return nil | ||||
| 			return | ||||
| 		} | ||||
|  | ||||
| 		// if the tag id doesn't exist the query won't return a name | ||||
| 		if name == "" { | ||||
| 			return nil | ||||
| 			return | ||||
| 		} | ||||
|  | ||||
| 		result.Videos = vids | ||||
| 		result.TagName = name | ||||
| 		// jsonify results | ||||
| 		str, _ := json.Marshal(result) | ||||
| 		return str | ||||
| 		context.Json(result) | ||||
| 	}) | ||||
|  | ||||
| 	/** | ||||
| @@ -122,26 +121,27 @@ func getVideoHandlers() { | ||||
| 	 * | ||||
| 	 * @apiSuccess {string} . Base64 encoded Thubnail | ||||
| 	 */ | ||||
| 	AddHandler("readThumbnail", VideoNode, func(info *HandlerInfo) []byte { | ||||
| 	api.AddHandler("readThumbnail", api.VideoNode, api.PermUser, func(context api.Context) { | ||||
| 		var args struct { | ||||
| 			Movieid int | ||||
| 		} | ||||
| 		if err := FillStruct(&args, info.Data); err != nil { | ||||
| 			fmt.Println(err.Error()) | ||||
| 			return nil | ||||
| 		err := api.DecodeRequest(context.GetRequest(), &args) | ||||
| 		if err != nil { | ||||
| 			context.Text("unable to decode request") | ||||
| 			return | ||||
| 		} | ||||
|  | ||||
| 		var pic []byte | ||||
|  | ||||
| 		query := fmt.Sprintf("SELECT thumbnail FROM videos WHERE movie_id=%d", args.Movieid) | ||||
|  | ||||
| 		err := database.QueryRow(query).Scan(&pic) | ||||
| 		err = database.QueryRow(query).Scan(&pic) | ||||
| 		if err != nil { | ||||
| 			fmt.Printf("the thumbnail of movie id %d couldn't be found", args.Movieid) | ||||
| 			return nil | ||||
| 			return | ||||
| 		} | ||||
|  | ||||
| 		return pic | ||||
| 		context.Text(string(pic)) | ||||
| 	}) | ||||
|  | ||||
| 	/** | ||||
| @@ -160,13 +160,13 @@ func getVideoHandlers() { | ||||
| 	 * @apiSuccess {string} Videos.MovieName Video Name | ||||
| 	 * @apiSuccess {int} Videos.MovieId Video ID | ||||
| 	 */ | ||||
| 	AddHandler("getRandomMovies", VideoNode, func(info *HandlerInfo) []byte { | ||||
| 	api.AddHandler("getRandomMovies", api.VideoNode, api.PermUser, func(context api.Context) { | ||||
| 		var args struct { | ||||
| 			Number int | ||||
| 		} | ||||
| 		if err := FillStruct(&args, info.Data); err != nil { | ||||
| 			fmt.Println(err.Error()) | ||||
| 			return nil | ||||
| 		if api.DecodeRequest(context.GetRequest(), &args) != nil { | ||||
| 			context.Text("unable to decode request") | ||||
| 			return | ||||
| 		} | ||||
|  | ||||
| 		var result struct { | ||||
| @@ -198,15 +198,13 @@ func getVideoHandlers() { | ||||
| 			var tag types.Tag | ||||
| 			err := rows.Scan(&tag.TagName, &tag.TagId) | ||||
| 			if err != nil { | ||||
| 				panic(err.Error()) // proper error handling instead of panic in your app | ||||
| 				panic(err.Error()) // proper Error handling instead of panic in your app | ||||
| 			} | ||||
| 			// append to final array | ||||
| 			result.Tags = append(result.Tags, tag) | ||||
| 		} | ||||
|  | ||||
| 		// jsonify results | ||||
| 		str, _ := json.Marshal(result) | ||||
| 		return str | ||||
| 		context.Json(result) | ||||
| 	}) | ||||
|  | ||||
| 	/** | ||||
| @@ -221,23 +219,19 @@ func getVideoHandlers() { | ||||
| 	 * @apiSuccess {number} .MovieId Id of Video | ||||
| 	 * @apiSuccess {String} .MovieName  Name of video | ||||
| 	 */ | ||||
| 	AddHandler("getSearchKeyWord", VideoNode, func(info *HandlerInfo) []byte { | ||||
| 	api.AddHandler("getSearchKeyWord", api.VideoNode, api.PermUser, func(context api.Context) { | ||||
| 		var args struct { | ||||
| 			KeyWord string | ||||
| 		} | ||||
| 		if err := FillStruct(&args, info.Data); err != nil { | ||||
| 			fmt.Println(err.Error()) | ||||
| 			return nil | ||||
| 		if api.DecodeRequest(context.GetRequest(), &args) != nil { | ||||
| 			context.Text("unable to decode request") | ||||
| 			return | ||||
| 		} | ||||
|  | ||||
| 		query := fmt.Sprintf(`SELECT movie_id,movie_name FROM videos  | ||||
| 					WHERE movie_name LIKE '%%%s%%' | ||||
| 					ORDER BY likes DESC, create_date DESC, movie_name`, args.KeyWord) | ||||
|  | ||||
| 		result := readVideosFromResultset(database.Query(query)) | ||||
| 		// jsonify results | ||||
| 		str, _ := json.Marshal(result) | ||||
| 		return str | ||||
| 		context.Json(readVideosFromResultset(database.Query(query))) | ||||
| 	}) | ||||
| } | ||||
|  | ||||
| @@ -273,13 +267,13 @@ func loadVideosHandlers() { | ||||
| 	 * @apiSuccess {string} Actors.Name Actor Name | ||||
| 	 * @apiSuccess {string} Actors.Thumbnail Portrait Thumbnail | ||||
| 	 */ | ||||
| 	AddHandler("loadVideo", VideoNode, func(info *HandlerInfo) []byte { | ||||
| 	api.AddHandler("loadVideo", api.VideoNode, api.PermUser, func(context api.Context) { | ||||
| 		var args struct { | ||||
| 			MovieId int | ||||
| 		} | ||||
| 		if err := FillStruct(&args, info.Data); err != nil { | ||||
| 			fmt.Println(err.Error()) | ||||
| 			return nil | ||||
| 		if api.DecodeRequest(context.GetRequest(), &args) != nil { | ||||
| 			context.Text("unable to decode request") | ||||
| 			return | ||||
| 		} | ||||
|  | ||||
| 		query := fmt.Sprintf(`SELECT movie_name,movie_url,movie_id,thumbnail,poster,likes,quality,length  | ||||
| @@ -291,9 +285,9 @@ func loadVideosHandlers() { | ||||
|  | ||||
| 		err := database.QueryRow(query).Scan(&res.MovieName, &res.MovieUrl, &res.MovieId, &thumbnail, &poster, &res.Likes, &res.Quality, &res.Length) | ||||
| 		if err != nil { | ||||
| 			fmt.Printf("error getting full data list of videoid - %d", args.MovieId) | ||||
| 			fmt.Printf("Error getting full data list of videoid - %d", args.MovieId) | ||||
| 			fmt.Println(err.Error()) | ||||
| 			return nil | ||||
| 			return | ||||
| 		} | ||||
|  | ||||
| 		// we ned to urlencode the movieurl | ||||
| @@ -331,9 +325,7 @@ func loadVideosHandlers() { | ||||
|  | ||||
| 		res.Actors = readActorsFromResultset(database.Query(query)) | ||||
|  | ||||
| 		// jsonify results | ||||
| 		str, _ := json.Marshal(res) | ||||
| 		return str | ||||
| 		context.Json(res) | ||||
| 	}) | ||||
|  | ||||
| 	/** | ||||
| @@ -349,7 +341,7 @@ func loadVideosHandlers() { | ||||
| 	 * @apiSuccess {uint32} DifferentTags number of different Tags available | ||||
| 	 * @apiSuccess {uint32} Tagged number of different Tags assigned | ||||
| 	 */ | ||||
| 	AddHandler("getStartData", VideoNode, func(info *HandlerInfo) []byte { | ||||
| 	api.AddHandler("getStartData", api.VideoNode, api.PermUser, func(context api.Context) { | ||||
| 		var result types.StartData | ||||
| 		// query settings and infotile values | ||||
| 		query := ` | ||||
| @@ -383,9 +375,7 @@ func loadVideosHandlers() { | ||||
|  | ||||
| 		_ = database.QueryRow(query).Scan(&result.VideoNr, &result.Tagged, &result.HDNr, &result.FullHdNr, &result.SDNr, &result.DifferentTags) | ||||
|  | ||||
| 		// jsonify results | ||||
| 		str, _ := json.Marshal(result) | ||||
| 		return str | ||||
| 		context.Json(result) | ||||
| 	}) | ||||
| } | ||||
|  | ||||
| @@ -398,19 +388,19 @@ func addToVideoHandlers() { | ||||
| 	 * | ||||
| 	 * @apiParam {int} MovieId ID of video | ||||
| 	 * | ||||
| 	 * @apiSuccess {string} result 'success' if successfully or error message if not | ||||
| 	 * @apiSuccess {string} result 'success' if successfully or Error message if not | ||||
| 	 */ | ||||
| 	AddHandler("addLike", VideoNode, func(info *HandlerInfo) []byte { | ||||
| 	api.AddHandler("addLike", api.VideoNode, api.PermUser, func(context api.Context) { | ||||
| 		var args struct { | ||||
| 			MovieId int | ||||
| 		} | ||||
| 		if err := FillStruct(&args, info.Data); err != nil { | ||||
| 			fmt.Println(err.Error()) | ||||
| 			return nil | ||||
| 		if api.DecodeRequest(context.GetRequest(), &args) != nil { | ||||
| 			context.Text("unable to decode request") | ||||
| 			return | ||||
| 		} | ||||
|  | ||||
| 		query := fmt.Sprintf("update videos set likes = likes + 1 where movie_id = %d", args.MovieId) | ||||
| 		return database.SuccessQuery(query) | ||||
| 		context.Text(string(database.SuccessQuery(query))) | ||||
| 	}) | ||||
|  | ||||
| 	/** | ||||
| @@ -422,16 +412,16 @@ func addToVideoHandlers() { | ||||
| 	 * @apiParam {int} MovieId ID of video | ||||
| 	 * @apiParam {bool} FullyDelete Delete video from disk? | ||||
| 	 * | ||||
| 	 * @apiSuccess {string} result 'success' if successfully or error message if not | ||||
| 	 * @apiSuccess {string} result 'success' if successfully or Error message if not | ||||
| 	 */ | ||||
| 	AddHandler("deleteVideo", VideoNode, func(info *HandlerInfo) []byte { | ||||
| 	api.AddHandler("deleteVideo", api.VideoNode, api.PermUser, func(context api.Context) { | ||||
| 		var args struct { | ||||
| 			MovieId     int | ||||
| 			FullyDelete bool | ||||
| 		} | ||||
| 		if err := FillStruct(&args, info.Data); err != nil { | ||||
| 			fmt.Println(err.Error()) | ||||
| 			return nil | ||||
| 		if api.DecodeRequest(context.GetRequest(), &args) != nil { | ||||
| 			context.Text("unable to decode request") | ||||
| 			return | ||||
| 		} | ||||
|  | ||||
| 		// delete tag constraints | ||||
| @@ -444,7 +434,7 @@ func addToVideoHandlers() { | ||||
|  | ||||
| 		// respond only if result not successful | ||||
| 		if err != nil { | ||||
| 			return database.ManualSuccessResponse(err) | ||||
| 			context.Text(string(database.ManualSuccessResponse(err))) | ||||
| 		} | ||||
|  | ||||
| 		// only allow deletion of video if cli flag is set, independent of passed api arg | ||||
| @@ -454,7 +444,7 @@ func addToVideoHandlers() { | ||||
| 			var vidpath string | ||||
| 			err := database.QueryRow(query).Scan(&vidpath) | ||||
| 			if err != nil { | ||||
| 				return database.ManualSuccessResponse(err) | ||||
| 				context.Text(string(database.ManualSuccessResponse(err))) | ||||
| 			} | ||||
|  | ||||
| 			sett, videoprefix, _ := database.GetSettings() | ||||
| @@ -463,12 +453,12 @@ func addToVideoHandlers() { | ||||
| 			err = os.Remove(assembledPath) | ||||
| 			if err != nil { | ||||
| 				fmt.Printf("unable to delete file: %s -- %s\n", assembledPath, err.Error()) | ||||
| 				return database.ManualSuccessResponse(err) | ||||
| 				context.Text(string(database.ManualSuccessResponse(err))) | ||||
| 			} | ||||
| 		} | ||||
|  | ||||
| 		// delete video row from db | ||||
| 		query = fmt.Sprintf("DELETE FROM videos WHERE movie_id=%d", args.MovieId) | ||||
| 		return database.SuccessQuery(query) | ||||
| 		context.Text(string(database.SuccessQuery(query))) | ||||
| 	}) | ||||
| } | ||||
|   | ||||
							
								
								
									
										125
									
								
								apiGo/api/api/ApiBase.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										125
									
								
								apiGo/api/api/ApiBase.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,125 @@ | ||||
| package api | ||||
|  | ||||
| import ( | ||||
| 	"fmt" | ||||
| 	"net/http" | ||||
| ) | ||||
|  | ||||
| const ( | ||||
| 	VideoNode    = "video" | ||||
| 	TagNode      = "tag" | ||||
| 	SettingsNode = "setting" | ||||
| 	ActorNode    = "actor" | ||||
| 	TVShowNode   = "tv" | ||||
| 	LoginNode    = "login" | ||||
| ) | ||||
|  | ||||
| //type HandlerInfo struct { | ||||
| //	ID    string | ||||
| //	Token string | ||||
| //	Data  map[string]interface{} | ||||
| //} | ||||
|  | ||||
| //type actionStruct struct { | ||||
| //	Action string | ||||
| //} | ||||
|  | ||||
| //type Handler struct { | ||||
| //	action  string | ||||
| //	handler api.PermUser, func(context api.Context) | ||||
| //	apiNode int | ||||
| //} | ||||
|  | ||||
| func AddHandler(action string, apiNode string, perm uint8, handler func(ctx Context)) { | ||||
| 	http.Handle(fmt.Sprintf("/api/%s/%s", apiNode, action), http.HandlerFunc(func(writer http.ResponseWriter, request *http.Request) { | ||||
| 		tokenheader := request.Header.Get("Token") | ||||
|  | ||||
| 		id := -1 | ||||
| 		permid := PermUnauthorized | ||||
|  | ||||
| 		// check token if token provided | ||||
| 		if tokenheader != "" { | ||||
| 			id, permid = TokenValid(request.Header.Get("Token")) | ||||
| 		} | ||||
|  | ||||
| 		ctx := &apicontext{writer: writer, responseWritten: false, request: request, userid: id, permid: permid} | ||||
|  | ||||
| 		// check if rights are sufficient to perform the action | ||||
| 		if permid <= perm { | ||||
| 			handler(ctx) | ||||
|  | ||||
| 			if !ctx.responseWritten { | ||||
| 				// none of the response functions called so send default response | ||||
| 				ctx.Error("Unknown server Error occured") | ||||
| 				writer.WriteHeader(501) | ||||
| 			} | ||||
| 		} else { | ||||
| 			ctx.Error("insufficient permissions") | ||||
| 			writer.WriteHeader(501) | ||||
| 		} | ||||
| 	})) | ||||
| } | ||||
|  | ||||
| func ServerInit() { | ||||
| 	// initialize auth service and add corresponding auth routes | ||||
| 	InitOAuth() | ||||
| } | ||||
|  | ||||
| //func handleAPICall(action string, requestBody string, apiNode int, context api.Context)  { | ||||
| //	handler, ok := handlers[fmt.Sprintf("%s/%d", action, apiNode)] | ||||
| //	if !ok { | ||||
| //		// handler doesn't exist! | ||||
| //		fmt.Printf("no handler found for Action: %d/%s\n", apiNode, action) | ||||
| //		return nil | ||||
| //	} | ||||
| // | ||||
| //	// check if info even exists | ||||
| //	if info == nil { | ||||
| //		info = &HandlerInfo{} | ||||
| //	} | ||||
| // | ||||
| //	// parse the arguments | ||||
| //	var args map[string]interface{} | ||||
| //	err := json.Unmarshal([]byte(requestBody), &args) | ||||
| // | ||||
| //	if err != nil { | ||||
| //		fmt.Printf("failed to decode arguments of action %s :: %s\n", action, requestBody) | ||||
| //	} else { | ||||
| //		// check if map has an action | ||||
| //		if _, ok := args["action"]; ok { | ||||
| //			delete(args, "action") | ||||
| //		} | ||||
| // | ||||
| //		info.Data = args | ||||
| //	} | ||||
| // | ||||
| //	// call the handler | ||||
| //	return handler.handler(info) | ||||
| //} | ||||
| // | ||||
| //func handlefunc(rw http.ResponseWriter, req *http.Request, node int, tokenInfo *oauth2.TokenInfo) { | ||||
| //	// only allow post requests | ||||
| //	if req.Method != "POST" { | ||||
| //		return | ||||
| //	} | ||||
| // | ||||
| //	buf := new(bytes.Buffer) | ||||
| //	buf.ReadFrom(req.Body) | ||||
| //	body := buf.String() | ||||
| // | ||||
| //	var t actionStruct | ||||
| //	err := json.Unmarshal([]byte(body), &t) | ||||
| //	if err != nil { | ||||
| //		fmt.Println("failed to read action from request! :: " + body) | ||||
| //	} | ||||
| // | ||||
| //	// load userid from received token object | ||||
| //	id := (*tokenInfo).GetClientID() | ||||
| // | ||||
| //	userinfo := &HandlerInfo{ | ||||
| //		ID:    id, | ||||
| //		Token: (*tokenInfo).GetCode(), | ||||
| //	} | ||||
| // | ||||
| //	rw.Write(handleAPICall(t.Action, body, node, userinfo)) | ||||
| //} | ||||
| @@ -11,7 +11,7 @@ func cleanUp() { | ||||
| func TestAddHandler(t *testing.T) { | ||||
| 	cleanUp() | ||||
| 
 | ||||
| 	AddHandler("test", ActorNode, func(info *HandlerInfo) []byte { | ||||
| 	AddHandler("test", ActorNode, api.PermUser, func(context api.Context) { | ||||
| 		return nil | ||||
| 	}) | ||||
| 	if len(handlers) != 1 { | ||||
| @@ -23,7 +23,7 @@ func TestCallOfHandler(t *testing.T) { | ||||
| 	cleanUp() | ||||
| 
 | ||||
| 	i := 0 | ||||
| 	AddHandler("test", ActorNode, func(info *HandlerInfo) []byte { | ||||
| 	AddHandler("test", ActorNode, api.PermUser, func(context api.Context) { | ||||
| 		i++ | ||||
| 		return nil | ||||
| 	}) | ||||
| @@ -39,7 +39,7 @@ func TestCallOfHandler(t *testing.T) { | ||||
| func TestDecodingOfArguments(t *testing.T) { | ||||
| 	cleanUp() | ||||
| 
 | ||||
| 	AddHandler("test", ActorNode, func(info *HandlerInfo) []byte { | ||||
| 	AddHandler("test", ActorNode, api.PermUser, func(context api.Context) { | ||||
| 		var args struct { | ||||
| 			Test    string | ||||
| 			TestInt int | ||||
							
								
								
									
										119
									
								
								apiGo/api/api/Auth.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										119
									
								
								apiGo/api/api/Auth.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,119 @@ | ||||
| package api | ||||
|  | ||||
| import ( | ||||
| 	"fmt" | ||||
| 	"github.com/dgrijalva/jwt-go" | ||||
| 	"gopkg.in/oauth2.v3" | ||||
| 	"gopkg.in/oauth2.v3/server" | ||||
| 	"net/http" | ||||
| 	"openmediacenter/apiGo/database" | ||||
| 	"strconv" | ||||
| 	"time" | ||||
| ) | ||||
|  | ||||
| var srv *server.Server | ||||
|  | ||||
| const ( | ||||
| 	PermAdmin        uint8 = iota | ||||
| 	PermUser         uint8 = iota | ||||
| 	PermUnauthorized uint8 = iota | ||||
| ) | ||||
|  | ||||
| const SignKey = "89013f1753a6890c6090b09e3c23ff43" | ||||
| const TokenExpireHours = 24 | ||||
|  | ||||
| type Token struct { | ||||
| 	Token     string | ||||
| 	ExpiresAt int64 | ||||
| } | ||||
|  | ||||
| func TokenValid(token string) (int, uint8) { | ||||
| 	t, err := jwt.ParseWithClaims(token, &jwt.StandardClaims{}, func(token *jwt.Token) (interface{}, error) { | ||||
| 		return []byte(SignKey), nil | ||||
| 	}) | ||||
| 	if err != nil { | ||||
| 		return -1, PermUnauthorized | ||||
| 	} | ||||
|  | ||||
| 	claims := t.Claims.(*jwt.StandardClaims) | ||||
|  | ||||
| 	id, err := strconv.Atoi(claims.Issuer) | ||||
| 	permid, err := strconv.Atoi(claims.Subject) | ||||
| 	if err != nil { | ||||
| 		return -1, PermUnauthorized | ||||
| 	} | ||||
| 	return id, uint8(permid) | ||||
| } | ||||
|  | ||||
| func InitOAuth() { | ||||
| 	AddHandler("login", LoginNode, PermUnauthorized, func(ctx Context) { | ||||
| 		var t struct { | ||||
| 			Username string | ||||
| 			Password string | ||||
| 		} | ||||
|  | ||||
| 		if DecodeRequest(ctx.GetRequest(), &t) != nil { | ||||
| 			fmt.Println("Error accured while decoding Testrequest!!") | ||||
| 		} | ||||
|  | ||||
| 		// empty check | ||||
| 		if t.Password == "" || t.Username == "" { | ||||
| 			ctx.Error("empty username or password") | ||||
| 			return | ||||
| 		} | ||||
|  | ||||
| 		// generate Argon2 Hash of passed pwd | ||||
| 		pwd := HashPassword(t.Password) | ||||
|  | ||||
| 		var id uint | ||||
| 		var name string | ||||
| 		var rightid uint8 | ||||
|  | ||||
| 		err := database.QueryRow("SELECT userId,userName,rightId FROM User WHERE userName=? AND password=?", t.Username, *pwd).Scan(&id, &name, &rightid) | ||||
| 		if err != nil { | ||||
| 			ctx.Error("unauthorized") | ||||
| 			return | ||||
| 		} | ||||
|  | ||||
| 		expires := time.Now().Add(time.Hour * TokenExpireHours).Unix() | ||||
| 		claims := jwt.NewWithClaims(jwt.SigningMethodHS256, jwt.StandardClaims{ | ||||
| 			Issuer:    strconv.Itoa(int(id)), | ||||
| 			Subject:   strconv.Itoa(int(rightid)), | ||||
| 			ExpiresAt: expires, | ||||
| 		}) | ||||
|  | ||||
| 		token, err := claims.SignedString([]byte(SignKey)) | ||||
| 		if err != nil { | ||||
| 			fmt.Println(err.Error()) | ||||
| 			ctx.Error("failed to generate authorization token") | ||||
| 			return | ||||
| 		} | ||||
|  | ||||
| 		type ResponseType struct { | ||||
| 			Token    Token | ||||
| 			Username string | ||||
| 			UserPerm uint8 | ||||
| 		} | ||||
|  | ||||
| 		ctx.Json(ResponseType{ | ||||
| 			Token: Token{ | ||||
| 				Token:     token, | ||||
| 				ExpiresAt: expires, | ||||
| 			}, | ||||
| 			Username: t.Username, | ||||
| 			UserPerm: rightid, | ||||
| 		}) | ||||
| 	}) | ||||
| } | ||||
|  | ||||
| func ValidateToken(f func(rw http.ResponseWriter, req *http.Request, node int, tokenInfo *oauth2.TokenInfo), node int) http.HandlerFunc { | ||||
| 	return func(w http.ResponseWriter, r *http.Request) { | ||||
| 		tokeninfo, err := srv.ValidationBearerToken(r) | ||||
| 		if err != nil { | ||||
| 			http.Error(w, err.Error(), http.StatusBadRequest) | ||||
| 			return | ||||
| 		} | ||||
|  | ||||
| 		f(w, r, node, &tokeninfo) | ||||
| 	} | ||||
| } | ||||
							
								
								
									
										60
									
								
								apiGo/api/api/Context.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										60
									
								
								apiGo/api/api/Context.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,60 @@ | ||||
| package api | ||||
|  | ||||
| import ( | ||||
| 	"fmt" | ||||
| 	"net/http" | ||||
| ) | ||||
|  | ||||
| type Context interface { | ||||
| 	Json(t interface{}) | ||||
| 	Text(msg string) | ||||
| 	Error(msg string) | ||||
| 	Errorf(msg string, args ...interface{}) | ||||
| 	GetRequest() *http.Request | ||||
| 	GetWriter() http.ResponseWriter | ||||
| 	UserID() int | ||||
| } | ||||
|  | ||||
| type apicontext struct { | ||||
| 	writer          http.ResponseWriter | ||||
| 	request         *http.Request | ||||
| 	responseWritten bool | ||||
| 	userid          int | ||||
| 	permid          uint8 | ||||
| } | ||||
|  | ||||
| func (r *apicontext) GetRequest() *http.Request { | ||||
| 	return r.request | ||||
| } | ||||
|  | ||||
| func (r *apicontext) UserID() int { | ||||
| 	return r.userid | ||||
| } | ||||
|  | ||||
| func (r *apicontext) GetWriter() http.ResponseWriter { | ||||
| 	return r.writer | ||||
| } | ||||
|  | ||||
| func (r *apicontext) Json(t interface{}) { | ||||
| 	r.writer.Write(Jsonify(t)) | ||||
| 	r.responseWritten = true | ||||
| } | ||||
|  | ||||
| func (r *apicontext) Text(msg string) { | ||||
| 	r.writer.Write([]byte(msg)) | ||||
| 	r.responseWritten = true | ||||
| } | ||||
|  | ||||
| func (r *apicontext) Error(msg string) { | ||||
| 	type Error struct { | ||||
| 		Message string | ||||
| 	} | ||||
|  | ||||
| 	r.writer.WriteHeader(500) | ||||
| 	r.writer.Write(Jsonify(Error{Message: msg})) | ||||
| 	r.responseWritten = true | ||||
| } | ||||
|  | ||||
| func (r *apicontext) Errorf(msg string, args ...interface{}) { | ||||
| 	r.Error(fmt.Sprintf(msg, args)) | ||||
| } | ||||
							
								
								
									
										13
									
								
								apiGo/api/api/Hash.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								apiGo/api/api/Hash.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,13 @@ | ||||
| package api | ||||
|  | ||||
| import ( | ||||
| 	"encoding/hex" | ||||
| 	"golang.org/x/crypto/argon2" | ||||
| ) | ||||
|  | ||||
| func HashPassword(pwd string) *string { | ||||
| 	// todo generate random salt | ||||
| 	hash := argon2.IDKey([]byte(pwd), []byte(SignKey), 3, 64*1024, 2, 32) | ||||
| 	hexx := hex.EncodeToString(hash) | ||||
| 	return &hexx | ||||
| } | ||||
							
								
								
									
										74
									
								
								apiGo/api/api/Helpers.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										74
									
								
								apiGo/api/api/Helpers.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,74 @@ | ||||
| package api | ||||
|  | ||||
| import ( | ||||
| 	"bytes" | ||||
| 	"encoding/json" | ||||
| 	"fmt" | ||||
| 	"net/http" | ||||
| 	"reflect" | ||||
| ) | ||||
|  | ||||
| func Jsonify(v interface{}) []byte { | ||||
| 	// Jsonify results | ||||
| 	str, err := json.Marshal(v) | ||||
| 	if err != nil { | ||||
| 		fmt.Println("Error while Jsonifying return object: " + err.Error()) | ||||
| 	} | ||||
| 	return str | ||||
| } | ||||
|  | ||||
| // DecodeRequest decodes the request | ||||
| func DecodeRequest(request *http.Request, arg interface{}) error { | ||||
| 	buf := new(bytes.Buffer) | ||||
| 	buf.ReadFrom(request.Body) | ||||
| 	body := buf.String() | ||||
|  | ||||
| 	err := json.Unmarshal([]byte(body), &arg) | ||||
| 	if err != nil { | ||||
| 		fmt.Println("JSON decode Error" + err.Error()) | ||||
| 	} | ||||
|  | ||||
| 	return err | ||||
| } | ||||
|  | ||||
| // setField set a specific field of an object with an object provided | ||||
| func setField(obj interface{}, name string, value interface{}) error { | ||||
| 	structValue := reflect.ValueOf(obj).Elem() | ||||
| 	structFieldValue := structValue.FieldByName(name) | ||||
|  | ||||
| 	if !structFieldValue.IsValid() { | ||||
| 		return fmt.Errorf("no such field: %s in obj", name) | ||||
| 	} | ||||
|  | ||||
| 	if !structFieldValue.CanSet() { | ||||
| 		return fmt.Errorf("cannot set %s field value", name) | ||||
| 	} | ||||
|  | ||||
| 	structFieldType := structFieldValue.Type() | ||||
| 	val := reflect.ValueOf(value) | ||||
|  | ||||
| 	if structFieldType != val.Type() { | ||||
| 		if val.Type().ConvertibleTo(structFieldType) { | ||||
| 			// if type is convertible - convert and set | ||||
| 			structFieldValue.Set(val.Convert(structFieldType)) | ||||
| 		} else { | ||||
| 			return fmt.Errorf("provided value %s type didn't match obj field type and isn't convertible", name) | ||||
| 		} | ||||
| 	} else { | ||||
| 		// set value if type is the same | ||||
| 		structFieldValue.Set(val) | ||||
| 	} | ||||
|  | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| // FillStruct fill a custom struct with objects of a map | ||||
| func FillStruct(i interface{}, m map[string]interface{}) error { | ||||
| 	for k, v := range m { | ||||
| 		err := setField(i, k, v) | ||||
| 		if err != nil { | ||||
| 			return err | ||||
| 		} | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
| @@ -1,57 +0,0 @@ | ||||
| package oauth | ||||
|  | ||||
| import ( | ||||
| 	"gopkg.in/oauth2.v3" | ||||
| 	"openmediacenter/apiGo/database/settings" | ||||
| ) | ||||
|  | ||||
| type CustomClientStore struct { | ||||
| 	oauth2.ClientStore | ||||
| } | ||||
|  | ||||
| type CustomClientInfo struct { | ||||
| 	oauth2.ClientInfo | ||||
| 	ID     string | ||||
| 	Secret string | ||||
| 	Domain string | ||||
| 	UserID string | ||||
| } | ||||
|  | ||||
| func NewCustomStore() oauth2.ClientStore { | ||||
| 	s := new(CustomClientStore) | ||||
| 	return s | ||||
| } | ||||
|  | ||||
| func (a *CustomClientStore) GetByID(id string) (oauth2.ClientInfo, error) { | ||||
| 	password := settings.GetPassword() | ||||
| 	// if password not set assign default password | ||||
| 	if password == nil { | ||||
| 		defaultpassword := "openmediacenter" | ||||
| 		password = &defaultpassword | ||||
| 	} | ||||
|  | ||||
| 	clientinfo := CustomClientInfo{ | ||||
| 		ID:     "openmediacenter", | ||||
| 		Secret: *password, | ||||
| 		Domain: "http://localhost:8081", | ||||
| 		UserID: "openmediacenter", | ||||
| 	} | ||||
|  | ||||
| 	return &clientinfo, nil | ||||
| } | ||||
|  | ||||
| func (a *CustomClientInfo) GetID() string { | ||||
| 	return a.ID | ||||
| } | ||||
|  | ||||
| func (a *CustomClientInfo) GetSecret() string { | ||||
| 	return a.Secret | ||||
| } | ||||
|  | ||||
| func (a *CustomClientInfo) GetDomain() string { | ||||
| 	return a.Domain | ||||
| } | ||||
|  | ||||
| func (a *CustomClientInfo) GetUserID() string { | ||||
| 	return a.UserID | ||||
| } | ||||
| @@ -1,62 +0,0 @@ | ||||
| package oauth | ||||
|  | ||||
| import ( | ||||
| 	"gopkg.in/oauth2.v3" | ||||
| 	"gopkg.in/oauth2.v3/errors" | ||||
| 	"gopkg.in/oauth2.v3/manage" | ||||
| 	"gopkg.in/oauth2.v3/server" | ||||
| 	"gopkg.in/oauth2.v3/store" | ||||
| 	"log" | ||||
| 	"net/http" | ||||
| ) | ||||
|  | ||||
| var srv *server.Server | ||||
|  | ||||
| func InitOAuth() { | ||||
| 	manager := manage.NewDefaultManager() | ||||
| 	// token store | ||||
| 	manager.MustTokenStorage(store.NewMemoryTokenStore()) | ||||
|  | ||||
| 	// create new secretstore | ||||
| 	clientStore := NewCustomStore() | ||||
| 	manager.MapClientStorage(clientStore) | ||||
|  | ||||
| 	srv = server.NewServer(server.NewConfig(), manager) | ||||
| 	srv.SetClientInfoHandler(server.ClientFormHandler) | ||||
| 	manager.SetRefreshTokenCfg(manage.DefaultRefreshTokenCfg) | ||||
|  | ||||
| 	srv.SetInternalErrorHandler(func(err error) (re *errors.Response) { | ||||
| 		log.Println("Internal Error:", err.Error()) | ||||
| 		return | ||||
| 	}) | ||||
|  | ||||
| 	srv.SetResponseErrorHandler(func(re *errors.Response) { | ||||
| 		log.Println("Response Error:", re.Error.Error()) | ||||
| 	}) | ||||
|  | ||||
| 	http.HandleFunc("/authorize", func(w http.ResponseWriter, r *http.Request) { | ||||
| 		err := srv.HandleAuthorizeRequest(w, r) | ||||
| 		if err != nil { | ||||
| 			http.Error(w, err.Error(), http.StatusBadRequest) | ||||
| 		} | ||||
| 	}) | ||||
|  | ||||
| 	http.HandleFunc("/token", func(w http.ResponseWriter, r *http.Request) { | ||||
| 		err := srv.HandleTokenRequest(w, r) | ||||
| 		if err != nil { | ||||
| 			http.Error(w, err.Error(), http.StatusInternalServerError) | ||||
| 		} | ||||
| 	}) | ||||
| } | ||||
|  | ||||
| func ValidateToken(f func(rw http.ResponseWriter, req *http.Request, node int, tokenInfo *oauth2.TokenInfo), node int) http.HandlerFunc { | ||||
| 	return func(w http.ResponseWriter, r *http.Request) { | ||||
| 		tokeninfo, err := srv.ValidationBearerToken(r) | ||||
| 		if err != nil { | ||||
| 			http.Error(w, err.Error(), http.StatusBadRequest) | ||||
| 			return | ||||
| 		} | ||||
|  | ||||
| 		f(w, r, node, &tokeninfo) | ||||
| 	} | ||||
| } | ||||
| @@ -3,8 +3,10 @@ module openmediacenter/apiGo | ||||
| go 1.16 | ||||
|  | ||||
| require ( | ||||
| 	github.com/dgrijalva/jwt-go v3.2.0+incompatible | ||||
| 	github.com/go-sql-driver/mysql v1.5.0 | ||||
| 	github.com/pelletier/go-toml/v2 v2.0.0-beta.3 | ||||
| 	golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2 | ||||
| 	gopkg.in/oauth2.v3 v3.12.0 | ||||
| 	nhooyr.io/websocket v1.8.7 | ||||
| ) | ||||
|   | ||||
| @@ -41,7 +41,6 @@ github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ | ||||
| github.com/google/go-querystring v1.0.0 h1:Xkwi/a1rcvNg1PPYe5vI8GbeBY/jrVuDX5ASuANWTrk= | ||||
| github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= | ||||
| github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= | ||||
| github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8= | ||||
| github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= | ||||
| github.com/gorilla/websocket v1.4.1 h1:q7AeDBpnBk8AogcD4DSag/Ukw/KV+YhzLj2bP5HvKCM= | ||||
| github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= | ||||
| @@ -50,7 +49,6 @@ github.com/imkira/go-interpol v1.1.0 h1:KIiKr0VSG2CUW1hl1jpiyuzuJeKUUpC8iM1AIE7N | ||||
| github.com/imkira/go-interpol v1.1.0/go.mod h1:z0h2/2T3XF8kyEPpRgJ3kmNv+C43p+I/CoI+jC3w2iA= | ||||
| github.com/json-iterator/go v1.1.9 h1:9yzud/Ht36ygwatGx56VwCZtlI/2AD15T1X2sjSuGns= | ||||
| github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= | ||||
| github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo= | ||||
| github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= | ||||
| github.com/k0kubun/colorstring v0.0.0-20150214042306-9440f1994b88/go.mod h1:3w7q1U84EfirKl04SVQ/s7nPm1ZPhiXd34z40TNz36k= | ||||
| github.com/klauspost/compress v1.8.2/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= | ||||
| @@ -78,9 +76,7 @@ github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZb | ||||
| github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= | ||||
| github.com/sergi/go-diff v1.0.0 h1:Kpca3qRNrduNnOQeazBd0ysaKrUJiIuISHxogkT9RPQ= | ||||
| github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= | ||||
| github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM= | ||||
| github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= | ||||
| github.com/smartystreets/goconvey v1.6.4 h1:fv0U8FUIMPNf1L9lnHLvLhgicrIVChEkdzIKYqbNC9s= | ||||
| github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= | ||||
| github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= | ||||
| github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= | ||||
| @@ -125,6 +121,7 @@ github.com/yudai/gojsondiff v1.0.0/go.mod h1:AY32+k2cwILAkW1fbgxQ5mUmMiZFgLIV+FB | ||||
| github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82 h1:BHyfKlQyqbsFN5p3IfnEUduWvb9is428/nNb5L3U01M= | ||||
| github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82/go.mod h1:lgjkn3NuSvDfVJdfcVVdX+jpBxNmX4rDAzaS45IcYoM= | ||||
| github.com/yudai/pp v2.0.1+incompatible/go.mod h1:PuxR/8QJ7cyCkFp/aUDS+JY727OFEZkTdatxwunjIkc= | ||||
| golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2 h1:VklqNMn3ovrHsnt90PveolxSbWFaJdECFbxSq0Mqo2M= | ||||
| golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= | ||||
| golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= | ||||
| golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= | ||||
|   | ||||
| @@ -5,6 +5,7 @@ import ( | ||||
| 	"log" | ||||
| 	"net/http" | ||||
| 	"openmediacenter/apiGo/api" | ||||
| 	api2 "openmediacenter/apiGo/api/api" | ||||
| 	"openmediacenter/apiGo/config" | ||||
| 	"openmediacenter/apiGo/database" | ||||
| 	"openmediacenter/apiGo/static" | ||||
| @@ -35,7 +36,7 @@ func main() { | ||||
| 	// add the static files | ||||
| 	static.ServeStaticFiles() | ||||
|  | ||||
| 	api.ServerInit() | ||||
| 	api2.ServerInit() | ||||
|  | ||||
| 	fmt.Printf("OpenMediacenter server up and running on port %d\n", port) | ||||
| 	log.Fatal(http.ListenAndServe(fmt.Sprintf(":%d", port), nil)) | ||||
|   | ||||
| @@ -68,7 +68,7 @@ function generalAPICall<T>( | ||||
|     mytoken: string | ||||
| ): void { | ||||
|     (async function (): Promise<void> { | ||||
|         const response = await fetch(APIPREFIX + apinode, { | ||||
|         const response = await fetch(APIPREFIX + apinode + '/' + fd.action, { | ||||
|             method: 'POST', | ||||
|             body: JSON.stringify(fd), | ||||
|             headers: new Headers({ | ||||
|   | ||||
		Reference in New Issue
	
	Block a user