NeosVRからElixirで遊ぶ

NeosVRからElixirを叩いて遊びたいと思います

:::note alert
ローカルのみで実行かつ信頼のできるユーザ以外はセッションに参加させないでください。
:::

# とりあえず遊びたい方用
###### ソースをcloneしてください
https://github.com/t-yamanashi/iexw
##### 起動方法

```sh
$ mix phx.server 
```

##### LogiXはこんな感じで組んでください

![Screenshot from 2022-05-20 22-01-53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/295814/345a8d1c-db72-ed2a-f702-ffb15194766e.png)


# 動作環境

```sh
$ cat /etc/os-release | grep VERSION=
VERSION="20.04.4 LTS (Focal Fossa)"

$ elixir -v
Erlang/OTP 24 [erts-12.3.1] [source] [64-bit] [smp:16:16] [ds:16:16:10] [async-threads:1] [jit]

Elixir 1.13.0 (compiled with Erlang/OTP 24)
```

参考までにハード環境
GPU RTX 3060
CPU Ryzen 7 5800X
メモリ 32GB
で検証してます

# なんちゃってiexの作り方

### プロジェクトを作成します
```sh
$ mix phx.new iexw --no-ecto  
```

### ソースを改良していく

 

コマンドを受付れるようにrouterを修正します
`lib/iexw_web/router.ex`
```diff_elixir
〜省略〜
   scope "/", IexwWeb do
     pipe_through :browser

-     get "/", PageController, :index
+     get "/:val", PageController, :index
   end
〜省略〜
```

各heexを修正
主に、不要なhtmlタグを出力しないように削除します

`lib/iexw_web/templates/layout/app.html.heex`
```diff_elixir
- <main class="container">
-   <p class="alert alert-info" role="alert"><%= get_flash(@conn, :info) %></p>
-   <p class="alert alert-danger" role="alert"><%= get_flash(@conn, :error) %></p>
-   <%= @inner_content %>
- </main>
+ <%= @inner_content %>
```

`lib/iexw_web/templates/layout/live.html.heex`
```diff_elixir
- <main class="container">
-   <p class="alert alert-info" role="alert"
-     phx-click="lv:clear-flash"
-     phx-value-key="info"><%= live_flash(@flash, :info) %></p>

-   <p class="alert alert-danger" role="alert"
-     phx-click="lv:clear-flash"
-     phx-value-key="error"><%= live_flash(@flash, :error) %></p>

-   <%= @inner_content %>
- </main>
+ <%= @inner_content %> 
```

`lib/iexw_web/templates/layout/root.html.heex`
```diff_elixir
- <!DOCTYPE html>
- <html lang="en">
-   <head>
-     <meta charset="utf-8"/>
-     <meta http-equiv="X-UA-Compatible" content="IE=edge"/>
-     <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
-     <%= csrf_meta_tag() %>
-     <%= live_title_tag assigns[:page_title] || "Iexw", suffix: " · Phoenix Framework" %>
-     <link phx-track-static rel="stylesheet" href={Routes.static_path(@conn, "/assets/app.css")}/>
-     <script defer phx-track-static type="text/javascript" src={Routes.static_path(@conn, "/assets/app.js")}></script>
-   </head>
-   <body>
-     <header>
-       <section class="container">
-         <nav>
-           <ul>
-             <li><a href="https://hexdocs.pm/phoenix/overview.html">Get Started</a></li>
-             <%= if function_exported?(Routes, :live_dashboard_path, 2) do %>
-               <li><%= link "LiveDashboard", to: Routes.live_dashboard_path(@conn, :home) %></li>
-             <% end %>
-           </ul>
-         </nav>
-         <a href="https://phoenixframework.org/" class="phx-logo">
-           <img src={Routes.static_path(@conn, "/images/phoenix.png")} alt="Phoenix Framework Logo"/>
-         </a>
-       </section>
-     </header>
-     <%= @inner_content %>
-   </body>
- </html>
+ <%= @inner_content %> 
```

valは結果を表示してます
`lib/iexw_web/templates/page/index.html.heex`
```diff_elixir
- <section class="phx-hero">
-   <h1><%= gettext "Welcome to %{name}!", name: "Phoenix" %></h1>
-   <p>Peace of mind from prototype to production</p>
- </section>

- <section class="row">
-   <article class="column">
-     <h2>Resources</h2>
-     <ul>
-       <li>
-         <a href="https://hexdocs.pm/phoenix/overview.html">Guides &amp; Docs</a>
-       </li>
-       <li>
-         <a href="https://github.com/phoenixframework/phoenix">Source</a>
-       </li>
-       <li>
-         <a href="https://github.com/phoenixframework/phoenix/blob/v1.6/CHANGELOG.md">v1.6 Changelog</a>
-       </li>
-     </ul>
-   </article>
-   <article class="column">
-     <h2>Help</h2>
-     <ul>
-       <li>
-         <a href="https://elixirforum.com/c/phoenix-forum">Forum</a>
-       </li>
-       <li>
-         <a href="https://web.libera.chat/#elixir">#elixir on Libera Chat (IRC)</a>
-       </li>
-       <li>
-         <a href="https://twitter.com/elixirphoenix">Twitter @elixirphoenix</a>
-       </li>
-       <li>
-         <a href="https://elixir-slackin.herokuapp.com/">Elixir on Slack</a>
-       </li>
-       <li>
-         <a href="https://discord.gg/elixir">Elixir on Discord</a>
-       </li>
-     </ul>
-   </article>
- </section>
+ <%= @val %>
```

コントローラを修正します
GETからの入力値を元に
・os:を排除
・System.を排除
・文字からElixirの文法を実行

`lib/iexw_web/controllers/page_controller.ex`
```diff_elixir
 defmodule IexwWeb.PageController do
   use IexwWeb, :controller

-   def index(conn, _params) do
-     render(conn, "index.html")
+   def index(conn, params) do
+     val =
+       params["val"]
+       |> String.replace("os:", "")
+       |> String.replace("System.", "")
+       |> Code.eval_string()
+       |> elem(0)
+       |> inspect()
+
+    render(conn, "index.html", val: val)
   end
 end
```

String.replaceを追加することで、セキュリティー的に実行して欲しくない関数を追加できます