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 ( | import ( | ||||||
| 	"fmt" | 	"fmt" | ||||||
|  | 	"openmediacenter/apiGo/api/api" | ||||||
| 	"openmediacenter/apiGo/api/types" | 	"openmediacenter/apiGo/api/types" | ||||||
| 	"openmediacenter/apiGo/database" | 	"openmediacenter/apiGo/database" | ||||||
| ) | ) | ||||||
| @@ -23,9 +24,9 @@ func getActorsFromDB() { | |||||||
| 	 * @apiSuccess {string} .Name Actor Name | 	 * @apiSuccess {string} .Name Actor Name | ||||||
| 	 * @apiSuccess {string} .Thumbnail Portrait Thumbnail | 	 * @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" | 		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} .Name Actor Name | ||||||
| 	 * @apiSuccess {string} .Thumbnail Portrait Thumbnail | 	 * @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 { | 		var args struct { | ||||||
| 			MovieId int | 			MovieId int | ||||||
| 		} | 		} | ||||||
| 		if err := FillStruct(&args, info.Data); err != nil { | 		err := api.DecodeRequest(context.GetRequest(), &args) | ||||||
| 			fmt.Println(err.Error()) | 		if err != nil { | ||||||
| 			return nil | 			context.Text("failed to decode request") | ||||||
|  | 			return | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		query := fmt.Sprintf(`SELECT a.actor_id, name, thumbnail FROM actors_videos | 		query := fmt.Sprintf(`SELECT a.actor_id, name, thumbnail FROM actors_videos | ||||||
| 									JOIN actors a on actors_videos.actor_id = a.actor_id | 									JOIN actors a on actors_videos.actor_id = a.actor_id | ||||||
| 									WHERE actors_videos.video_id=%d`, args.MovieId) | 									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.Name Actor Name | ||||||
| 	 * @apiSuccess {string} Info.Thumbnail Actor Thumbnail | 	 * @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 { | 		var args struct { | ||||||
| 			ActorId int | 			ActorId int | ||||||
| 		} | 		} | ||||||
| 		if err := FillStruct(&args, info.Data); err != nil { |  | ||||||
| 			fmt.Println(err.Error()) | 		err := api.DecodeRequest(context.GetRequest(), &args) | ||||||
| 			return nil | 		if err != nil { | ||||||
|  | 			context.Error("unable to decode request") | ||||||
|  | 			return | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		query := fmt.Sprintf(`SELECT movie_id, movie_name FROM actors_videos | 		query := fmt.Sprintf(`SELECT movie_id, movie_name FROM actors_videos | ||||||
| @@ -99,7 +103,7 @@ func getActorsFromDB() { | |||||||
| 			Info:   actor, | 			Info:   actor, | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		return jsonify(result) | 		context.Json(result) | ||||||
| 	}) | 	}) | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -112,19 +116,17 @@ func saveActorsToDB() { | |||||||
| 	 * | 	 * | ||||||
| 	 * @apiParam {string} ActorName Name of new Actor | 	 * @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 { | 		var args struct { | ||||||
| 			ActorName string | 			ActorName string | ||||||
| 		} | 		} | ||||||
| 		if err := FillStruct(&args, info.Data); err != nil { | 		api.DecodeRequest(context.GetRequest(), &args) | ||||||
| 			fmt.Println(err.Error()) |  | ||||||
| 			return nil |  | ||||||
| 		} |  | ||||||
|  |  | ||||||
| 		query := "INSERT IGNORE INTO actors (name) VALUES (?)" | 		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} ActorId Id of Actor | ||||||
| 	 * @apiParam {int} MovieId Id of Movie to add to | 	 * @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 { | 		var args struct { | ||||||
| 			ActorId int | 			ActorId int | ||||||
| 			MovieId int | 			MovieId int | ||||||
| 		} | 		} | ||||||
| 		if err := FillStruct(&args, info.Data); err != nil { | 		err := api.DecodeRequest(context.GetRequest(), &args) | ||||||
| 			fmt.Println(err.Error()) | 		if err != nil { | ||||||
| 			return 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) | 		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 ( | import ( | ||||||
| 	"database/sql" | 	"database/sql" | ||||||
| 	"encoding/json" |  | ||||||
| 	"fmt" | 	"fmt" | ||||||
| 	"openmediacenter/apiGo/api/types" | 	"openmediacenter/apiGo/api/types" | ||||||
| 	"reflect" |  | ||||||
| ) | ) | ||||||
|  |  | ||||||
| // MovieId - MovieName : pay attention to the order! | // MovieId - MovieName : pay attention to the order! | ||||||
| @@ -33,7 +31,7 @@ func readTagsFromResultset(rows *sql.Rows) []types.Tag { | |||||||
| 		var tag types.Tag | 		var tag types.Tag | ||||||
| 		err := rows.Scan(&tag.TagId, &tag.TagName) | 		err := rows.Scan(&tag.TagId, &tag.TagName) | ||||||
| 		if err != nil { | 		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) | 		result = append(result, tag) | ||||||
| 	} | 	} | ||||||
| @@ -54,7 +52,7 @@ func readActorsFromResultset(rows *sql.Rows) []types.Actor { | |||||||
| 			actor.Thumbnail = string(thumbnail) | 			actor.Thumbnail = string(thumbnail) | ||||||
| 		} | 		} | ||||||
| 		if err != nil { | 		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) | 		result = append(result, actor) | ||||||
| 	} | 	} | ||||||
| @@ -70,7 +68,7 @@ func readTVshowsFromResultset(rows *sql.Rows) []types.TVShow { | |||||||
| 		var vid types.TVShow | 		var vid types.TVShow | ||||||
| 		err := rows.Scan(&vid.Id, &vid.Name) | 		err := rows.Scan(&vid.Id, &vid.Name) | ||||||
| 		if err != nil { | 		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) | 		result = append(result, vid) | ||||||
| 	} | 	} | ||||||
| @@ -78,54 +76,3 @@ func readTVshowsFromResultset(rows *sql.Rows) []types.TVShow { | |||||||
|  |  | ||||||
| 	return result | 	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 | package api | ||||||
|  |  | ||||||
| import ( | import ( | ||||||
| 	"encoding/json" | 	"openmediacenter/apiGo/api/api" | ||||||
| 	"fmt" |  | ||||||
| 	"openmediacenter/apiGo/api/types" | 	"openmediacenter/apiGo/api/types" | ||||||
| 	"openmediacenter/apiGo/config" | 	"openmediacenter/apiGo/config" | ||||||
| 	"openmediacenter/apiGo/database" | 	"openmediacenter/apiGo/database" | ||||||
| @@ -38,7 +37,7 @@ func getSettingsFromDB() { | |||||||
| 	 * @apiSuccess {uint32} Sizes.DifferentTags number of different tags available | 	 * @apiSuccess {uint32} Sizes.DifferentTags number of different tags available | ||||||
| 	 * @apiSuccess {uint32} Sizes.TagsAdded number of different tags added to videos | 	 * @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() | 		result, _, sizes := database.GetSettings() | ||||||
|  |  | ||||||
| 		var ret = struct { | 		var ret = struct { | ||||||
| @@ -48,7 +47,7 @@ func getSettingsFromDB() { | |||||||
| 			Settings: &result, | 			Settings: &result, | ||||||
| 			Sizes:    &sizes, | 			Sizes:    &sizes, | ||||||
| 		} | 		} | ||||||
| 		return jsonify(ret) | 		context.Json(ret) | ||||||
| 	}) | 	}) | ||||||
|  |  | ||||||
| 	/** | 	/** | ||||||
| @@ -64,7 +63,7 @@ func getSettingsFromDB() { | |||||||
| 	 * @apiSuccess {bool} DarkMode Darkmode enabled? | 	 * @apiSuccess {bool} DarkMode Darkmode enabled? | ||||||
| 	 * @apiSuccess {bool} TVShowEnabled is are TVShows 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() | 		sett := settings.LoadSettings() | ||||||
|  |  | ||||||
| 		type InitialDataTypeResponse struct { | 		type InitialDataTypeResponse struct { | ||||||
| @@ -93,8 +92,7 @@ func getSettingsFromDB() { | |||||||
| 			FullDeleteEnabled: config.GetConfig().Features.FullyDeletableVideos, | 			FullDeleteEnabled: config.GetConfig().Features.FullyDeletableVideos, | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		str, _ := json.Marshal(res) | 		context.Json(res) | ||||||
| 		return str |  | ||||||
| 	}) | 	}) | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -112,13 +110,14 @@ func saveSettingsToDB() { | |||||||
| 	 * @apiParam {bool} TMDBGrabbing TMDB grabbing support to grab tag info and thumbnails | 	 * @apiParam {bool} TMDBGrabbing TMDB grabbing support to grab tag info and thumbnails | ||||||
| 	 * @apiParam {bool} DarkMode Darkmode enabled? | 	 * @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 | 		var args types.SettingsType | ||||||
| 		if err := FillStruct(&args, info.Data); err != nil { | 		err := api.DecodeRequest(context.GetRequest(), &args) | ||||||
| 			fmt.Println(err.Error()) | 		if err != nil { | ||||||
| 			return nil | 			context.Error("unable to decode arguments") | ||||||
|  | 			return | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		query := ` | 		query := ` | ||||||
| @@ -130,9 +129,10 @@ func saveSettingsToDB() { | |||||||
|                         TMDB_grabbing=?,  |                         TMDB_grabbing=?,  | ||||||
|                         DarkMode=? |                         DarkMode=? | ||||||
|                     WHERE 1` |                     WHERE 1` | ||||||
| 		return database.SuccessQuery(query, | 		// todo avoid conversion | ||||||
|  | 		context.Text(string(database.SuccessQuery(query, | ||||||
| 			args.VideoPath, args.EpisodePath, args.Password, | 			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 | 	 * @apiName startReindex | ||||||
| 	 * @apiGroup Settings | 	 * @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() | 		videoparser.StartReindex() | ||||||
| 		return database.ManualSuccessResponse(nil) | 		context.Text(string(database.ManualSuccessResponse(nil))) | ||||||
| 	}) | 	}) | ||||||
|  |  | ||||||
| 	/** | 	/** | ||||||
| @@ -157,11 +157,11 @@ func reIndexHandling() { | |||||||
| 	 * @apiName startTVShowReindex | 	 * @apiName startTVShowReindex | ||||||
| 	 * @apiGroup Settings | 	 * @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() | 		videoparser.StartTVShowReindex() | ||||||
| 		return database.ManualSuccessResponse(nil) | 		context.Text(string(database.ManualSuccessResponse(nil))) | ||||||
| 	}) | 	}) | ||||||
|  |  | ||||||
| 	/** | 	/** | ||||||
| @@ -170,8 +170,7 @@ func reIndexHandling() { | |||||||
| 	 * @apiName cleanupGravity | 	 * @apiName cleanupGravity | ||||||
| 	 * @apiGroup Settings | 	 * @apiGroup Settings | ||||||
| 	 */ | 	 */ | ||||||
| 	AddHandler("cleanupGravity", SettingsNode, func(info *HandlerInfo) []byte { | 	api.AddHandler("cleanupGravity", api.SettingsNode, api.PermUser, func(context api.Context) { | ||||||
| 		videoparser.StartCleanup() | 		videoparser.StartCleanup() | ||||||
| 		return nil |  | ||||||
| 	}) | 	}) | ||||||
| } | } | ||||||
|   | |||||||
| @@ -2,6 +2,7 @@ package api | |||||||
|  |  | ||||||
| import ( | import ( | ||||||
| 	"fmt" | 	"fmt" | ||||||
|  | 	"openmediacenter/apiGo/api/api" | ||||||
| 	"openmediacenter/apiGo/config" | 	"openmediacenter/apiGo/config" | ||||||
| 	"openmediacenter/apiGo/database" | 	"openmediacenter/apiGo/database" | ||||||
| ) | ) | ||||||
| @@ -22,10 +23,10 @@ func AddTvshowHandlers() { | |||||||
| 	 * @apiSuccess {uint32} .Id tvshow id | 	 * @apiSuccess {uint32} .Id tvshow id | ||||||
| 	 * @apiSuccess {string} .Name tvshow name | 	 * @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" | 		query := "SELECT id, name FROM tvshow" | ||||||
| 		rows := database.Query(query) | 		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} .Season Season number | ||||||
| 	 * @apiSuccess {uint8} .Episode Episode 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 { | 		var args struct { | ||||||
| 			ShowID uint32 | 			ShowID uint32 | ||||||
| 		} | 		} | ||||||
| 		if err := FillStruct(&args, info.Data); err != nil { | 		err := api.DecodeRequest(context.GetRequest(), &args) | ||||||
| 			fmt.Println(err.Error()) | 		if err != nil { | ||||||
| 			return 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) | 		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) | 			episodes = append(episodes, ep) | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		return jsonify(episodes) | 		context.Json(episodes) | ||||||
| 	}) | 	}) | ||||||
|  |  | ||||||
| 	/** | 	/** | ||||||
| @@ -90,13 +92,14 @@ func AddTvshowHandlers() { | |||||||
| 	 * @apiSuccess {uint8} Episode Episode number | 	 * @apiSuccess {uint8} Episode Episode number | ||||||
| 	 * @apiSuccess {string} Path webserver path of video file | 	 * @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 { | 		var args struct { | ||||||
| 			ID uint32 | 			ID uint32 | ||||||
| 		} | 		} | ||||||
| 		if err := FillStruct(&args, info.Data); err != nil { | 		err := api.DecodeRequest(context.GetRequest(), &args) | ||||||
| 			fmt.Println(err.Error()) | 		if err != nil { | ||||||
| 			return nil | 			context.Text("unable to decode argument") | ||||||
|  | 			return | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		query := fmt.Sprintf(` | 		query := fmt.Sprintf(` | ||||||
| @@ -116,15 +119,16 @@ WHERE tvshow_episodes.id=%d`, args.ID) | |||||||
| 		var filename string | 		var filename string | ||||||
| 		var foldername 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 { | 		if err != nil { | ||||||
| 			fmt.Println(err.Error()) | 			fmt.Println(err.Error()) | ||||||
| 			return nil | 			context.Error(err.Error()) | ||||||
|  | 			return | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		ret.Path = foldername + "/" + filename | 		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 | 	 * @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 { | 		var args struct { | ||||||
| 			Id int | 			Id int | ||||||
| 		} | 		} | ||||||
| 		if err := FillStruct(&args, info.Data); err != nil { | 		err := api.DecodeRequest(context.GetRequest(), &args) | ||||||
| 			fmt.Println(err.Error()) | 		if err != nil { | ||||||
| 			return nil | 			context.Text("unable to decode request") | ||||||
|  | 			return | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		var pic []byte | 		var pic []byte | ||||||
|  |  | ||||||
| 		query := fmt.Sprintf("SELECT thumbnail FROM tvshow WHERE id=%d", args.Id) | 		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 { | 		if err != nil { | ||||||
| 			fmt.Printf("the thumbnail of movie id %d couldn't be found", args.Id) | 			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 ( | import ( | ||||||
| 	"fmt" | 	"fmt" | ||||||
|  | 	"openmediacenter/apiGo/api/api" | ||||||
| 	"openmediacenter/apiGo/database" | 	"openmediacenter/apiGo/database" | ||||||
| 	"regexp" | 	"regexp" | ||||||
| ) | ) | ||||||
| @@ -22,16 +23,17 @@ func deleteFromDB() { | |||||||
| 	 * @apiParam {bool} [Force] force delete tag with its constraints | 	 * @apiParam {bool} [Force] force delete tag with its constraints | ||||||
| 	 * @apiParam {int} TagId id of tag to delete | 	 * @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 { | 		var args struct { | ||||||
| 			TagId int | 			TagId int | ||||||
| 			Force bool | 			Force bool | ||||||
| 		} | 		} | ||||||
| 		if err := FillStruct(&args, info.Data); err != nil { | 		err := api.DecodeRequest(context.GetRequest(), &args) | ||||||
| 			fmt.Println(err.Error()) | 		if err != nil { | ||||||
| 			return nil | 			context.Text("unable to decode request") | ||||||
|  | 			return | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		// delete key constraints first | 		// delete key constraints first | ||||||
| @@ -41,23 +43,24 @@ func deleteFromDB() { | |||||||
|  |  | ||||||
| 			// respond only if result not successful | 			// respond only if result not successful | ||||||
| 			if err != nil { | 			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) | 		query := fmt.Sprintf("DELETE FROM tags WHERE tag_id=%d", args.TagId) | ||||||
| 		err := database.Edit(query) | 		err = database.Edit(query) | ||||||
|  |  | ||||||
| 		if err == nil { | 		if err == nil { | ||||||
| 			// return if successful | 			// return if successful | ||||||
| 			return database.ManualSuccessResponse(err) | 			context.Text(string(database.ManualSuccessResponse(err))) | ||||||
| 		} else { | 		} 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.*$") | 			r := regexp.MustCompile("^.*a foreign key constraint fails.*$") | ||||||
| 			if r.MatchString(err.Error()) { | 			if r.MatchString(err.Error()) { | ||||||
| 				return database.ManualSuccessResponse(fmt.Errorf("not empty tag")) | 				context.Text(string(database.ManualSuccessResponse(fmt.Errorf("not empty tag")))) | ||||||
| 			} else { | 			} else { | ||||||
| 				return database.ManualSuccessResponse(err) | 				context.Text(string(database.ManualSuccessResponse(err))) | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 	}) | 	}) | ||||||
| @@ -74,9 +77,9 @@ func getFromDB() { | |||||||
| 	 * @apiSuccess {uint32} TagId | 	 * @apiSuccess {uint32} TagId | ||||||
| 	 * @apiSuccess {string} TagName name of the Tag | 	 * @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" | 		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 | 	 * @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 { | 		var args struct { | ||||||
| 			TagName string | 			TagName string | ||||||
| 		} | 		} | ||||||
| 		if err := FillStruct(&args, info.Data); err != nil { | 		err := api.DecodeRequest(context.GetRequest(), &args) | ||||||
| 			fmt.Println(err.Error()) | 		if err != nil { | ||||||
| 			return nil | 			context.Text("unable to decode request") | ||||||
|  | 			return | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		query := "INSERT IGNORE INTO tags (tag_name) VALUES (?)" | 		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} TagId Tag id to add to video | ||||||
| 	 * @apiParam {int} MovieId Video Id of video to add tag to | 	 * @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 { | 		var args struct { | ||||||
| 			MovieId int | 			MovieId int | ||||||
| 			TagId   int | 			TagId   int | ||||||
| 		} | 		} | ||||||
| 		if err := FillStruct(&args, info.Data); err != nil { | 		err := api.DecodeRequest(context.GetRequest(), &args) | ||||||
| 			fmt.Println(err.Error()) | 		if err != nil { | ||||||
| 			return nil | 			context.Text("unable to decode request") | ||||||
|  | 			return | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		query := "INSERT IGNORE INTO video_tags(tag_id, video_id) VALUES (?,?)" | 		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 | package api | ||||||
|  |  | ||||||
| import ( | import ( | ||||||
| 	"encoding/json" |  | ||||||
| 	"fmt" | 	"fmt" | ||||||
| 	"net/url" | 	"net/url" | ||||||
|  | 	"openmediacenter/apiGo/api/api" | ||||||
| 	"openmediacenter/apiGo/api/types" | 	"openmediacenter/apiGo/api/types" | ||||||
| 	"openmediacenter/apiGo/config" | 	"openmediacenter/apiGo/config" | ||||||
| 	"openmediacenter/apiGo/database" | 	"openmediacenter/apiGo/database" | ||||||
| @@ -31,14 +31,15 @@ func getVideoHandlers() { | |||||||
| 	 * @apiSuccess {String} Videos.MovieName  Name of video | 	 * @apiSuccess {String} Videos.MovieName  Name of video | ||||||
| 	 * @apiSuccess {String} TagName Name of the Tag returned | 	 * @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 { | 		var args struct { | ||||||
| 			Tag  uint32 | 			Tag  uint32 | ||||||
| 			Sort uint8 | 			Sort uint8 | ||||||
| 		} | 		} | ||||||
| 		if err := FillStruct(&args, info.Data); err != nil { | 		err := api.DecodeRequest(context.GetRequest(), &args) | ||||||
| 			fmt.Println(err.Error()) | 		if err != nil { | ||||||
| 			return nil | 			context.Text("unable to decode request") | ||||||
|  | 			return | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		const ( | 		const ( | ||||||
| @@ -92,24 +93,22 @@ func getVideoHandlers() { | |||||||
| 			var vid types.VideoUnloadedType | 			var vid types.VideoUnloadedType | ||||||
| 			err := rows.Scan(&vid.MovieId, &vid.MovieName, &name) | 			err := rows.Scan(&vid.MovieId, &vid.MovieName, &name) | ||||||
| 			if err != nil { | 			if err != nil { | ||||||
| 				return nil | 				return | ||||||
| 			} | 			} | ||||||
| 			vids = append(vids, vid) | 			vids = append(vids, vid) | ||||||
| 		} | 		} | ||||||
| 		if rows.Close() != nil { | 		if rows.Close() != nil { | ||||||
| 			return nil | 			return | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		// if the tag id doesn't exist the query won't return a name | 		// if the tag id doesn't exist the query won't return a name | ||||||
| 		if name == "" { | 		if name == "" { | ||||||
| 			return nil | 			return | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		result.Videos = vids | 		result.Videos = vids | ||||||
| 		result.TagName = name | 		result.TagName = name | ||||||
| 		// jsonify results | 		context.Json(result) | ||||||
| 		str, _ := json.Marshal(result) |  | ||||||
| 		return str |  | ||||||
| 	}) | 	}) | ||||||
|  |  | ||||||
| 	/** | 	/** | ||||||
| @@ -122,26 +121,27 @@ func getVideoHandlers() { | |||||||
| 	 * | 	 * | ||||||
| 	 * @apiSuccess {string} . Base64 encoded Thubnail | 	 * @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 { | 		var args struct { | ||||||
| 			Movieid int | 			Movieid int | ||||||
| 		} | 		} | ||||||
| 		if err := FillStruct(&args, info.Data); err != nil { | 		err := api.DecodeRequest(context.GetRequest(), &args) | ||||||
| 			fmt.Println(err.Error()) | 		if err != nil { | ||||||
| 			return nil | 			context.Text("unable to decode request") | ||||||
|  | 			return | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		var pic []byte | 		var pic []byte | ||||||
|  |  | ||||||
| 		query := fmt.Sprintf("SELECT thumbnail FROM videos WHERE movie_id=%d", args.Movieid) | 		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 { | 		if err != nil { | ||||||
| 			fmt.Printf("the thumbnail of movie id %d couldn't be found", args.Movieid) | 			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 {string} Videos.MovieName Video Name | ||||||
| 	 * @apiSuccess {int} Videos.MovieId Video ID | 	 * @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 { | 		var args struct { | ||||||
| 			Number int | 			Number int | ||||||
| 		} | 		} | ||||||
| 		if err := FillStruct(&args, info.Data); err != nil { | 		if api.DecodeRequest(context.GetRequest(), &args) != nil { | ||||||
| 			fmt.Println(err.Error()) | 			context.Text("unable to decode request") | ||||||
| 			return nil | 			return | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		var result struct { | 		var result struct { | ||||||
| @@ -198,15 +198,13 @@ func getVideoHandlers() { | |||||||
| 			var tag types.Tag | 			var tag types.Tag | ||||||
| 			err := rows.Scan(&tag.TagName, &tag.TagId) | 			err := rows.Scan(&tag.TagName, &tag.TagId) | ||||||
| 			if err != nil { | 			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 | 			// append to final array | ||||||
| 			result.Tags = append(result.Tags, tag) | 			result.Tags = append(result.Tags, tag) | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		// jsonify results | 		context.Json(result) | ||||||
| 		str, _ := json.Marshal(result) |  | ||||||
| 		return str |  | ||||||
| 	}) | 	}) | ||||||
|  |  | ||||||
| 	/** | 	/** | ||||||
| @@ -221,23 +219,19 @@ func getVideoHandlers() { | |||||||
| 	 * @apiSuccess {number} .MovieId Id of Video | 	 * @apiSuccess {number} .MovieId Id of Video | ||||||
| 	 * @apiSuccess {String} .MovieName  Name 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 { | 		var args struct { | ||||||
| 			KeyWord string | 			KeyWord string | ||||||
| 		} | 		} | ||||||
| 		if err := FillStruct(&args, info.Data); err != nil { | 		if api.DecodeRequest(context.GetRequest(), &args) != nil { | ||||||
| 			fmt.Println(err.Error()) | 			context.Text("unable to decode request") | ||||||
| 			return nil | 			return | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		query := fmt.Sprintf(`SELECT movie_id,movie_name FROM videos  | 		query := fmt.Sprintf(`SELECT movie_id,movie_name FROM videos  | ||||||
| 					WHERE movie_name LIKE '%%%s%%' | 					WHERE movie_name LIKE '%%%s%%' | ||||||
| 					ORDER BY likes DESC, create_date DESC, movie_name`, args.KeyWord) | 					ORDER BY likes DESC, create_date DESC, movie_name`, args.KeyWord) | ||||||
|  | 		context.Json(readVideosFromResultset(database.Query(query))) | ||||||
| 		result := readVideosFromResultset(database.Query(query)) |  | ||||||
| 		// jsonify results |  | ||||||
| 		str, _ := json.Marshal(result) |  | ||||||
| 		return str |  | ||||||
| 	}) | 	}) | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -273,13 +267,13 @@ func loadVideosHandlers() { | |||||||
| 	 * @apiSuccess {string} Actors.Name Actor Name | 	 * @apiSuccess {string} Actors.Name Actor Name | ||||||
| 	 * @apiSuccess {string} Actors.Thumbnail Portrait Thumbnail | 	 * @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 { | 		var args struct { | ||||||
| 			MovieId int | 			MovieId int | ||||||
| 		} | 		} | ||||||
| 		if err := FillStruct(&args, info.Data); err != nil { | 		if api.DecodeRequest(context.GetRequest(), &args) != nil { | ||||||
| 			fmt.Println(err.Error()) | 			context.Text("unable to decode request") | ||||||
| 			return nil | 			return | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		query := fmt.Sprintf(`SELECT movie_name,movie_url,movie_id,thumbnail,poster,likes,quality,length  | 		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) | 		err := database.QueryRow(query).Scan(&res.MovieName, &res.MovieUrl, &res.MovieId, &thumbnail, &poster, &res.Likes, &res.Quality, &res.Length) | ||||||
| 		if err != nil { | 		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()) | 			fmt.Println(err.Error()) | ||||||
| 			return nil | 			return | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		// we ned to urlencode the movieurl | 		// we ned to urlencode the movieurl | ||||||
| @@ -331,9 +325,7 @@ func loadVideosHandlers() { | |||||||
|  |  | ||||||
| 		res.Actors = readActorsFromResultset(database.Query(query)) | 		res.Actors = readActorsFromResultset(database.Query(query)) | ||||||
|  |  | ||||||
| 		// jsonify results | 		context.Json(res) | ||||||
| 		str, _ := json.Marshal(res) |  | ||||||
| 		return str |  | ||||||
| 	}) | 	}) | ||||||
|  |  | ||||||
| 	/** | 	/** | ||||||
| @@ -349,7 +341,7 @@ func loadVideosHandlers() { | |||||||
| 	 * @apiSuccess {uint32} DifferentTags number of different Tags available | 	 * @apiSuccess {uint32} DifferentTags number of different Tags available | ||||||
| 	 * @apiSuccess {uint32} Tagged number of different Tags assigned | 	 * @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 | 		var result types.StartData | ||||||
| 		// query settings and infotile values | 		// query settings and infotile values | ||||||
| 		query := ` | 		query := ` | ||||||
| @@ -383,9 +375,7 @@ func loadVideosHandlers() { | |||||||
|  |  | ||||||
| 		_ = database.QueryRow(query).Scan(&result.VideoNr, &result.Tagged, &result.HDNr, &result.FullHdNr, &result.SDNr, &result.DifferentTags) | 		_ = database.QueryRow(query).Scan(&result.VideoNr, &result.Tagged, &result.HDNr, &result.FullHdNr, &result.SDNr, &result.DifferentTags) | ||||||
|  |  | ||||||
| 		// jsonify results | 		context.Json(result) | ||||||
| 		str, _ := json.Marshal(result) |  | ||||||
| 		return str |  | ||||||
| 	}) | 	}) | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -398,19 +388,19 @@ func addToVideoHandlers() { | |||||||
| 	 * | 	 * | ||||||
| 	 * @apiParam {int} MovieId ID of video | 	 * @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 { | 		var args struct { | ||||||
| 			MovieId int | 			MovieId int | ||||||
| 		} | 		} | ||||||
| 		if err := FillStruct(&args, info.Data); err != nil { | 		if api.DecodeRequest(context.GetRequest(), &args) != nil { | ||||||
| 			fmt.Println(err.Error()) | 			context.Text("unable to decode request") | ||||||
| 			return nil | 			return | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		query := fmt.Sprintf("update videos set likes = likes + 1 where movie_id = %d", args.MovieId) | 		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 {int} MovieId ID of video | ||||||
| 	 * @apiParam {bool} FullyDelete Delete video from disk? | 	 * @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 { | 		var args struct { | ||||||
| 			MovieId     int | 			MovieId     int | ||||||
| 			FullyDelete bool | 			FullyDelete bool | ||||||
| 		} | 		} | ||||||
| 		if err := FillStruct(&args, info.Data); err != nil { | 		if api.DecodeRequest(context.GetRequest(), &args) != nil { | ||||||
| 			fmt.Println(err.Error()) | 			context.Text("unable to decode request") | ||||||
| 			return nil | 			return | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		// delete tag constraints | 		// delete tag constraints | ||||||
| @@ -444,7 +434,7 @@ func addToVideoHandlers() { | |||||||
|  |  | ||||||
| 		// respond only if result not successful | 		// respond only if result not successful | ||||||
| 		if err != nil { | 		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 | 		// only allow deletion of video if cli flag is set, independent of passed api arg | ||||||
| @@ -454,7 +444,7 @@ func addToVideoHandlers() { | |||||||
| 			var vidpath string | 			var vidpath string | ||||||
| 			err := database.QueryRow(query).Scan(&vidpath) | 			err := database.QueryRow(query).Scan(&vidpath) | ||||||
| 			if err != nil { | 			if err != nil { | ||||||
| 				return database.ManualSuccessResponse(err) | 				context.Text(string(database.ManualSuccessResponse(err))) | ||||||
| 			} | 			} | ||||||
|  |  | ||||||
| 			sett, videoprefix, _ := database.GetSettings() | 			sett, videoprefix, _ := database.GetSettings() | ||||||
| @@ -463,12 +453,12 @@ func addToVideoHandlers() { | |||||||
| 			err = os.Remove(assembledPath) | 			err = os.Remove(assembledPath) | ||||||
| 			if err != nil { | 			if err != nil { | ||||||
| 				fmt.Printf("unable to delete file: %s -- %s\n", assembledPath, err.Error()) | 				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 | 		// delete video row from db | ||||||
| 		query = fmt.Sprintf("DELETE FROM videos WHERE movie_id=%d", args.MovieId) | 		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) { | func TestAddHandler(t *testing.T) { | ||||||
| 	cleanUp() | 	cleanUp() | ||||||
| 
 | 
 | ||||||
| 	AddHandler("test", ActorNode, func(info *HandlerInfo) []byte { | 	AddHandler("test", ActorNode, api.PermUser, func(context api.Context) { | ||||||
| 		return nil | 		return nil | ||||||
| 	}) | 	}) | ||||||
| 	if len(handlers) != 1 { | 	if len(handlers) != 1 { | ||||||
| @@ -23,7 +23,7 @@ func TestCallOfHandler(t *testing.T) { | |||||||
| 	cleanUp() | 	cleanUp() | ||||||
| 
 | 
 | ||||||
| 	i := 0 | 	i := 0 | ||||||
| 	AddHandler("test", ActorNode, func(info *HandlerInfo) []byte { | 	AddHandler("test", ActorNode, api.PermUser, func(context api.Context) { | ||||||
| 		i++ | 		i++ | ||||||
| 		return nil | 		return nil | ||||||
| 	}) | 	}) | ||||||
| @@ -39,7 +39,7 @@ func TestCallOfHandler(t *testing.T) { | |||||||
| func TestDecodingOfArguments(t *testing.T) { | func TestDecodingOfArguments(t *testing.T) { | ||||||
| 	cleanUp() | 	cleanUp() | ||||||
| 
 | 
 | ||||||
| 	AddHandler("test", ActorNode, func(info *HandlerInfo) []byte { | 	AddHandler("test", ActorNode, api.PermUser, func(context api.Context) { | ||||||
| 		var args struct { | 		var args struct { | ||||||
| 			Test    string | 			Test    string | ||||||
| 			TestInt int | 			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 | go 1.16 | ||||||
|  |  | ||||||
| require ( | require ( | ||||||
|  | 	github.com/dgrijalva/jwt-go v3.2.0+incompatible | ||||||
| 	github.com/go-sql-driver/mysql v1.5.0 | 	github.com/go-sql-driver/mysql v1.5.0 | ||||||
| 	github.com/pelletier/go-toml/v2 v2.0.0-beta.3 | 	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 | 	gopkg.in/oauth2.v3 v3.12.0 | ||||||
| 	nhooyr.io/websocket v1.8.7 | 	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 h1:Xkwi/a1rcvNg1PPYe5vI8GbeBY/jrVuDX5ASuANWTrk= | ||||||
| github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= | 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/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/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 h1:q7AeDBpnBk8AogcD4DSag/Ukw/KV+YhzLj2bP5HvKCM= | ||||||
| github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= | 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/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 h1:9yzud/Ht36ygwatGx56VwCZtlI/2AD15T1X2sjSuGns= | ||||||
| github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= | 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/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/k0kubun/colorstring v0.0.0-20150214042306-9440f1994b88/go.mod h1:3w7q1U84EfirKl04SVQ/s7nPm1ZPhiXd34z40TNz36k= | ||||||
| github.com/klauspost/compress v1.8.2/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= | 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/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 h1:Kpca3qRNrduNnOQeazBd0ysaKrUJiIuISHxogkT9RPQ= | ||||||
| github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= | 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/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/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/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= | ||||||
| github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= | 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 h1:BHyfKlQyqbsFN5p3IfnEUduWvb9is428/nNb5L3U01M= | ||||||
| github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82/go.mod h1:lgjkn3NuSvDfVJdfcVVdX+jpBxNmX4rDAzaS45IcYoM= | 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= | 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/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-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= | ||||||
| golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/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" | 	"log" | ||||||
| 	"net/http" | 	"net/http" | ||||||
| 	"openmediacenter/apiGo/api" | 	"openmediacenter/apiGo/api" | ||||||
|  | 	api2 "openmediacenter/apiGo/api/api" | ||||||
| 	"openmediacenter/apiGo/config" | 	"openmediacenter/apiGo/config" | ||||||
| 	"openmediacenter/apiGo/database" | 	"openmediacenter/apiGo/database" | ||||||
| 	"openmediacenter/apiGo/static" | 	"openmediacenter/apiGo/static" | ||||||
| @@ -35,7 +36,7 @@ func main() { | |||||||
| 	// add the static files | 	// add the static files | ||||||
| 	static.ServeStaticFiles() | 	static.ServeStaticFiles() | ||||||
|  |  | ||||||
| 	api.ServerInit() | 	api2.ServerInit() | ||||||
|  |  | ||||||
| 	fmt.Printf("OpenMediacenter server up and running on port %d\n", port) | 	fmt.Printf("OpenMediacenter server up and running on port %d\n", port) | ||||||
| 	log.Fatal(http.ListenAndServe(fmt.Sprintf(":%d", port), nil)) | 	log.Fatal(http.ListenAndServe(fmt.Sprintf(":%d", port), nil)) | ||||||
|   | |||||||
| @@ -68,7 +68,7 @@ function generalAPICall<T>( | |||||||
|     mytoken: string |     mytoken: string | ||||||
| ): void { | ): void { | ||||||
|     (async function (): Promise<void> { |     (async function (): Promise<void> { | ||||||
|         const response = await fetch(APIPREFIX + apinode, { |         const response = await fetch(APIPREFIX + apinode + '/' + fd.action, { | ||||||
|             method: 'POST', |             method: 'POST', | ||||||
|             body: JSON.stringify(fd), |             body: JSON.stringify(fd), | ||||||
|             headers: new Headers({ |             headers: new Headers({ | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user