/* * Copyright (c) 2013 GigaSpaces Technologies Ltd. All rights reserved * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package controllers; import com.avaje.ebean.Ebean; import controllers.compositions.UserCheck; import data.validation.GsConstraints; import models.*; import org.apache.commons.io.IOUtils; import org.apache.commons.lang.ArrayUtils; import org.apache.commons.lang.math.NumberUtils; import org.apache.commons.lang3.StringUtils; import org.codehaus.jackson.JsonNode; import org.codehaus.jackson.map.ObjectMapper; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import play.data.Form; import play.data.validation.Constraints; import play.libs.Json; import play.mvc.Controller; import play.mvc.Http; import play.mvc.Result; import play.mvc.With; import server.ApplicationContext; import server.HeaderMessage; import server.exceptions.ServerException; import utils.RestUtils; import views.html.widgets.dashboard.account; import views.html.widgets.dashboard.angularjs_widget; import views.html.widgets.dashboard.previewWidget; import views.html.widgets.dashboard.widgets; import views.html.widgets.widget; import views.html.widgets.widgetSinglePage; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.util.*; import static utils.RestUtils.*; /** * Widget Admin controller. * * @author Igor Goldenberg */ public class WidgetAdmin extends Controller { private static Logger logger = LoggerFactory.getLogger( WidgetAdmin.class ); public static Result getWidget( String apiKey ){ if ( StringUtils.isEmpty(apiKey)){ return badRequest("apiKey required"); } Widget widgetItem = Widget.getWidget(apiKey); if ( widgetItem == null ){//|| !widgetItem.isEnabled()){ return ok(); } return redirect("/public-folder/angularApps/index.html#/widgets/" + apiKey + "/view?since=" + System.currentTimeMillis()); } public static Result icon( String apiKey ){ WidgetIcon widgetItem = WidgetIcon.findByWidgetApiKey( apiKey ); if ( widgetItem == null || ArrayUtils.isEmpty(widgetItem.getData()) ){ return ok().as( "image/png"); // return notFound( ); } return ok( widgetItem.getData() ).as( widgetItem.getContentType() ); } /** * This function will save the widget. * It receives the user's authToken, the widget in JSON format, and icon file in the request body. * * This method handles 2 scenarios (not best practice, we know), * - if widget exists * - if widget does not exists - we create it * * * Removing an icon is decided if form gets "removeIcon" key. * @return the widget as JSON - without the icon data. */ public static Result postWidget( ){ // read everything from the form. Http.MultipartFormData body = request().body().asMultipartFormData(); String widgetString = body.asFormUrlEncoded().get( "widget" )[0]; boolean removeIcon = body.asFormUrlEncoded().containsKey("removeIcon"); String authToken = session("authToken"); Http.MultipartFormData.FilePart picture = body.getFile( "icon" ); JsonNode jsonNode = Json.parse(widgetString); Widget w = null; User user = null; if ( jsonNode.has( "id" ) ){ String widgetApiKey = jsonNode.get("apiKey").asText(); w = getWidgetSafely( authToken, widgetApiKey ); }else{ user = User.validateAuthToken( authToken ); } ObjectMapper mapper = new ObjectMapper(); Form<Widget> validator = form( Widget.class ).bind( jsonNode ); // ignore apiKey errors validator.errors().remove("apiKey"); if ( validator.hasErrors() ){ new HeaderMessage().populateFormErrors( validator ).apply( response().getHeaders() ); logger.error("trying to save an invalid widget " + validator.toString()); return badRequest( ); } try { if ( w == null ){ // creating a new widget. w = mapper.treeToValue( jsonNode, Widget.class ); w.init(); }else{ mapper.readerForUpdating( w ).treeToValue( jsonNode, Widget.class ); } logger.info( "successfully turned json to widget [{}]", w ); if ( user != null ){ user.addNewWidget( w ); } w.update(); w.save( ); w.refresh( ); if ( removeIcon ){ WidgetIcon icon = WidgetIcon.findByWidgetApiKey( w.getApiKey() ); if ( icon != null ){ w.setIcon(null); w.save(); icon.delete(); } } // now lets handle the icon - but only if one was posted. if ( picture != null ) { // decide if widget already has an icon or not WidgetIcon icon = WidgetIcon.findByWidgetApiKey( w.getApiKey() ); if ( icon == null ){ icon = new WidgetIcon(); } String fileName = picture.getFilename(); String contentType = picture.getContentType(); File file = picture.getFile(); byte[] iconData = IOUtils.toByteArray( new FileInputStream( file ) ); icon.setName( fileName ); icon.setContentType( contentType ); icon.setData( iconData ); Ebean.save( icon ); // supports both save and update. w.setIcon( icon ); w.save( ); return ok( "Added icon successfully" ); } return ok( Json.toJson( w ) ); } catch ( IOException e ) { logger.error( "unable to turn body to Json",e ); } logger.info( "saving widget [{}]", widgetString ); return ok( ); } // public static Result getAllWidgets( ) { User user = User.validateAuthToken(session("authToken")); List<Widget> list = null; if ( user.getSession().isAdmin() ) { list = Widget.find.all(); // Utils.workaround( Widget.find.all() ); // list = Utils.workaround( Widget.find.all() ); } else { list = user.getWidgets(); } ObjectMapper mapper = new ObjectMapper(); mapper.getSerializationConfig().addMixInAnnotations( Widget.class, Widget.IncludeInstancesMixin.class ); return ok( Json.toJson(list) ); } public static Result shutdownInstance( String authToken, String instanceId ) { User.validateAuthToken(authToken); ApplicationContext.get().getWidgetServer().undeploy( ServerNode.getServerNode( instanceId )); // todo : link to user somehow return ok(OK_STATUS).as("application/json"); } @With( UserCheck.class ) public static Result listWidgets( Long userId, String authToken ){ User user = ( User) ctx().args.get("user"); return ok(Json.toJson(Widget.findByUser( user ))); } public static Result disableWidgetById( Long widgetId ) { return enableDisableWidget( widgetId, false ); } private static Result enableDisableWidget( Long widgetId, boolean enabled ) { getWidgetSafely( session("authToken"), widgetId, true ).setEnabled( enabled ).save(); return ok(OK_STATUS).as("application/json"); } public static Result enableWidgetById( Long widgetId ) { return enableDisableWidget( widgetId, true ); } private static Widget getWidgetSafely( String authToken, Long widgetId, boolean allowAdmin ){ User user = User.validateAuthToken( authToken ); if ( allowAdmin && user.isAdmin()){ return Widget.find.byId( widgetId ); }else{ return Widget.findByUserAndId( user, widgetId ); } } private static Widget getWidgetSafely( String authToken, String apiKey ) { User user = User.validateAuthToken(authToken); if ( user.isAdmin() ){ return Widget.getWidget(apiKey); }else{ return Widget.getWidgetByApiKey(user, apiKey); } } public static Result getWidgetById( Long widgetId ){ return ok(Json.toJson(getWidgetSafely(session("authToken"), widgetId, false))); } public static Result deleteWidgetById( Long widgetId ){ String authToken = session("authToken"); Widget widget = getWidgetSafely( authToken, widgetId, true ); widget.delete( ); return ok( ); } public static Result previewWidget( String apiKey ){ Http.Cookie authTokenCookie = request().cookies().get("authToken"); if ( authTokenCookie == null ){ redirect("/"); } String authToken = authTokenCookie.value(); Widget widget = getWidgetSafely( authToken, apiKey ); return ok( previewWidget.render(widget, request().host())); } public static Result regenerateWidgetApiKey( String authToken, String apiKey ) { Widget w = getWidgetSafely( authToken, apiKey ).regenerateApiKey(); logger.info( "regenerated api key to [{}]", w ); Map<String, Object> result = new HashMap<String, Object>( ); result.put("widget", w); return ok( Json.toJson( result ) ); } public static Result headers() { Http.Request req = Http.Context.current().request(); StringBuilder sb = new StringBuilder("HEADERS:"); sb.append( "\nRemote address: " ).append( req.remoteAddress() ); Map<String, String[]> headerMap = req.headers(); for (String headerKey : headerMap.keySet()) { for( String s : headerMap.get(headerKey) ) sb.append( "\n" ).append( headerKey ).append( "=" ).append( s ); } return ok(sb.toString()); } public static Result postRequireLogin( String authToken, Long widgetId, boolean requireLogin, String loginVerificationUrl, String webServiceKey ){ Widget widget = getWidgetSafely( authToken, widgetId, false ); if ( widget == null ){ new HeaderMessage().setError(" User is not allowed to edit this widget ").apply(response().getHeaders()); return badRequest(); } GsConstraints.UrlValidator validator = new GsConstraints.UrlValidator(); if ( !validator.isValid(loginVerificationUrl) ){ new HeaderMessage().addFormError("loginVerificationUrl", "invalid value").apply(response().getHeaders()); return badRequest(); } widget.setRequireLogin( requireLogin ); widget.setLoginVerificationUrl( loginVerificationUrl ); widget.setWebServiceKey( webServiceKey ); widget.save(); return ok(); } public static Result postWidgetDescription( String authToken, Long widgetId, String description ){ Widget widget = getWidgetSafely( authToken, widgetId, false ); if ( widget == null ){ new HeaderMessage().setError(" User is not allowed to edit this widget ").apply(response().getHeaders()); return badRequest(); } widget.setDescription( description ); widget.save( ); return ok( ); } public static Result newWidgetsPage(){ return ok( angularjs_widget.render() ); } public static Result getPublicWidgetDetails( String apiKey ){ Widget w = Widget.getWidget(apiKey); return ok(Json.toJson(new PublicWidget(w))); } // public static Result createNewWidget( String widgetId, String authToken, String productName, String productVersion, // String title, String youtubeVideoUrl, String providerURL, // String recipeURL, String consolename, String consoleurl, String rootpath, String recipeName, String consoleUrlService ) // { // User user = User.validateAuthToken(authToken); // Widget widget = null; // if ( !NumberUtils.isNumber( widgetId ) ){ // widget = user.createNewWidget( productName, productVersion, title, youtubeVideoUrl, providerURL, recipeURL, consolename, consoleurl, rootpath ); // }else{ // Long widgetIdLong = Long.parseLong( widgetId ); // widget = Widget.findByUserAndId( user, widgetIdLong ); // if ( widget == null ){ // new HeaderMessage().setError( "User is not allowed to edit this widget" ).apply( response().getHeaders() ); // return badRequest( ); // } // widget.setProductName( productName ); // widget.setProductVersion( productVersion ); // widget.setTitle( title ); // widget.setYoutubeVideoUrl( youtubeVideoUrl ); // widget.setProviderURL( providerURL ); // widget.setRecipeURL( recipeURL ); // widget.setConsoleName( consolename ); // widget.setConsoleURL( consoleurl ); // widget.setRecipeRootPath( rootpath ); // widget.setRecipeName( recipeName ); // widget.setConsoleUrlService( consoleUrlService ); // widget.save(); // } // // logger.info( "edited widget : " + widget.toString() ); // return ok( Json.toJson(widget) ); //// return resultAsJson(widget); // } }